aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp6
-rw-r--r--src/qml/qml/parser/qqmljs.g4
-rw-r--r--src/qml/qml/parser/qqmljsparser.cpp4
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqml.h18
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.cpp91
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor_p.h66
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp11
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp1
-rw-r--r--src/qml/qml/qqmlcompiler.cpp5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp69
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h3
-rw-r--r--src/qml/qml/qqmlcontext.cpp16
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h2
-rw-r--r--src/qml/qml/qqmldata_p.h9
-rw-r--r--src/qml/qml/qqmlengine.cpp109
-rw-r--r--src/qml/qml/qqmlengine.h4
-rw-r--r--src/qml/qml/qqmlengine_p.h5
-rw-r--r--src/qml/qml/qqmlerror.cpp27
-rw-r--r--src/qml/qml/qqmlerror.h2
-rw-r--r--src/qml/qml/qqmlexpression.cpp2
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp30
-rw-r--r--src/qml/qml/qqmlglobal_p.h6
-rw-r--r--src/qml/qml/qqmlimport.cpp10
-rw-r--r--src/qml/qml/qqmlimport_p.h2
-rw-r--r--src/qml/qml/qqmlinfo.cpp24
-rw-r--r--src/qml/qml/qqmlinfo.h19
-rw-r--r--src/qml/qml/qqmlinstruction.cpp2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp7
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h1
-rw-r--r--src/qml/qml/qqmllist.cpp4
-rw-r--r--src/qml/qml/qqmllocale.cpp8
-rw-r--r--src/qml/qml/qqmlmetatype.cpp46
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp2
-rw-r--r--src/qml/qml/qqmlparserstatus.cpp2
-rw-r--r--src/qml/qml/qqmlprivate.h2
-rw-r--r--src/qml/qml/qqmlproperty.cpp7
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp51
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h2
-rw-r--r--src/qml/qml/qqmlscript.cpp6
-rw-r--r--src/qml/qml/qqmlscript_p.h2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp31
-rw-r--r--src/qml/qml/qqmltypeloader_p.h11
-rw-r--r--src/qml/qml/qqmlvme.cpp50
-rw-r--r--src/qml/qml/qqmlvme_p.h6
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp5
-rw-r--r--src/qml/qml/v4/qv4jsonobject_p.h1
-rw-r--r--src/qml/qml/v4/qv4qobjectwrapper.cpp10
-rw-r--r--src/qml/qml/v8/qjsengine.cpp4
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp28
51 files changed, 652 insertions, 185 deletions
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 577757f3c0..99f342f6f0 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -152,7 +152,7 @@ bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
if (a == b || !length)
return true;
- register union {
+ union {
const quint16 *w;
const quint32 *d;
quintptr value;
@@ -177,7 +177,7 @@ bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
// both addresses are 4-bytes aligned
// do a fast 32-bit comparison
- register const quint32 *e = sa.d + (length >> 1);
+ const quint32 *e = sa.d + (length >> 1);
for ( ; sa.d != e; ++sa.d, ++sb.d) {
if (*sa.d != *sb.d)
return false;
@@ -187,7 +187,7 @@ bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
return (length & 1) ? *sa.w == *sb.w : true;
} else {
// one of the addresses isn't 4-byte aligned but the other is
- register const quint16 *e = sa.w + length;
+ const quint16 *e = sa.w + length;
for ( ; sa.w != e; ++sa.w, ++sb.w) {
if (*sa.w != *sb.w)
return false;
diff --git a/src/qml/qml/parser/qqmljs.g b/src/qml/qml/parser/qqmljs.g
index ff4f54374b..5d279ef1a2 100644
--- a/src/qml/qml/parser/qqmljs.g
+++ b/src/qml/qml/parser/qqmljs.g
@@ -2615,6 +2615,10 @@ case $rule_number: {
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
+ if (lexer->qmlMode()) {
+ const QString msg = qApp->translate("QQmlParser", "Deprecated JavaScript `with' statement detected in QML expression. Support for this will be removed in Qt 5.2!");
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, node->withToken, msg));
+ }
} break;
./
diff --git a/src/qml/qml/parser/qqmljsparser.cpp b/src/qml/qml/parser/qqmljsparser.cpp
index a0fa7a4711..46b5c041d4 100644
--- a/src/qml/qml/parser/qqmljsparser.cpp
+++ b/src/qml/qml/parser/qqmljsparser.cpp
@@ -1515,6 +1515,10 @@ case 311: {
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
+ if (lexer->qmlMode()) {
+ const QString msg = qApp->translate("QQmlParser", "Deprecated JavaScript `with' statement detected in QML expression. Support for this will be removed in Qt 5.2!");
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, node->withToken, msg));
+ }
} break;
case 312: {
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 680e317a4e..31904f81e2 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -51,6 +51,7 @@ SOURCES += \
$$PWD/qqmlmemoryprofiler.cpp \
$$PWD/qqmlplatform.cpp \
$$PWD/qqmlbinding.cpp \
+ $$PWD/qqmlabstracturlinterceptor.cpp \
$$PWD/qqmlapplicationengine.cpp \
$$PWD/qqmllistwrapper.cpp \
$$PWD/qqmlcontextwrapper.cpp \
@@ -127,6 +128,7 @@ HEADERS += \
$$PWD/qqmlplatform_p.h \
$$PWD/qqmlbinding_p.h \
$$PWD/qqmlextensionplugin_p.h \
+ $$PWD/qqmlabstracturlinterceptor_p.h \
$$PWD/qqmlapplicationengine_p.h \
$$PWD/qqmlapplicationengine.h \
$$PWD/qqmllistwrapper_p.h \
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 7e6e0d1d36..fb0133f305 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -102,6 +102,8 @@ class QQmlPropertyValueInterceptor;
listName[listLen+nameLen] = '>'; \
listName[listLen+nameLen+1] = '\0';
+void Q_QML_EXPORT qmlClearTypeRegistrations();
+
template<typename T>
int qmlRegisterType()
{
@@ -417,11 +419,17 @@ class QQmlContext;
class QQmlEngine;
class QJSValue;
class QJSEngine;
-Q_QML_EXPORT void qmlExecuteDeferred(QObject *);
-Q_QML_EXPORT QQmlContext *qmlContext(const QObject *);
-Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *);
-Q_QML_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true);
-Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *, const QObject *, const QMetaObject *, bool create);
+
+namespace QtQml {
+ // declared in namespace to avoid symbol conflicts with QtDeclarative
+ Q_QML_EXPORT void qmlExecuteDeferred(QObject *);
+ Q_QML_EXPORT QQmlContext *qmlContext(const QObject *);
+ Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *);
+ Q_QML_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true);
+ Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *, const QObject *,
+ const QMetaObject *, bool create);
+}
+using namespace QtQml;
template<typename T>
QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
diff --git a/src/qml/qml/qqmlabstracturlinterceptor.cpp b/src/qml/qml/qqmlabstracturlinterceptor.cpp
new file mode 100644
index 0000000000..a68d5f7489
--- /dev/null
+++ b/src/qml/qml/qqmlabstracturlinterceptor.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QQmlAbstractUrlInterceptor
+ \inmodule QtQml
+ \brief allows you to control QML file loading.
+
+ \note This class is in an extended validation period and still subject to change. It should be treated as private API for 5.1
+
+ QQmlAbstractUrlInterceptor is an interface which can be used to alter URLs
+ before they are used by the QML engine. This is primarily useful for altering
+ file urls into other file urls, such as selecting different graphical assets
+ for the current platform.
+
+ Relative URLs are intercepted after being resolved against the file path of the
+ current QML context. URL interception also occurs after setting the base path for
+ a loaded QML file. This means that the content loaded for that QML file uses the
+ intercepted URL, but inside the file the pre-intercepted URL is used for resolving
+ relative paths. This allows for interception of .qml file loading without needing
+ all paths (or local types) inside intercepted content to insert a different relative path.
+
+ Compared to setNetworkAccessManagerFactory, QQmlAbstractUrlInterceptor affects all URLs
+ and paths, including local files and embedded resource files. QQmlAbstractUrlInterceptor
+ is synchronous, and for asynchronous files must return a url with an asynchronous scheme
+ (such as http or a custom scheme handled by your own custom QNetworkAccessManager). You
+ can use a QQmlAbstractUrlInterceptor to change file URLs into networked URLs which are
+ handled by your own custom QNetworkAccessManager.
+
+ To implement support for a custom networked scheme, see setNetworkAccessManagerFactory.
+*/
+
+/*
+ \enum QQmlAbstractUrlInterceptor::DataType
+
+ Specifies where URL interception is taking place place.
+
+ Because QML loads qmldir files for locating types, there are two URLs involved in loading a QML type. The URL of the (possibly implicit) qmldir used for locating the type and the URL of the file which defines the type. Intercepting
+ both leads to either complex URL replacement or double URL replacements for the same file.
+
+ \value QmldirFile The URL being intercepted is for a Qmldir file. Intercepting this, but not the QmlFile, allows for swapping out entire sub trees.
+ \value JavaScriptFile The URL being intercepted is an import for a Javascript file.
+ \value QmlFile The URL being intercepted is for a Qml file. Intercepting this, but not the Qmldir file, leaves the base dir of a QML file untouched and acts like replacing the file with another file.
+ \value UrlString The URL being intercepted is a url property in a QML file, and not being used to load a file through the engine.
+
+*/
+
+/*!
+ \fn QUrl QQmlAbstractUrlInterceptor::intercept(const QUrl& url, DataType type)
+
+ A pure virtual function where you can intercept the url. The returned value is taken as the
+ new value for the url. The type of url being intercepted is given by the type variable.
+*/
diff --git a/src/qml/qml/qqmlabstracturlinterceptor_p.h b/src/qml/qml/qqmlabstracturlinterceptor_p.h
new file mode 100644
index 0000000000..186d59e301
--- /dev/null
+++ b/src/qml/qml/qqmlabstracturlinterceptor_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//Private API for 5.1 (at least)
+#ifndef QQMLABSTRACTURLINTERCEPTOR_H
+#define QQMLABSTRACTURLINTERCEPTOR_H
+
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QML_EXPORT QQmlAbstractUrlInterceptor
+{
+ Q_FLAGS(InterceptionPoint)
+public:
+ enum DataType { //Matches QQmlDataBlob::Type
+ QmlFile = 0,
+ JavaScriptFile = 1,
+ QmldirFile = 2,
+ UrlString = 0x1000
+ };
+
+ QQmlAbstractUrlInterceptor() {}
+ virtual ~QQmlAbstractUrlInterceptor() {}
+ virtual QUrl intercept(const QUrl &path, DataType type) = 0;
+};
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 7dc2c77922..9181dad519 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -72,6 +72,7 @@ void QQmlApplicationEnginePrivate::init()
QCoreApplication::installTranslator(qtTranslator);
translators << qtTranslator;
#endif
+ QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
}
void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile)
@@ -133,7 +134,8 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
case QQmlComponent::Null:
return; //These cases just wait for the next status update
}
- delete c;
+
+ c->deleteLater();
}
/*!
@@ -158,16 +160,21 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
}
\endcode
- You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as QtQuick).
+ You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as \c QtQuick).
List of configuration changes from a default QQmlEngine:
\list
\li Connecting Qt.quit() to QCoreApplication::quit()
\li Automatically loads translation files from an i18n directory adjacent to the main QML file.
+ \li Automatically sets an incubuation controller if the scene contains a QQuickWindow.
\endlist
The engine behavior can be further tweaked by using the inherited methods from QQmlEngine.
+
+ \note In the future QQmlApplicationEngine may automatically apply file selectors.
+ To ensure forwards compatibility, do not use folder names containing a '+' character in your QML file
+ structure.
*/
/*!
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp
index 4dba670be8..d44ae16fd2 100644
--- a/src/qml/qml/qqmlcompileddata.cpp
+++ b/src/qml/qml/qqmlcompileddata.cpp
@@ -221,7 +221,6 @@ QQmlInstruction::Type QQmlCompiledData::instructionType(const QQmlInstruction *i
return QQmlInstruction::I;
FOR_EACH_QML_INSTR(QML_CHECK_INSTR_CODE)
- Q_UNREACHABLE();
Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid instruction address");
return static_cast<QQmlInstruction::Type>(0);
# undef QML_CHECK_INSTR_CODE
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 07a29e5a63..dcc33a20a3 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -60,6 +60,7 @@
#include "qqmlscriptstring.h"
#include "qqmlglobal_p.h"
#include "qqmlbinding_p.h"
+#include "qqmlabstracturlinterceptor_p.h"
#include <QDebug>
#include <QPointF>
@@ -516,6 +517,10 @@ void QQmlCompiler::genLiteralAssignment(QQmlScript::Property *prop,
// Encoded dir-separators defeat QUrl processing - decode them first
string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
+ // Apply URL interceptor
+ if (engine->urlInterceptor())
+ u = engine->urlInterceptor()->intercept(u,
+ QQmlAbstractUrlInterceptor::UrlString);
instr.propertyIndex = prop->index;
instr.value = output->indexForUrl(u);
output->addInstruction(instr);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 06f99abc8c..382b85685a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -203,14 +203,14 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
}
\endcode
- Note that the QtQuick 1 version is named QDeclarativeComponent.
+ Note that the \l {Qt Quick 1} version is named QDeclarativeComponent.
*/
/*!
\qmltype Component
\instantiates QQmlComponent
\ingroup qml-utility-elements
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\brief Encapsulates a QML component definition
Components are reusable, encapsulated QML types with well-defined interfaces.
@@ -226,7 +226,7 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
\snippet qml/component.qml 0
- Notice that while a \l Rectangle by itself would be automatically
+ Notice that while a \l Rectangle by itself would be automatically
rendered and displayed, this is not the case for the above rectangle
because it is defined inside a \c Component. The component encapsulates the
QML types within, as if they were defined in a separate QML
@@ -246,7 +246,7 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
to specify how each list item is to be displayed.
\c Component objects can also be created dynamically using
- \l{QML:Qt::createComponent()}{Qt.createComponent()}.
+ \l{QtQml2::Qt::createComponent()}{Qt.createComponent()}.
\section2 Creation Context
@@ -312,12 +312,12 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
}
\endqml
- \sa QtQml
+ \sa {Qt QML}
*/
/*!
\enum QQmlComponent::Status
-
+
Specifies the loading status of the QQmlComponent.
\value Null This QQmlComponent has no data. Call loadUrl() or setData() to add QML content.
@@ -382,8 +382,8 @@ void QQmlComponentPrivate::clear()
typeData->release();
typeData = 0;
}
-
- if (cc) {
+
+ if (cc) {
cc->release();
cc = 0;
}
@@ -558,12 +558,12 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QUrl &url, CompilationMod
}
/*!
- Create a QQmlComponent from the given \a fileName and give it the specified
+ Create a QQmlComponent from the given \a fileName and give it the specified
\a parent and \a engine.
\sa loadUrl()
*/
-QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName,
+QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName,
QObject *parent)
: QObject(*(new QQmlComponentPrivate), parent)
{
@@ -617,7 +617,7 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url)
d->url = url;
QQmlTypeData *typeData = QQmlEnginePrivate::get(d->engine)->typeLoader.getType(data, url);
-
+
if (typeData->isCompleteOrError()) {
d->fromTypeData(typeData);
} else {
@@ -780,10 +780,15 @@ QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent)
/*!
Create an object instance from this component. Returns 0 if creation
failed. \a context specifies the context within which to create the object
- instance.
+ instance.
If \a context is 0 (the default), it will create the instance in the
engine' s \l {QQmlEngine::rootContext()}{root context}.
+
+ The ownership of the returned object instance is determined by the QQmlEngine.
+ By default the caller has to take care that the object is eventually deleted.
+
+ \sa QQmlEngine::ObjectOwnership
*/
QObject *QQmlComponent::create(QQmlContext *context)
{
@@ -801,28 +806,31 @@ QObject *QQmlComponent::create(QQmlContext *context)
/*!
This method provides advanced control over component instance creation.
- In general, programmers should use QQmlComponent::create() to create a
+ In general, programmers should use QQmlComponent::create() to create a
component.
Create an object instance from this component. Returns 0 if creation
failed. \a publicContext specifies the context within which to create the object
- instance.
+ instance.
When QQmlComponent constructs an instance, it occurs in three steps:
\list 1
\li The object hierarchy is created, and constant values are assigned.
\li Property bindings are evaluated for the first time.
\li If applicable, QQmlParserStatus::componentComplete() is called on objects.
- \endlist
+ \endlist
QQmlComponent::beginCreate() differs from QQmlComponent::create() in that it
- only performs step 1. QQmlComponent::completeCreate() must be called to
+ only performs step 1. QQmlComponent::completeCreate() must be called to
complete steps 2 and 3.
This breaking point is sometimes useful when using attached properties to
communicate information to an instantiated component, as it allows their
initial values to be configured before property bindings take effect.
- \sa completeCreate()
+ The ownership of the returned object instance is determined by the QQmlEngine.
+ By default the caller has to take care that the object is eventually deleted.
+
+ \sa completeCreate(), QQmlEngine::ObjectOwnership
*/
QObject *QQmlComponent::beginCreate(QQmlContext *publicContext)
{
@@ -950,7 +958,7 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS
/*!
This method provides advanced control over component instance creation.
- In general, programmers should use QQmlComponent::create() to create a
+ In general, programmers should use QQmlComponent::create() to create a
component.
This function completes the component creation begun with QQmlComponent::beginCreate()
@@ -1044,7 +1052,7 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
{
Q_D(QQmlComponent);
- if (!context)
+ if (!context)
context = d->engine->rootContext();
QQmlContextData *contextData = QQmlContextData::get(context);
@@ -1122,7 +1130,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
needParent = true;
}
}
- if (needParent)
+ if (needParent)
qWarning("QQmlComponent: Created graphical object was not "
"placed in the graphics scene.");
}
@@ -1140,15 +1148,15 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
which were not created in QML.
If you wish to create an object without setting a parent, specify \c null for
- the \a parent value. Note that if the returned object is to be displayed, you
- must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent}
+ the \a parent value. Note that if the returned object is to be displayed, you
+ must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent}
property, or else the object will not be visible.
If a \a parent is not provided to createObject(), a reference to the returned object must be held so that
it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards,
since setting the Item parent does not change object ownership; only the graphical parent is changed.
- As of QtQuick 1.1, this method accepts an optional \a properties argument that specifies a
+ As of \c {QtQuick 1.1}, this method accepts an optional \a properties argument that specifies a
map of initial property values for the created object. These values are applied before object
creation is finalized. This is more efficient than setting property values after object creation,
particularly where large sets of property values are defined, and also allows property bindings
@@ -1236,17 +1244,16 @@ void QQmlComponent::createObject(QQmlV4Function *args)
/*!
\qmlmethod object Component::incubateObject(Item parent, object properties, enumeration mode)
- Creates an incubator for instance of this component. Incubators allow new component
+ Creates an incubator for instance of this component. Incubators allow new component
instances to be instantiated asynchronously and not cause freezes in the UI.
- The \a parent argument specifies the parent the created instance will have. Omitting the
+ The \a parent argument specifies the parent the created instance will have. Omitting the
parameter or passing null will create an object with no parent. In this case, a reference
- to the created object must be maintained by the application or the object will eventually
- be garbage collected.
+ to the created object must be held so that it is not destroyed by the garbage collector.
The \a properties argument is specified as a map of property-value items which will be
- set on the created object during its construction. \a mode may be Qt.Synchronous or
- Qt.Asynchronous and controls whether the instance is created synchronously or asynchronously.
+ set on the created object during its construction. \a mode may be Qt.Synchronous or
+ Qt.Asynchronous and controls whether the instance is created synchronously or asynchronously.
The default is asynchronously. In some circumstances, even if Qt.Synchronous is specified,
the incubator may create the object asynchronously. This happens if the component calling
incubateObject() is itself being created asynchronously.
@@ -1329,7 +1336,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
}
QQmlComponentExtension *e = componentExtension(args->engine());
-
+
QV4::ExecutionEngine *v4 = QV8Engine::getV4(args->engine());
QmlIncubatorObject *r = new (v4->memoryManager) QmlIncubatorObject(args->engine(), mode);
r->prototype = e->incubationProto.value().asObject();
@@ -1462,7 +1469,7 @@ void QmlIncubatorObject::setInitialState(QObject *o)
f.asFunctionObject()->call(QV4::Value::fromObject(v4->globalObject), args, 2);
}
}
-
+
void QmlIncubatorObject::destroy(Managed *that)
{
QmlIncubatorObject *o = that->as<QmlIncubatorObject>();
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index 3c27e795c6..ae416dcb1c 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -43,12 +43,13 @@
#define QQMLCOMPONENTATTACHED_P_H
#include <QtQml/qqml.h>
+#include <private/qtqmlglobal_p.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QQmlComponentAttached : public QObject
+class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject
{
Q_OBJECT
public:
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index efe586eec1..daa115b952 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -48,6 +48,7 @@
#include "qqmlengine_p.h"
#include "qqmlengine.h"
#include "qqmlinfo.h"
+#include "qqmlabstracturlinterceptor_p.h"
#include <qjsengine.h>
#include <QtCore/qvarlengtharray.h>
@@ -429,6 +430,7 @@ QUrl QQmlContextData::resolvedUrl(const QUrl &src)
{
QQmlContextData *ctxt = this;
+ QUrl resolved;
if (src.isRelative() && !src.isEmpty()) {
if (ctxt) {
while(ctxt) {
@@ -439,14 +441,20 @@ QUrl QQmlContextData::resolvedUrl(const QUrl &src)
}
if (ctxt)
- return ctxt->url.resolved(src);
+ resolved = ctxt->url.resolved(src);
else if (engine)
- return engine->baseUrl().resolved(src);
+ resolved = engine->baseUrl().resolved(src);
}
- return QUrl();
} else {
- return src;
+ resolved = src;
}
+
+ if (resolved.isEmpty()) //relative but no ctxt
+ return resolved;
+
+ if (engine && engine->urlInterceptor())
+ resolved = engine->urlInterceptor()->intercept(resolved, QQmlAbstractUrlInterceptor::UrlString);
+ return resolved;
}
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 038badae22..baf00adec4 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -149,7 +149,7 @@ private:
Flags m_flags;
friend class QQmlCompiler;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags)
#if 0
#define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 7ab783c577..76d03f011e 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -83,7 +83,7 @@ public:
hasTaintedV8Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
hasVMEMetaObject(false), parentFrozen(false), notifyList(0), context(0), outerContext(0),
bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0),
- lineNumber(0), columnNumber(0), compiledData(0), deferredIdx(0), jsEngineId(0),
+ lineNumber(0), columnNumber(0), compiledData(0), deferredData(0), jsEngineId(0),
propertyCache(0), guards(0), extendedData(0) {
init();
}
@@ -174,8 +174,13 @@ public:
quint16 lineNumber;
quint16 columnNumber;
+ struct DeferredData {
+ unsigned int deferredIdx;
+ QQmlCompiledData *compiledData;//Not always the same as the other compiledData
+ QQmlContextData *context;//Could be either context or outerContext
+ };
QQmlCompiledData *compiledData;
- unsigned int deferredIdx;
+ DeferredData *deferredData;
quint32 jsEngineId; // id of the engine that cerated the jsWrapper
QV4::WeakValue jsWrapper;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 26f3ea9b56..be1c28c62b 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -66,6 +66,7 @@
#include <private/qv8debugservice_p.h>
#include <private/qdebugmessageservice_p.h>
#include "qqmlincubator.h"
+#include "qqmlabstracturlinterceptor_p.h"
#include <private/qv8profilerservice_p.h>
#include <private/qqmlboundsignal_p.h>
@@ -120,7 +121,7 @@ void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
/*!
\qmltype QtObject
\instantiates QObject
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\ingroup qml-utility-elements
\brief A basic QML type
@@ -274,8 +275,9 @@ QQmlImageProviderBase::~QQmlImageProviderBase()
/*!
\qmltype Qt
- \instantiates QQmlEnginePrivate
- \ingroup qml-utility-elements
+\inqmlmodule QtQml 2
+\instantiates QQmlEnginePrivate
+\ingroup qml-utility-elements
\brief The QML global Qt object provides useful enums and functions from Qt.
\keyword QmlGlobalQtObject
@@ -314,7 +316,7 @@ when the property has one of the following types:
\li \c size - use \l{Qt::size()}{Qt.size()}
\endlist
-If the QtQuick module has been imported, the following helper functions for
+If the \c QtQuick module has been imported, the following helper functions for
creating objects of specific data types are also available for clients to use:
\list
\li \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()}
@@ -509,7 +511,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
outputWarningsToStdErr(true),
cleanup(0), erroredBindings(0), inProgressCreations(0),
workerScriptEngine(0), activeVME(0),
- networkAccessManager(0), networkAccessManagerFactory(0),
+ networkAccessManager(0), networkAccessManagerFactory(0), urlInterceptor(0),
scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
{
@@ -721,17 +723,17 @@ void QQmlData::flushPendingBindingImpl(int coreIndex)
}
}
+bool QQmlEnginePrivate::baseModulesUninitialized = true;
void QQmlEnginePrivate::init()
{
Q_Q(QQmlEngine);
- static bool firstTime = true;
- if (firstTime) {
+ if (baseModulesUninitialized) {
qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler.
registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks.
QQmlData::init();
- firstTime = false;
+ baseModulesUninitialized = false;
}
qRegisterMetaType<QVariant>();
@@ -800,7 +802,7 @@ QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine()
In this case, the Text item will be created in the engine's
\l {QQmlEngine::rootContext()}{root context}.
- Note that the QtQuick 1 version is called QDeclarativeEngine.
+ Note that the \l {Qt Quick 1} version is called QDeclarativeEngine.
\sa QQmlComponent, QQmlContext
*/
@@ -831,6 +833,8 @@ QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent)
Any QQmlContext's created on this engine will be
invalidated, but not destroyed (unless they are parented to the
QQmlEngine object).
+
+ See QJSEngine docs for details on cleaning up the JS engine.
*/
QQmlEngine::~QQmlEngine()
{
@@ -923,6 +927,35 @@ QQmlContext *QQmlEngine::rootContext() const
}
/*!
+ \internal
+ This API is private for 5.1
+
+ Sets the \a urlInterceptor to be used when resolving URLs in QML.
+ This also applies to URLs used for loading script files and QML types.
+ This should not be modifed while the engine is loading files, or URL
+ selection may be inconsistent.
+*/
+void QQmlEngine::setUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
+{
+ Q_D(QQmlEngine);
+ d->urlInterceptor = urlInterceptor;
+}
+
+/*!
+ \internal
+ This API is private for 5.1
+
+ Returns the current QQmlAbstractUrlInterceptor. It must not be modified outside
+ the GUI thread.
+*/
+QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const
+{
+ Q_D(const QQmlEngine);
+ return d->urlInterceptor;
+}
+
+
+/*!
Sets the \a factory to use for creating QNetworkAccessManager(s).
QNetworkAccessManager is used for all network access by QML. By
@@ -1032,7 +1065,7 @@ QQmlImageProviderBase *QQmlEngine::imageProvider(const QString &providerId) cons
{
Q_D(const QQmlEngine);
QMutexLocker locker(&d->mutex);
- return d->imageProviders.value(providerId).data();
+ return d->imageProviders.value(providerId.toLower()).data();
}
/*!
@@ -1044,7 +1077,7 @@ void QQmlEngine::removeImageProvider(const QString &providerId)
{
Q_D(QQmlEngine);
QMutexLocker locker(&d->mutex);
- d->imageProviders.take(providerId);
+ d->imageProviders.take(providerId.toLower());
}
/*!
@@ -1246,11 +1279,13 @@ void QQmlEnginePrivate::doDeleteInEngineThread()
delete d;
}
-Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
+namespace QtQml {
+
+void qmlExecuteDeferred(QObject *object)
{
QQmlData *data = QQmlData::get(object);
- if (data && data->compiledData && data->deferredIdx) {
+ if (data && data->deferredData) {
QQmlObjectCreatingProfiler prof;
if (prof.enabled) {
QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
@@ -1265,8 +1300,9 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
QQmlComponentPrivate::beginDeferred(ep, object, &state);
// Release the reference for the deferral action (we still have one from construction)
- data->compiledData->release();
- data->compiledData = 0;
+ data->deferredData->compiledData->release();
+ delete data->deferredData;
+ data->deferredData = 0;
QQmlComponentPrivate::complete(ep, &state);
}
@@ -1319,6 +1355,41 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
return qmlAttachedPropertiesObjectById(*idCache, object, create);
}
+} // namespace QtQml
+
+#if QT_DEPRECATED_SINCE(5, 1)
+
+// Also define symbols outside namespace to keep binary compatibility with Qt 5.0
+
+Q_QML_EXPORT void qmlExecuteDeferred(QObject *obj)
+{
+ QtQml::qmlExecuteDeferred(obj);
+}
+
+Q_QML_EXPORT QQmlContext *qmlContext(const QObject *obj)
+{
+ return QtQml::qmlContext(obj);
+}
+
+Q_QML_EXPORT QQmlEngine *qmlEngine(const QObject *obj)
+{
+ return QtQml::qmlEngine(obj);
+}
+
+Q_QML_EXPORT QObject *qmlAttachedPropertiesObjectById(int id, const QObject *obj, bool create)
+{
+ return QtQml::qmlAttachedPropertiesObjectById(id, obj, create);
+}
+
+Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
+ const QMetaObject *attachedMetaObject,
+ bool create)
+{
+ return QtQml::qmlAttachedPropertiesObject(idCache, object, attachedMetaObject, create);
+}
+
+#endif // QT_DEPRECATED_SINCE(5, 1)
+
QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
{
#ifndef QQML_NO_DEBUG_PROTOCOL
@@ -1472,6 +1543,12 @@ void QQmlData::destroyed(QObject *object)
compiledData = 0;
}
+ if (deferredData) {
+ deferredData->compiledData->release();
+ delete deferredData;
+ deferredData = 0;
+ }
+
QQmlAbstractBoundSignal *signalHandler = signalHandlers;
while (signalHandler) {
if (signalHandler->isEvaluating()) {
@@ -2150,7 +2227,7 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */)
QFileInfo info(fileName);
const QString absolute = info.absoluteFilePath();
-#if defined(Q_OS_MAC) || defined(Q_OS_WINCE)
+#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
const QString canonical = info.canonicalFilePath();
#elif defined(Q_OS_WIN)
wchar_t buffer[1024];
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 45826a4a67..ab25e06235 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
+class QQmlAbstractUrlInterceptor;
class Q_QML_EXPORT QQmlImageProviderBase
{
@@ -119,6 +120,9 @@ public:
QNetworkAccessManager *networkAccessManager() const;
+ void setUrlInterceptor(QQmlAbstractUrlInterceptor* urlInterceptor);
+ QQmlAbstractUrlInterceptor* urlInterceptor() const;
+
void addImageProvider(const QString &id, QQmlImageProviderBase *);
QQmlImageProviderBase *imageProvider(const QString &id) const;
void removeImageProvider(const QString &id);
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 62e4ee9e5d..b300dcc791 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -125,6 +125,9 @@ public:
~QQmlEnginePrivate();
void init();
+ // No mutex protecting baseModulesUninitialized, because use outside QQmlEngine
+ // is just qmlClearTypeRegistrations (which can't be called while an engine exists)
+ static bool baseModulesUninitialized;
class PropertyCapture {
public:
@@ -171,6 +174,8 @@ public:
QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders;
+ QQmlAbstractUrlInterceptor* urlInterceptor;
+
int scarceResourcesRefCount;
void referenceScarceResources();
void dereferenceScarceResources();
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 88129b7240..0c8e46bd8d 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
^
\endcode
- Note that the QtQuick 1 version is named QDeclarativeError
+ Note that the \l {Qt Quick 1} version is named QDeclarativeError
\sa QQuickView::errors(), QQmlComponent::errors()
*/
@@ -84,10 +84,11 @@ public:
QString description;
quint16 line;
quint16 column;
+ QObject *object;
};
QQmlErrorPrivate::QQmlErrorPrivate()
-: line(0), column(0)
+: line(0), column(0), object()
{
}
@@ -122,6 +123,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
+ d->object = other.d->object;
}
return *this;
}
@@ -215,6 +217,27 @@ void QQmlError::setColumn(int column)
}
/*!
+ Returns the nearest object where this error occurred.
+ Exceptions in bound property expressions set this to the object
+ to which the property belongs. It will be 0 for all
+ other exceptions.
+ */
+QObject *QQmlError::object() const
+{
+ if (d) return d->object;
+ else return 0;
+}
+
+/*!
+ Sets the nearest \a object where this error occurred.
+ */
+void QQmlError::setObject(QObject *object)
+{
+ if (!d) d = new QQmlErrorPrivate;
+ d->object = object;
+}
+
+/*!
Returns the error as a human readable string.
*/
QString QQmlError::toString() const
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index feb13d68d7..e69b3c15ba 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -69,6 +69,8 @@ public:
void setLine(int);
int column() const;
void setColumn(int);
+ QObject *object() const;
+ void setObject(QObject *);
QString toString() const;
private:
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index da66477a03..ddebf02c6c 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -122,7 +122,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
int result = expr->evaluate().toInt(); // result = 400
\endcode
- Note that the QtQuick 1 version is called QDeclarativeExpression.
+ Note that the \l {Qt Quick 1} version is called QDeclarativeExpression.
*/
/*!
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index edef5a91cd..f77b176404 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -54,10 +54,10 @@ QT_BEGIN_NAMESPACE
QQmlExtensionPlugin is a plugin interface that makes it possible to
create QML extensions that can be loaded dynamically into QML applications.
- These extensions allow custom QML types to be made available to the QML engine.
-
+ These extensions allow custom QML types to be made available to the QML engine.
+
To write a QML extension plugin:
-
+
\list
\li Subclass QQmlExtensionPlugin, implement registerTypes() method to register types
using qmlRegisterType(), and export the class using the Q_PLUGIN_METADATA() macro
@@ -74,10 +74,10 @@ QT_BEGIN_NAMESPACE
\section1 An example
Suppose there is a new \c TimeModel C++ class that should be made available
- as a new QML element. It provides the current time through \c hour and \c minute
+ as a new QML element. It provides the current time through \c hour and \c minute
properties, like this:
- \snippet qml/plugins/plugin.cpp 0
+ \snippet plugins/plugin.cpp 0
\dots
To make this class available as a QML type, create a plugin that registers
@@ -85,13 +85,13 @@ QT_BEGIN_NAMESPACE
module will be named \c TimeExample (as defined in the project
file further below).
- \snippet qml/plugins/plugin.cpp plugin
+ \snippet plugins/plugin.cpp plugin
- This registers the \c TimeModel class with the 1.0 version of this
- plugin library, as a QML type called \c Time. The Q_ASSERT statement
+ This registers the \c TimeModel class with the 1.0 version of this
+ plugin library, as a QML type called \c Time. The Q_ASSERT statement
ensures the module is imported correctly by any QML components that use this plugin.
- The project file defines the project as a plugin library and specifies
+ The project file defines the project as a plugin library and specifies
it should be built into the \c imports/TimeExample directory:
\code
@@ -102,26 +102,26 @@ QT_BEGIN_NAMESPACE
DESTDIR = imports/TimeExample
TARGET = qmlqtimeexampleplugin
...
- \endcode
+ \endcode
Finally, a \l{Module Definition qmldir Files}{qmldir file} is required in the \c imports/TimeExample directory
that describes the plugin. This directory includes a \c Clock.qml file that
should be bundled with the plugin, so it needs to be specified in the \c qmldir
file:
- \quotefile qml/plugins/imports/TimeExample/qmldir
+ \quotefile plugins/imports/TimeExample/qmldir
- Once the project is built and installed, the new \c Time element can be
+ Once the project is built and installed, the new \c Time element can be
used by any QML component that imports the \c TimeExample module:
- \snippet qml/plugins/plugins.qml 0
+ \snippet plugins/plugins.qml 0
The full source code is available in the \l {qml/plugins}{plugins example}.
The \l {Writing QML Extensions with C++} tutorial also contains a chapter
on creating QML plugins.
- Note that the QtQuick 1 version is called QDeclarativeExtensionPlugin.
+ Note that the \l {Qt Quick 1} version is called QDeclarativeExtensionPlugin.
\sa QQmlEngine::importPlugin(), {How to Create Qt Plugins}
*/
@@ -134,7 +134,7 @@ QT_BEGIN_NAMESPACE
plugin.
The \a uri is an identifier for the plugin generated by the QML engine
- based on the name and path of the extension's plugin library.
+ based on the name and path of the extension's plugin library.
*/
/*!
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index c9eec4c23b..0c9e685a07 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -317,7 +317,7 @@ class QQmlApplicationPrivate;
class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject
{
- //Application level logic, subclassed by QtQuick if available via QQmlGuiProvider
+ //Application level logic, subclassed by Qt Quick if available via QQmlGuiProvider
Q_OBJECT
Q_PROPERTY(QStringList arguments READ args CONSTANT)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
@@ -344,8 +344,8 @@ protected:
QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0);
private:
- Q_DISABLE_COPY(QQmlApplication);
- Q_DECLARE_PRIVATE(QQmlApplication);
+ Q_DISABLE_COPY(QQmlApplication)
+ Q_DECLARE_PRIVATE(QQmlApplication)
};
class QQmlApplicationPrivate : public QObjectPrivate
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index f793ca9604..50b2c8af0d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -163,6 +163,14 @@ QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeNa
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
+void qmlClearEnginePlugins()
+{
+ foreach (const QString &s, qmlEnginePluginsWithRegisteredTypes()->values()) {
+ QPluginLoader loader(s);
+ loader.unload(); // ### Always returns false, worth doing?
+ }
+ qmlEnginePluginsWithRegisteredTypes()->clear();
+}
class QQmlImportNamespace
{
@@ -1455,7 +1463,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName)
{
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN)
return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 140ca6695e..06b50c09e9 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -182,6 +182,8 @@ private:
QQmlEngine *engine;
};
+void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
+
QT_END_NAMESPACE
#endif // QQMLIMPORT_P_H
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 66670e2658..32f0eeef36 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -165,6 +165,8 @@ QQmlInfo::~QQmlInfo()
}
}
+namespace QtQml {
+
QQmlInfo qmlInfo(const QObject *me)
{
QQmlInfoPrivate *d = new QQmlInfoPrivate;
@@ -188,5 +190,27 @@ QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
return QQmlInfo(d);
}
+} // namespace QtQml
+
+#if QT_DEPRECATED_SINCE(5, 1)
+
+// Also define symbols outside namespace to keep binary compatibility with Qt 5.0
+
+QQmlInfo qmlInfo(const QObject *me)
+{
+ return QtQml::qmlInfo(me);
+}
+
+QQmlInfo qmlInfo(const QObject *me, const QQmlError &error)
+{
+ return QtQml::qmlInfo(me, error);
+}
+
+QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
+{
+ return QtQml::qmlInfo(me, errors);
+}
+
+#endif // QT_DEPRECATED_SINCE(5, 1)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h
index 16fca9428e..56ac788624 100644
--- a/src/qml/qml/qqmlinfo.h
+++ b/src/qml/qml/qqmlinfo.h
@@ -48,6 +48,15 @@
QT_BEGIN_NAMESPACE
+class QQmlInfo;
+
+namespace QtQml {
+ // declared in namespace to avoid symbol conflicts with QtDeclarative
+ Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me);
+ Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error);
+ Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+}
+using namespace QtQml;
class QQmlInfoPrivate;
class Q_QML_EXPORT QQmlInfo : public QDebug
@@ -82,18 +91,14 @@ public:
#endif
private:
- friend Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me);
- friend Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error);
- friend Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QQmlError &error);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QList<QQmlError> &errors);
QQmlInfo(QQmlInfoPrivate *);
QQmlInfoPrivate *d;
};
-Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me);
-Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error);
-Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors);
-
QT_END_NAMESPACE
#endif // QQMLINFO_H
diff --git a/src/qml/qml/qqmlinstruction.cpp b/src/qml/qml/qqmlinstruction.cpp
index c5a4e5d15c..626140d99d 100644
--- a/src/qml/qml/qqmlinstruction.cpp
+++ b/src/qml/qml/qqmlinstruction.cpp
@@ -58,7 +58,7 @@ void QQmlCompiledData::dump(QQmlInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding;
break;
case QQmlInstruction::DeferInit:
- qWarning().nospace() << idx << "\t\t" << "DEFER_INIT\t\t" << instr->deferInit.bindingsSize << "\t" << instr->deferInit.parserStatusSize;
+ qWarning().nospace() << idx << "\t\t" << "DEFER_INIT\t\t" << instr->deferInit.bindingsSize << "\t" << instr->deferInit.parserStatusSize << "\t" << instr->deferInit.objectStackSize << "\t" << instr->deferInit.listStackSize;
break;
case QQmlInstruction::Done:
qWarning().nospace() << idx << "\t\t" << "DONE";
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 2be4c57db4..3b3227cbbb 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -78,6 +78,11 @@ void QQmlDelayedError::setErrorDescription(const QString &description)
m_error.setDescription(description);
}
+void QQmlDelayedError::setErrorObject(QObject *object)
+{
+ m_error.setObject(object);
+}
+
void QQmlDelayedError::setError(const QV4::Exception &e)
{
m_error.setDescription(e.value().toQString());
@@ -340,6 +345,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setLine(line);
if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
ep->warning(error);
return QV4::PersistentValue();
}
@@ -374,6 +380,7 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt,
error.setLine(line);
if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
ep->warning(error);
return QV4::PersistentValue();
}
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 77f8304e95..2e674b214a 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -82,6 +82,7 @@ public:
void setErrorLocation(const QUrl &url, quint16 line, quint16 column);
void setErrorDescription(const QString &description);
+ void setErrorObject(QObject *object);
void setError(const QV4::Exception &e);
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index e6913f01a8..91c9bc2416 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -112,7 +112,7 @@ Attempting to add objects of the incorrect type to a list property will fail.
Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
that it does not request an out of range element using the count() method before calling at().
-The QtQuick 1 version of this class is named QDeclarativeListReference.
+The \l {Qt Quick 1} version of this class is named QDeclarativeListReference.
*/
/*!
@@ -369,7 +369,7 @@ Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
\c {Apple}, \c {Orange} and \c {Banana} all derive from.
-The QtQuick 1 version of this class is named QDeclarativeListProperty.
+The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
*/
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 32e717ed72..58ef5d0930 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -708,13 +708,13 @@ V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
/*!
\qmltype Locale
\instantiates QQmlLocale
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\brief Provides locale specific properties and formatted data
- The Locale object may only be created via the \l{QML:Qt::locale()}{Qt.locale()} function.
+ The Locale object may only be created via the \l{QtQml2::Qt::locale()}{Qt.locale()} function.
It cannot be created directly.
- The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
+ The \l{QtQml2::Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
locale with the specified name, which has the format
"language[_territory][.codeset][@modifier]" or "C".
@@ -751,7 +751,7 @@ V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
}
\endcode
- QtQuick Locale's data is based on Common Locale Data Repository v1.8.1.
+ Qt Quick Locale's data is based on Common Locale Data Repository v1.8.1.
\target FormatType
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index dbb397462f..b7138e01b3 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -46,6 +46,7 @@
#include <private/qqmlcustomparser_p.h>
#include <private/qqmlguard_p.h>
#include <private/qhashedstring_p.h>
+#include <private/qqmlimport_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
@@ -585,16 +586,18 @@ void QQmlTypePrivate::init() const
while(mo) {
QQmlType *t = metaTypeData()->metaObjectToType.value(mo);
if (t) {
- if (t->d->extraData.cd->extFunc) {
- QMetaObjectBuilder builder;
- clone(builder, t->d->extraData.cd->extMetaObject, t->d->baseMetaObject, baseMetaObject);
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- QMetaObject *mmo = builder.toMetaObject();
- mmo->d.superdata = baseMetaObject;
- if (!metaObjects.isEmpty())
- metaObjects.last().metaObject->d.superdata = mmo;
- QQmlProxyMetaObject::ProxyData data = { mmo, t->d->extraData.cd->extFunc, 0, 0 };
- metaObjects << data;
+ if (t->d->regType == QQmlType::CppType) {
+ if (t->d->extraData.cd->extFunc) {
+ QMetaObjectBuilder builder;
+ clone(builder, t->d->extraData.cd->extMetaObject, t->d->baseMetaObject, baseMetaObject);
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ QMetaObject *mmo = builder.toMetaObject();
+ mmo->d.superdata = baseMetaObject;
+ if (!metaObjects.isEmpty())
+ metaObjects.last().metaObject->d.superdata = mmo;
+ QQmlProxyMetaObject::ProxyData data = { mmo, t->d->extraData.cd->extFunc, 0, 0 };
+ metaObjects << data;
+ }
}
}
mo = mo->d.superdata;
@@ -1069,6 +1072,29 @@ QQmlType *QQmlTypeModuleVersion::type(const QHashedV4String &name) const
else return 0;
}
+void qmlClearTypeRegistrations() // Declared in qqml.h
+{
+ //Only cleans global static, assumed no running engine
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ for (int i = 0; i < data->types.count(); ++i)
+ delete data->types.at(i);
+
+ QQmlMetaTypeData::TypeModules::const_iterator i = data->uriToModule.constBegin();
+ for (; i != data->uriToModule.constEnd(); ++i)
+ delete *i;
+
+ data->types.clear();
+ data->idToType.clear();
+ data->nameToType.clear();
+ data->urlToType.clear();
+ data->metaObjectToType.clear();
+ data->uriToModule.clear();
+
+ QQmlEnginePrivate::baseModulesUninitialized = true; //So the engine re-registers its types
+ qmlClearEnginePlugins();
+}
int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
{
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 5f3d115d5f..26fba2b2fc 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -231,6 +231,7 @@ private:
friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
friend int registerInterface(const QQmlPrivate::RegisterInterface &);
friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
+ friend Q_QML_EXPORT void qmlClearTypeRegistrations();
QQmlType(int, const QQmlPrivate::RegisterInterface &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterType &);
@@ -259,6 +260,7 @@ private:
//Used by register functions and creates the QQmlTypeModule for them
friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data);
friend struct QQmlMetaTypeData;
+ friend Q_QML_EXPORT void qmlClearTypeRegistrations();
QQmlTypeModule();
~QQmlTypeModule();
diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
index 156c341158..b0271b11f2 100644
--- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
+++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
For more information about signals and threads, see
\l {Threads and QObjects} and \l {Signals and Slots Across Threads}.
- The QtQuick 1 version of this class is named QDeclarativeNetworkAccessManagerFactory.
+ The \l {Qt Quick 1} version of this class is named QDeclarativeNetworkAccessManagerFactory.
\sa {qml/networkaccessmanagerfactory}{NetworkAccessManagerFactory example}
*/
diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp
index 452a8d7eb8..41b7d962ce 100644
--- a/src/qml/qml/qqmlparserstatus.cpp
+++ b/src/qml/qml/qqmlparserstatus.cpp
@@ -84,7 +84,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- The QtQuick 1.0 version of this class is named QDeclarativeParserStatus.
+ The \l {Qt Quick 1} version of this class is named QDeclarativeParserStatus.
*/
/*! \internal */
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 570435ae81..b5b11d2c6a 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -253,7 +253,7 @@ namespace QQmlPrivate
};
struct RegisterCompositeType {
- const QUrl &url;
+ QUrl url;
const char *uri;
int versionMajor;
int versionMinor;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index cb3866a0dc..d1ecfdc52d 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -113,7 +113,7 @@ property.write(24);
qWarning() << "Pixel size should now be 24:" << property.read().toInt();
\endcode
-The QtQuick 1 version of this class was named QDeclarativeProperty.
+The \l {Qt Quick 1} version of this class was named QDeclarativeProperty.
*/
/*!
@@ -1531,6 +1531,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
// we explicitly disallow this case to avoid confusion. Users can still store one
// in an array in a var property if they need to, but the common case is user error.
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
@@ -1546,6 +1547,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QV4::FunctionObject *f = result.asFunctionObject();
if (f && f->bindingKeyFlag) {
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
writeValueProperty(object, core, QVariant::fromValue(
@@ -1558,12 +1560,14 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
else
errorStr += QLatin1String(QMetaType::typeName(type));
expression->delayedError()->setErrorDescription(errorStr);
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (QV4::FunctionObject *f = result.asFunctionObject()) {
if (f->bindingKeyFlag)
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
else
expression->delayedError()->setErrorDescription(QLatin1String("Unable to assign a function to a property of any type other than var."));
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (!writeValueProperty(object, core, value, context, flags)) {
@@ -1596,6 +1600,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QLatin1String(valueType) +
QLatin1String(" to ") +
QLatin1String(propertyType));
+ expression->delayedError()->setErrorObject(object);
return false;
}
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 7846081a4a..08005f1df2 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -1318,25 +1318,10 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const QS
Q_ASSERT(metaObject);
QQmlPropertyData rv;
- {
- const QMetaObject *cmo = metaObject;
- const QByteArray propertyName = property.toUtf8();
- while (cmo) {
- int idx = cmo->indexOfProperty(propertyName);
- if (idx != -1) {
- QMetaProperty p = cmo->property(idx);
- if (p.isScriptable()) {
- rv.load(p);
- return rv;
- } else {
- while (cmo && cmo->propertyOffset() >= idx)
- cmo = cmo->superClass();
- }
- } else {
- cmo = 0;
- }
- }
- }
+
+ /* It's important to check the method list before checking for properties;
+ * otherwise, if the meta object is dynamic, a property will be created even
+ * if not found and it might obscure a method having the same name. */
//Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
@@ -1358,6 +1343,31 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const QS
}
}
+ {
+ const QMetaObject *cmo = metaObject;
+ const QByteArray propertyName = property.toUtf8();
+ while (cmo) {
+ int idx = cmo->indexOfProperty(propertyName);
+ if (idx != -1) {
+ QMetaProperty p = cmo->property(idx);
+ if (p.isScriptable()) {
+ rv.load(p);
+ return rv;
+ } else {
+ bool changed = false;
+ while (cmo && cmo->propertyOffset() >= idx) {
+ cmo = cmo->superClass();
+ changed = true;
+ }
+ /* If the "cmo" variable didn't change, set it to 0 to
+ * avoid running into an infinite loop */
+ if (!changed) cmo = 0;
+ }
+ } else {
+ cmo = 0;
+ }
+ }
+ }
return rv;
}
@@ -1396,7 +1406,8 @@ qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, const T &name,
if (cache) {
rv = cache->property(name, obj, context);
- } else {
+ }
+ if (!rv) {
local = qQmlPropertyCacheCreate(obj->metaObject(), qQmlPropertyCacheToString(name));
if (local.isValid())
rv = &local;
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 80c7ebf66a..737b39c199 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -215,7 +215,7 @@ private:
friend class QQmlPropertyCache;
quint32 flags;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyRawData::Flags)
class QQmlPropertyData : public QQmlPropertyRawData
{
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index c24891f6d6..7e3a23b489 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -1317,13 +1317,15 @@ bool QQmlScript::Parser::parse(const QString &qmlcode, const QByteArray & /* pre
QQmlJS::Parser parser(&data->engine);
- if (! parser.parse() || !_errors.isEmpty()) {
+ if (! parser.parse() || !parser.diagnosticMessages().isEmpty()) {
// Extract errors from the parser
foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {
- if (m.isWarning())
+ if (m.isWarning()) {
+ qWarning("%s:%d : %s", qPrintable(_scriptFile), m.loc.startLine, qPrintable(m.message));
continue;
+ }
QQmlError error;
error.setUrl(url);
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
index 54e7a67b65..250c71d6ac 100644
--- a/src/qml/qml/qqmlscript_p.h
+++ b/src/qml/qml/qqmlscript_p.h
@@ -512,7 +512,7 @@ public:
}
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index c91fc06c22..022083c596 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qqmltypeloader_p.h"
+#include "qqmlabstracturlinterceptor_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
@@ -250,6 +251,23 @@ QQmlDataBlob::~QQmlDataBlob()
}
/*!
+ Sets the manager, and does stuff like selection which needs access to the manager.
+ Must be called before loading can occur.
+*/
+void QQmlDataBlob::startLoading(QQmlDataLoader *manager)
+{
+ Q_ASSERT(status() == QQmlDataBlob::Null);
+ Q_ASSERT(m_manager == 0);
+ m_data.setStatus(QQmlDataBlob::Loading);
+ m_manager = manager;
+
+ //Set here because we need to get the engine from the manager
+ if (manager && manager->engine() && manager->engine()->urlInterceptor())
+ m_url = manager->engine()->urlInterceptor()->intercept(m_url,
+ (QQmlAbstractUrlInterceptor::DataType)m_type);
+}
+
+/*!
Returns the type provided to the constructor.
*/
QQmlDataBlob::Type QQmlDataBlob::type() const
@@ -892,12 +910,7 @@ void QQmlDataLoader::load(QQmlDataBlob *blob, Mode mode)
qWarning("QQmlDataLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()),
m_thread->isThisThread()?"Compile":"Engine");
#endif
-
- Q_ASSERT(blob->status() == QQmlDataBlob::Null);
- Q_ASSERT(blob->m_manager == 0);
-
- blob->m_data.setStatus(QQmlDataBlob::Loading);
- blob->m_manager = this;
+ blob->startLoading(this);
if (m_thread->isThisThread()) {
unlock();
@@ -930,11 +943,7 @@ void QQmlDataLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da
m_thread->isThisThread()?"Compile":"Engine");
#endif
- Q_ASSERT(blob->status() == QQmlDataBlob::Null);
- Q_ASSERT(blob->m_manager == 0);
-
- blob->m_data.setStatus(QQmlDataBlob::Loading);
- blob->m_manager = this;
+ blob->startLoading(this);
if (m_thread->isThisThread()) {
unlock();
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index ee6773b8e7..88bca702db 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -67,6 +67,7 @@
#include <private/qqmldirparser_p.h>
#include <private/qqmlbundle_p.h>
#include <private/qflagpointer_p.h>
+#include <private/qqmlabstracturlinterceptor_p.h>
#include <private/qv4value_p.h>
#include <private/qv4script_p.h>
@@ -94,15 +95,17 @@ public:
Error // Error
};
- enum Type {
- QmlFile,
- JavaScriptFile,
- QmldirFile
+ enum Type { //Matched in QQmlAbstractUrlInterceptor
+ QmlFile = QQmlAbstractUrlInterceptor::QmlFile,
+ JavaScriptFile = QQmlAbstractUrlInterceptor::JavaScriptFile,
+ QmldirFile = QQmlAbstractUrlInterceptor::QmldirFile
};
QQmlDataBlob(const QUrl &, Type);
virtual ~QQmlDataBlob();
+ void startLoading(QQmlDataLoader* manager);
+
Type type() const;
Status status() const;
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 309275777e..cde16e885d 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -47,6 +47,7 @@
#include <private/qmetaobjectbuilder_p.h>
#include "qqmldata_p.h"
#include "qqml.h"
+#include "qqmlinfo.h"
#include "qqmlcustomparser_p.h"
#include "qqmlengine.h"
#include "qqmlcontext.h"
@@ -91,6 +92,8 @@ using namespace QQmlVMETypes;
goto exceptionExit; \
}
+bool QQmlVME::s_enableComponentComplete = true;
+
void QQmlVME::init(QQmlContextData *ctxt, QQmlCompiledData *comp, int start,
QQmlContextData *creation)
{
@@ -132,12 +135,12 @@ bool QQmlVME::initDeferred(QObject *object)
{
QQmlData *data = QQmlData::get(object);
- if (!data || !data->context || !data->compiledData)
+ if (!data || !data->deferredData)
return false;
- QQmlContextData *ctxt = data->context;
- QQmlCompiledData *comp = data->compiledData;
- int start = data->deferredIdx;
+ QQmlContextData *ctxt = data->deferredData->context;
+ QQmlCompiledData *comp = data->deferredData->compiledData;
+ int start = data->deferredData->deferredIdx;
State initState;
initState.flags = State::Deferred;
@@ -949,10 +952,19 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
if (instr.deferCount) {
QObject *target = objects.top();
QQmlData *data = QQmlData::get(target, true);
- data->compiledData = COMP;
- data->compiledData->addref(); // Keep this data referenced until we're initialized
- data->deferredIdx = INSTRUCTIONSTREAM - COMP->bytecode.constData();
- Q_ASSERT(data->deferredIdx != 0);
+ if (data->deferredData) {
+ //This rare case still won't always work right
+ qmlInfo(target) << "Setting deferred property across multiple components may not work";
+ delete data->deferredData;
+ }
+ data->deferredData = new QQmlData::DeferredData;
+ //If we're in a CreateQML here, data->compiledData could be reset later
+ data->deferredData->compiledData = COMP;
+ data->deferredData->context = CTXT;
+ // Keep this data referenced until we're initialized
+ data->deferredData->compiledData->addref();
+ data->deferredData->deferredIdx = INSTRUCTIONSTREAM - COMP->bytecode.constData();
+ Q_ASSERT(data->deferredData->deferredIdx != 0);
INSTRUCTIONSTREAM += instr.deferCount;
}
QML_END_INSTR(Defer)
@@ -1243,7 +1255,7 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
bindValues.deallocate();
}
- if (!QQmlEnginePrivate::designerMode()) { // the qml designer does the component complete later
+ if (componentCompleteEnabled()) { // the qml designer does the component complete later
QQmlTrace trace("VME Component Complete");
while (!parserStatus.isEmpty()) {
QQmlParserStatus *status = parserStatus.pop();
@@ -1291,7 +1303,8 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
Q_ASSERT(d);
Q_ASSERT(d->context);
a->add(&d->context->componentAttached);
- emit a->completed();
+ if (componentCompleteEnabled())
+ emit a->completed();
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return 0;
@@ -1307,6 +1320,21 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
return rv;
}
+void QQmlVME::enableComponentComplete()
+{
+ s_enableComponentComplete = true;
+}
+
+void QQmlVME::disableComponentComplete()
+{
+ s_enableComponentComplete = false;
+}
+
+bool QQmlVME::componentCompleteEnabled()
+{
+ return s_enableComponentComplete;
+}
+
void QQmlVME::blank(QFiniteStack<QQmlAbstractBinding *> &bs)
{
for (int ii = 0; ii < bs.count(); ++ii) {
@@ -1368,7 +1396,7 @@ bool QQmlVMEGuard::isOK() const
return false;
for (int ii = 0; ii < m_contextCount; ++ii)
- if (m_contexts[ii].isNull())
+ if (m_contexts[ii].isNull() || !m_contexts[ii]->engine)
return false;
return true;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 863a7a3c6b..750076f277 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -139,6 +139,10 @@ public:
QObject *execute(QList<QQmlError> *errors, const Interrupt & = Interrupt());
QQmlContextData *complete(const Interrupt & = Interrupt());
+ static void enableComponentComplete();
+ static void disableComponentComplete();
+ static bool componentCompleteEnabled();
+
private:
friend class QQmlVMEGuard;
@@ -178,6 +182,8 @@ private:
static void blank(QFiniteStack<QQmlParserStatus *> &);
static void blank(QFiniteStack<QQmlAbstractBinding *> &);
+
+ static bool s_enableComponentComplete;
};
// Used to check that a QQmlVME that is interrupted mid-execution
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 46f9237727..162f3dbd22 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1046,6 +1046,7 @@ private:
int m_status;
QString m_statusText;
QNetworkRequest m_request;
+ QStringList m_addedHeaders;
QQmlGuard<QNetworkReply> m_network;
void destroyNetwork();
@@ -1100,6 +1101,7 @@ Value QQmlXMLHttpRequest::open(const Value &me, const QString &method,
m_method = method;
m_url = url;
m_state = Opened;
+ m_addedHeaders.clear();
dispatchCallback(me);
return Value::undefinedValue();
}
@@ -1108,10 +1110,11 @@ void QQmlXMLHttpRequest::addHeader(const QString &name, const QString &value)
{
QByteArray utfname = name.toUtf8();
- if (m_request.hasRawHeader(utfname)) {
+ if (m_addedHeaders.contains(name, Qt::CaseInsensitive)) {
m_request.setRawHeader(utfname, m_request.rawHeader(utfname) + ',' + value.toUtf8());
} else {
m_request.setRawHeader(utfname, value.toUtf8());
+ m_addedHeaders.append(name);
}
}
diff --git a/src/qml/qml/v4/qv4jsonobject_p.h b/src/qml/qml/v4/qv4jsonobject_p.h
index 4225f4c4ae..465539e504 100644
--- a/src/qml/qml/v4/qv4jsonobject_p.h
+++ b/src/qml/qml/v4/qv4jsonobject_p.h
@@ -74,6 +74,7 @@ private:
static QJsonValue toJsonValue(const QV4::Value &value, V4ObjectSet &visitedObjects);
static QJsonObject toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects);
static QJsonArray toJsonArray(QV4::ArrayObject *a, V4ObjectSet &visitedObjects);
+
};
}
diff --git a/src/qml/qml/v4/qv4qobjectwrapper.cpp b/src/qml/qml/v4/qv4qobjectwrapper.cpp
index 42b057c48d..a267c4a894 100644
--- a/src/qml/qml/v4/qv4qobjectwrapper.cpp
+++ b/src/qml/qml/v4/qv4qobjectwrapper.cpp
@@ -266,10 +266,12 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont
QQmlData *ddata = QQmlData::get(m_object, false);
if (!ddata)
return 0;
+ QQmlPropertyData *result = 0;
if (ddata && ddata->propertyCache)
- return ddata->propertyCache->property(propertystring, m_object, qmlContext);
- else
- return QQmlPropertyCache::property(engine->v8Engine->engine(), m_object, propertystring, qmlContext, *local);
+ result = ddata->propertyCache->property(propertystring, m_object, qmlContext);
+ if (!result)
+ result = QQmlPropertyCache::property(engine->v8Engine->engine(), m_object, propertystring, qmlContext, *local);
+ return result;
}
Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports)
@@ -1078,7 +1080,7 @@ static QV4::Value CallMethod(QObject *object, int index, int returnType, int arg
Returns the match score for converting \a actual to be of type \a conversionType. A
zero score means "perfect match" whereas a higher score is worse.
- The conversion table is copied out of the QtScript callQtMethod() function.
+ The conversion table is copied out of the \l QScript::callQtMethod() function.
*/
static int MatchScore(const QV4::Value &actual, int conversionType)
{
diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp
index 24d46277e9..13281875e6 100644
--- a/src/qml/qml/v8/qjsengine.cpp
+++ b/src/qml/qml/v8/qjsengine.cpp
@@ -198,6 +198,10 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
/*!
Destroys this QJSEngine.
+
+ Garbage is not collected from the persistent JS heap during QJSEngine
+ destruction. If you need all memory freed, call collectGarbage manually
+ right before destroying the QJSEngine.
*/
QJSEngine::~QJSEngine()
{
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 7c7ac124f0..97736355d4 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -612,7 +612,7 @@ to \c format.
The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
property, a QDate, or QDateTime value. The \a format parameter may be any of
the possible format values as described for
-\l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
+\l{QtQml2::Qt::formatDateTime()}{Qt.formatDateTime()}.
If \a format is not specified, \a date is formatted using
\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
@@ -655,7 +655,7 @@ Returns a string representation of \c time, optionally formatted according to
The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
value. The \a format parameter may be any of the possible format values as
-described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
+described for \l{QtQml2::Qt::formatDateTime()}{Qt.formatDateTime()}.
If \a format is not specified, \a time is formatted using
\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
@@ -773,7 +773,7 @@ For example, if the following date/time value was specified:
\endcode
This \a dateTime value could be passed to \c Qt.formatDateTime(),
-\l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
+\l {QtQml2::Qt::formatDate()}{Qt.formatDate()} or \l {QtQml2::Qt::formatTime()}{Qt.formatTime()}
with the \a format values below to produce the following results:
\table
@@ -934,7 +934,7 @@ Example (where \c parentItem is the id of an existing QML item):
\snippet qml/createQmlObject.qml 0
-In the case of an error, a QtScript Error object is thrown. This object has an additional property,
+In the case of an error, a \l {Qt Script} Error object is thrown. This object has an additional property,
\c qmlErrors, which is an array of the errors encountered.
Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
@@ -942,7 +942,7 @@ For example, if the above snippet had misspelled color as 'colro' then the array
Note that this function returns immediately, and therefore may not work if
the \a qml string loads new components (that is, external QML files that have not yet been loaded).
-If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
+If this is the case, consider using \l{QtQml2::Qt::createComponent()}{Qt.createComponent()} instead.
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
@@ -1070,7 +1070,7 @@ For example:
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
To create a QML object from an arbitrary string of QML (instead of a file),
-use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
+use \l{QtQml2::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
Value QtObject::method_createComponent(SimpleCallContext *ctx)
{
@@ -1243,9 +1243,9 @@ DEFINE_MANAGED_VTABLE(BindingFunction);
\snippet qml/qtBinding.4.qml 0
- Note: in QtQuick 1.x, all function assignment was treated as
+ \note In \l {Qt Quick 1}, all function assignment was treated as
binding assignment, so the Qt.binding() function is new in
- QtQuick 2.0.
+ \l {Qt Quick}{Qt Quick 2}.
\since QtQuick 2.0
*/
@@ -1613,7 +1613,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
Example:
\snippet qml/qsTranslate.qml 0
- \sa {Localization And Internationalization Support In Qt Quick}
+ \sa {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
{
@@ -1669,7 +1669,7 @@ Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
Example:
\snippet qml/qtTranslateNoOp.qml 0
- \sa {Localization And Internationalization Support In Qt Quick}
+ \sa {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
{
@@ -1693,7 +1693,7 @@ Value GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
Example:
\snippet qml/qsTr.qml 0
- \sa {Localization And Internationalization Support In Qt Quick}
+ \sa {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
{
@@ -1747,7 +1747,7 @@ Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
Example:
\snippet qml/qtTrNoOp.qml 0
- \sa {Localization And Internationalization Support In Qt Quick}
+ \sa {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
{
@@ -1784,7 +1784,7 @@ Value GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
Creating binary translation (QM) files suitable for use with this function requires passing
the \c -idbased option to the \c lrelease tool.
- \sa QT_TRID_NOOP, {Localization And Internationalization Support In Qt Quick}
+ \sa QT_TRID_NOOP, {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
{
@@ -1816,7 +1816,7 @@ Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
Example:
\snippet qml/qtTrIdNoOp.qml 0
- \sa qsTrId(), {Localization And Internationalization Support In Qt Quick}
+ \sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
Value GlobalExtensions::method_qsTrIdNoOp(SimpleCallContext *ctx)
{