Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/qml/qqmlcomponent.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||
5 | ** | - | ||||||||||||||||||
6 | ** This file is part of the QtQml module of the Qt Toolkit. | - | ||||||||||||||||||
7 | ** | - | ||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||||||||
16 | ** | - | ||||||||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||
24 | ** | - | ||||||||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||
35 | ** | - | ||||||||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
37 | ** | - | ||||||||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | #include "qqmlcomponent.h" | - | ||||||||||||||||||
41 | #include "qqmlcomponent_p.h" | - | ||||||||||||||||||
42 | #include "qqmlcomponentattached_p.h" | - | ||||||||||||||||||
43 | - | |||||||||||||||||||
44 | #include "qqmlcontext_p.h" | - | ||||||||||||||||||
45 | #include "qqmlengine_p.h" | - | ||||||||||||||||||
46 | #include "qqmlvme_p.h" | - | ||||||||||||||||||
47 | #include "qqml.h" | - | ||||||||||||||||||
48 | #include "qqmlengine.h" | - | ||||||||||||||||||
49 | #include "qqmlbinding_p.h" | - | ||||||||||||||||||
50 | #include "qqmlincubator.h" | - | ||||||||||||||||||
51 | #include "qqmlincubator_p.h" | - | ||||||||||||||||||
52 | #include <private/qqmljavascriptexpression_p.h> | - | ||||||||||||||||||
53 | - | |||||||||||||||||||
54 | #include <private/qv8engine_p.h> | - | ||||||||||||||||||
55 | - | |||||||||||||||||||
56 | #include <private/qv4functionobject_p.h> | - | ||||||||||||||||||
57 | #include <private/qv4script_p.h> | - | ||||||||||||||||||
58 | #include <private/qv4scopedvalue_p.h> | - | ||||||||||||||||||
59 | #include <private/qv4objectiterator_p.h> | - | ||||||||||||||||||
60 | #include <private/qv4qobjectwrapper_p.h> | - | ||||||||||||||||||
61 | #include <private/qv4jscall_p.h> | - | ||||||||||||||||||
62 | - | |||||||||||||||||||
63 | #include <QDir> | - | ||||||||||||||||||
64 | #include <QStack> | - | ||||||||||||||||||
65 | #include <QStringList> | - | ||||||||||||||||||
66 | #include <QThreadStorage> | - | ||||||||||||||||||
67 | #include <QtCore/qdebug.h> | - | ||||||||||||||||||
68 | #include <qqmlinfo.h> | - | ||||||||||||||||||
69 | #include "qqmlmemoryprofiler_p.h" | - | ||||||||||||||||||
70 | - | |||||||||||||||||||
71 | namespace { | - | ||||||||||||||||||
72 | QThreadStorage<int> creationDepth; | - | ||||||||||||||||||
73 | } | - | ||||||||||||||||||
74 | - | |||||||||||||||||||
75 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
76 | - | |||||||||||||||||||
77 | class QQmlComponentExtension : public QV8Engine::Deletable | - | ||||||||||||||||||
78 | { | - | ||||||||||||||||||
79 | public: | - | ||||||||||||||||||
80 | QQmlComponentExtension(QV4::ExecutionEngine *v4); | - | ||||||||||||||||||
81 | virtual ~QQmlComponentExtension(); | - | ||||||||||||||||||
82 | - | |||||||||||||||||||
83 | QV4::PersistentValue incubationProto; | - | ||||||||||||||||||
84 | }; | - | ||||||||||||||||||
85 | V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); executed 6 times by 3 tests: extensionId = QV8Engine::registerExtension(); Executed by:
executed 6 times by 3 tests: end of block Executed by:
executed 8 times by 3 tests: end of block Executed by:
executed 10 times by 3 tests: return rv; Executed by:
| 0-10 | ||||||||||||||||||
86 | - | |||||||||||||||||||
87 | /*! | - | ||||||||||||||||||
88 | \class QQmlComponent | - | ||||||||||||||||||
89 | \since 5.0 | - | ||||||||||||||||||
90 | \inmodule QtQml | - | ||||||||||||||||||
91 | - | |||||||||||||||||||
92 | \brief The QQmlComponent class encapsulates a QML component definition. | - | ||||||||||||||||||
93 | - | |||||||||||||||||||
94 | Components are reusable, encapsulated QML types with well-defined interfaces. | - | ||||||||||||||||||
95 | - | |||||||||||||||||||
96 | A QQmlComponent instance can be created from a QML file. | - | ||||||||||||||||||
97 | For example, if there is a \c main.qml file like this: | - | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | \qml | - | ||||||||||||||||||
100 | import QtQuick 2.0 | - | ||||||||||||||||||
101 | - | |||||||||||||||||||
102 | Item { | - | ||||||||||||||||||
103 | width: 200 | - | ||||||||||||||||||
104 | height: 200 | - | ||||||||||||||||||
105 | } | - | ||||||||||||||||||
106 | \endqml | - | ||||||||||||||||||
107 | - | |||||||||||||||||||
108 | The following code loads this QML file as a component, creates an instance of | - | ||||||||||||||||||
109 | this component using create(), and then queries the \l Item's \l {Item::}{width} | - | ||||||||||||||||||
110 | value: | - | ||||||||||||||||||
111 | - | |||||||||||||||||||
112 | \code | - | ||||||||||||||||||
113 | QQmlEngine *engine = new QQmlEngine; | - | ||||||||||||||||||
114 | QQmlComponent component(engine, QUrl::fromLocalFile("main.qml")); | - | ||||||||||||||||||
115 | - | |||||||||||||||||||
116 | QObject *myObject = component.create(); | - | ||||||||||||||||||
117 | QQuickItem *item = qobject_cast<QQuickItem*>(myObject); | - | ||||||||||||||||||
118 | int width = item->width(); // width = 200 | - | ||||||||||||||||||
119 | \endcode | - | ||||||||||||||||||
120 | - | |||||||||||||||||||
121 | To create instances of a component in code where a QQmlEngine instance is | - | ||||||||||||||||||
122 | not available, you can use \l qmlContext() or \l qmlEngine(). For example, | - | ||||||||||||||||||
123 | in the scenario below, child items are being created within a QQuickItem | - | ||||||||||||||||||
124 | subclass: | - | ||||||||||||||||||
125 | - | |||||||||||||||||||
126 | \code | - | ||||||||||||||||||
127 | void MyCppItem::init() | - | ||||||||||||||||||
128 | { | - | ||||||||||||||||||
129 | QQmlEngine *engine = qmlEngine(this); | - | ||||||||||||||||||
130 | // Or: | - | ||||||||||||||||||
131 | // QQmlEngine *engine = qmlContext(this)->engine(); | - | ||||||||||||||||||
132 | QQmlComponent component(engine, QUrl::fromLocalFile("MyItem.qml")); | - | ||||||||||||||||||
133 | QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create()); | - | ||||||||||||||||||
134 | childItem->setParentItem(this); | - | ||||||||||||||||||
135 | } | - | ||||||||||||||||||
136 | \endcode | - | ||||||||||||||||||
137 | - | |||||||||||||||||||
138 | Note that these functions will return \c null when called inside the | - | ||||||||||||||||||
139 | constructor of a QObject subclass, as the instance will not yet have | - | ||||||||||||||||||
140 | a context nor engine. | - | ||||||||||||||||||
141 | - | |||||||||||||||||||
142 | \section2 Network Components | - | ||||||||||||||||||
143 | - | |||||||||||||||||||
144 | If the URL passed to QQmlComponent is a network resource, or if the QML document references a | - | ||||||||||||||||||
145 | network resource, the QQmlComponent has to fetch the network data before it is able to create | - | ||||||||||||||||||
146 | objects. In this case, the QQmlComponent will have a \l {QQmlComponent::Loading}{Loading} | - | ||||||||||||||||||
147 | \l {QQmlComponent::status()}{status}. An application will have to wait until the component | - | ||||||||||||||||||
148 | is \l {QQmlComponent::Ready}{Ready} before calling \l {QQmlComponent::create()}. | - | ||||||||||||||||||
149 | - | |||||||||||||||||||
150 | The following example shows how to load a QML file from a network resource. After creating | - | ||||||||||||||||||
151 | the QQmlComponent, it tests whether the component is loading. If it is, it connects to the | - | ||||||||||||||||||
152 | QQmlComponent::statusChanged() signal and otherwise calls the \c {continueLoading()} method | - | ||||||||||||||||||
153 | directly. Note that QQmlComponent::isLoading() may be false for a network component if the | - | ||||||||||||||||||
154 | component has been cached and is ready immediately. | - | ||||||||||||||||||
155 | - | |||||||||||||||||||
156 | \code | - | ||||||||||||||||||
157 | MyApplication::MyApplication() | - | ||||||||||||||||||
158 | { | - | ||||||||||||||||||
159 | // ... | - | ||||||||||||||||||
160 | component = new QQmlComponent(engine, QUrl("http://www.example.com/main.qml")); | - | ||||||||||||||||||
161 | if (component->isLoading()) | - | ||||||||||||||||||
162 | QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)), | - | ||||||||||||||||||
163 | this, SLOT(continueLoading())); | - | ||||||||||||||||||
164 | else | - | ||||||||||||||||||
165 | continueLoading(); | - | ||||||||||||||||||
166 | } | - | ||||||||||||||||||
167 | - | |||||||||||||||||||
168 | void MyApplication::continueLoading() | - | ||||||||||||||||||
169 | { | - | ||||||||||||||||||
170 | if (component->isError()) { | - | ||||||||||||||||||
171 | qWarning() << component->errors(); | - | ||||||||||||||||||
172 | } else { | - | ||||||||||||||||||
173 | QObject *myObject = component->create(); | - | ||||||||||||||||||
174 | } | - | ||||||||||||||||||
175 | } | - | ||||||||||||||||||
176 | \endcode | - | ||||||||||||||||||
177 | - | |||||||||||||||||||
178 | Note that the \l {Qt Quick 1} version is named QDeclarativeComponent. | - | ||||||||||||||||||
179 | */ | - | ||||||||||||||||||
180 | - | |||||||||||||||||||
181 | /*! | - | ||||||||||||||||||
182 | \qmltype Component | - | ||||||||||||||||||
183 | \instantiates QQmlComponent | - | ||||||||||||||||||
184 | \ingroup qml-utility-elements | - | ||||||||||||||||||
185 | \inqmlmodule QtQml | - | ||||||||||||||||||
186 | \brief Encapsulates a QML component definition. | - | ||||||||||||||||||
187 | - | |||||||||||||||||||
188 | Components are reusable, encapsulated QML types with well-defined interfaces. | - | ||||||||||||||||||
189 | - | |||||||||||||||||||
190 | Components are often defined by \l {{QML Documents}}{component files} - | - | ||||||||||||||||||
191 | that is, \c .qml files. The \e Component type essentially allows QML components | - | ||||||||||||||||||
192 | to be defined inline, within a \l {QML Documents}{QML document}, rather than as a separate QML file. | - | ||||||||||||||||||
193 | This may be useful for reusing a small component within a QML file, or for defining | - | ||||||||||||||||||
194 | a component that logically belongs with other QML components within a file. | - | ||||||||||||||||||
195 | - | |||||||||||||||||||
196 | For example, here is a component that is used by multiple \l Loader objects. | - | ||||||||||||||||||
197 | It contains a single item, a \l Rectangle: | - | ||||||||||||||||||
198 | - | |||||||||||||||||||
199 | \snippet qml/component.qml 0 | - | ||||||||||||||||||
200 | - | |||||||||||||||||||
201 | Notice that while a \l Rectangle by itself would be automatically | - | ||||||||||||||||||
202 | rendered and displayed, this is not the case for the above rectangle | - | ||||||||||||||||||
203 | because it is defined inside a \c Component. The component encapsulates the | - | ||||||||||||||||||
204 | QML types within, as if they were defined in a separate QML | - | ||||||||||||||||||
205 | file, and is not loaded until requested (in this case, by the | - | ||||||||||||||||||
206 | two \l Loader objects). Because Component is not derived from Item, you cannot | - | ||||||||||||||||||
207 | anchor anything to it. | - | ||||||||||||||||||
208 | - | |||||||||||||||||||
209 | Defining a \c Component is similar to defining a \l {QML Documents}{QML document}. | - | ||||||||||||||||||
210 | A QML document has a single top-level item that defines the behavior and | - | ||||||||||||||||||
211 | properties of that component, and cannot define properties or behavior outside | - | ||||||||||||||||||
212 | of that top-level item. In the same way, a \c Component definition contains a single | - | ||||||||||||||||||
213 | top level item (which in the above example is a \l Rectangle) and cannot define any | - | ||||||||||||||||||
214 | data outside of this item, with the exception of an \e id (which in the above example | - | ||||||||||||||||||
215 | is \e redSquare). | - | ||||||||||||||||||
216 | - | |||||||||||||||||||
217 | The \c Component type is commonly used to provide graphical components | - | ||||||||||||||||||
218 | for views. For example, the ListView::delegate property requires a \c Component | - | ||||||||||||||||||
219 | to specify how each list item is to be displayed. | - | ||||||||||||||||||
220 | - | |||||||||||||||||||
221 | \c Component objects can also be created dynamically using | - | ||||||||||||||||||
222 | \l{QtQml::Qt::createComponent()}{Qt.createComponent()}. | - | ||||||||||||||||||
223 | - | |||||||||||||||||||
224 | \section2 Creation Context | - | ||||||||||||||||||
225 | - | |||||||||||||||||||
226 | The creation context of a Component corresponds to the context where the Component was declared. | - | ||||||||||||||||||
227 | This context is used as the parent context (creating a \l{qtqml-documents-scope.html#component-instance-hierarchy}{context hierarchy}) | - | ||||||||||||||||||
228 | when the component is instantiated by an object such as a ListView or a Loader. | - | ||||||||||||||||||
229 | - | |||||||||||||||||||
230 | In the following example, \c comp1 is created within the root context of MyItem.qml, and any objects | - | ||||||||||||||||||
231 | instantiated from this component will have access to the ids and properties within that context, | - | ||||||||||||||||||
232 | such as \c internalSettings.color. When \c comp1 is used as a ListView delegate in another context | - | ||||||||||||||||||
233 | (as in main.qml below), it will continue to have access to the properties of its creation context | - | ||||||||||||||||||
234 | (which would otherwise be private to external users). | - | ||||||||||||||||||
235 | - | |||||||||||||||||||
236 | \table | - | ||||||||||||||||||
237 | \row | - | ||||||||||||||||||
238 | \li MyItem.qml | - | ||||||||||||||||||
239 | \li \snippet qml/component/MyItem.qml 0 | - | ||||||||||||||||||
240 | \row | - | ||||||||||||||||||
241 | \li main.qml | - | ||||||||||||||||||
242 | \li \snippet qml/component/main.qml 0 | - | ||||||||||||||||||
243 | \endtable | - | ||||||||||||||||||
244 | - | |||||||||||||||||||
245 | It is important that the lifetime of the creation context outlive any created objects. See | - | ||||||||||||||||||
246 | \l{Maintaining Dynamically Created Objects} for more details. | - | ||||||||||||||||||
247 | */ | - | ||||||||||||||||||
248 | - | |||||||||||||||||||
249 | /*! | - | ||||||||||||||||||
250 | \qmlattachedsignal Component::completed() | - | ||||||||||||||||||
251 | - | |||||||||||||||||||
252 | Emitted after the object has been instantiated. This can be used to | - | ||||||||||||||||||
253 | execute script code at startup, once the full QML environment has been | - | ||||||||||||||||||
254 | established. | - | ||||||||||||||||||
255 | - | |||||||||||||||||||
256 | The corresponding handler is \c onCompleted. It can be declared on | - | ||||||||||||||||||
257 | any object. The order of running the \c onCompleted handlers is | - | ||||||||||||||||||
258 | undefined. | - | ||||||||||||||||||
259 | - | |||||||||||||||||||
260 | \qml | - | ||||||||||||||||||
261 | Rectangle { | - | ||||||||||||||||||
262 | Component.onCompleted: console.log("Completed Running!") | - | ||||||||||||||||||
263 | Rectangle { | - | ||||||||||||||||||
264 | Component.onCompleted: console.log("Nested Completed Running!") | - | ||||||||||||||||||
265 | } | - | ||||||||||||||||||
266 | } | - | ||||||||||||||||||
267 | \endqml | - | ||||||||||||||||||
268 | */ | - | ||||||||||||||||||
269 | - | |||||||||||||||||||
270 | /*! | - | ||||||||||||||||||
271 | \qmlattachedsignal Component::destruction() | - | ||||||||||||||||||
272 | - | |||||||||||||||||||
273 | Emitted as the object begins destruction. This can be used to undo | - | ||||||||||||||||||
274 | work done in response to the \l {completed}{completed()} signal, or other | - | ||||||||||||||||||
275 | imperative code in your application. | - | ||||||||||||||||||
276 | - | |||||||||||||||||||
277 | The corresponding handler is \c onDestruction. It can be declared on | - | ||||||||||||||||||
278 | any object. The order of running the \c onDestruction handlers is | - | ||||||||||||||||||
279 | undefined. | - | ||||||||||||||||||
280 | - | |||||||||||||||||||
281 | \qml | - | ||||||||||||||||||
282 | Rectangle { | - | ||||||||||||||||||
283 | Component.onDestruction: console.log("Destruction Beginning!") | - | ||||||||||||||||||
284 | Rectangle { | - | ||||||||||||||||||
285 | Component.onDestruction: console.log("Nested Destruction Beginning!") | - | ||||||||||||||||||
286 | } | - | ||||||||||||||||||
287 | } | - | ||||||||||||||||||
288 | \endqml | - | ||||||||||||||||||
289 | - | |||||||||||||||||||
290 | \sa {Qt QML} | - | ||||||||||||||||||
291 | */ | - | ||||||||||||||||||
292 | - | |||||||||||||||||||
293 | /*! | - | ||||||||||||||||||
294 | \enum QQmlComponent::Status | - | ||||||||||||||||||
295 | - | |||||||||||||||||||
296 | Specifies the loading status of the QQmlComponent. | - | ||||||||||||||||||
297 | - | |||||||||||||||||||
298 | \value Null This QQmlComponent has no data. Call loadUrl() or setData() to add QML content. | - | ||||||||||||||||||
299 | \value Ready This QQmlComponent is ready and create() may be called. | - | ||||||||||||||||||
300 | \value Loading This QQmlComponent is loading network data. | - | ||||||||||||||||||
301 | \value Error An error has occurred. Call errors() to retrieve a list of \l {QQmlError}{errors}. | - | ||||||||||||||||||
302 | */ | - | ||||||||||||||||||
303 | - | |||||||||||||||||||
304 | /*! | - | ||||||||||||||||||
305 | \enum QQmlComponent::CompilationMode | - | ||||||||||||||||||
306 | - | |||||||||||||||||||
307 | Specifies whether the QQmlComponent should load the component immediately, or asynchonously. | - | ||||||||||||||||||
308 | - | |||||||||||||||||||
309 | \value PreferSynchronous Prefer loading/compiling the component immediately, blocking the thread. | - | ||||||||||||||||||
310 | This is not always possible; for example, remote URLs will always load asynchronously. | - | ||||||||||||||||||
311 | \value Asynchronous Load/compile the component in a background thread. | - | ||||||||||||||||||
312 | */ | - | ||||||||||||||||||
313 | - | |||||||||||||||||||
314 | void QQmlComponentPrivate::typeDataReady(QQmlTypeData *) | - | ||||||||||||||||||
315 | { | - | ||||||||||||||||||
316 | Q_Q(QQmlComponent); | - | ||||||||||||||||||
317 | - | |||||||||||||||||||
318 | Q_ASSERT(typeData); | - | ||||||||||||||||||
319 | - | |||||||||||||||||||
320 | fromTypeData(typeData); | - | ||||||||||||||||||
321 | typeData = nullptr; | - | ||||||||||||||||||
322 | progress = 1.0; | - | ||||||||||||||||||
323 | - | |||||||||||||||||||
324 | emit q->statusChanged(q->status()); | - | ||||||||||||||||||
325 | emit q->progressChanged(progress); | - | ||||||||||||||||||
326 | } executed 134 times by 12 tests: end of block Executed by:
| 134 | ||||||||||||||||||
327 | - | |||||||||||||||||||
328 | void QQmlComponentPrivate::typeDataProgress(QQmlTypeData *, qreal p) | - | ||||||||||||||||||
329 | { | - | ||||||||||||||||||
330 | Q_Q(QQmlComponent); | - | ||||||||||||||||||
331 | - | |||||||||||||||||||
332 | progress = p; | - | ||||||||||||||||||
333 | - | |||||||||||||||||||
334 | emit q->progressChanged(p); | - | ||||||||||||||||||
335 | } executed 117 times by 11 tests: end of block Executed by:
| 117 | ||||||||||||||||||
336 | - | |||||||||||||||||||
337 | void QQmlComponentPrivate::fromTypeData(const QQmlRefPointer<QQmlTypeData> &data) | - | ||||||||||||||||||
338 | { | - | ||||||||||||||||||
339 | url = data->finalUrl(); | - | ||||||||||||||||||
340 | compilationUnit = data->compilationUnit(); | - | ||||||||||||||||||
341 | - | |||||||||||||||||||
342 | if (!compilationUnit) {
| 206-58253 | ||||||||||||||||||
343 | Q_ASSERT(data->isError()); | - | ||||||||||||||||||
344 | state.errors = data->errors(); | - | ||||||||||||||||||
345 | } executed 206 times by 21 tests: end of block Executed by:
| 206 | ||||||||||||||||||
346 | } executed 58459 times by 141 tests: end of block Executed by:
| 58459 | ||||||||||||||||||
347 | - | |||||||||||||||||||
348 | void QQmlComponentPrivate::clear() | - | ||||||||||||||||||
349 | { | - | ||||||||||||||||||
350 | if (typeData) {
| 0-58378 | ||||||||||||||||||
351 | typeData->unregisterCallback(this); | - | ||||||||||||||||||
352 | typeData = nullptr; | - | ||||||||||||||||||
353 | } never executed: end of block | 0 | ||||||||||||||||||
354 | - | |||||||||||||||||||
355 | compilationUnit = nullptr; | - | ||||||||||||||||||
356 | } executed 58378 times by 141 tests: end of block Executed by:
| 58378 | ||||||||||||||||||
357 | - | |||||||||||||||||||
358 | /*! | - | ||||||||||||||||||
359 | \internal | - | ||||||||||||||||||
360 | */ | - | ||||||||||||||||||
361 | QQmlComponent::QQmlComponent(QObject *parent) | - | ||||||||||||||||||
362 | : QObject(*(new QQmlComponentPrivate), parent) | - | ||||||||||||||||||
363 | { | - | ||||||||||||||||||
364 | } executed 12 times by 2 tests: end of block Executed by:
| 12 | ||||||||||||||||||
365 | - | |||||||||||||||||||
366 | /*! | - | ||||||||||||||||||
367 | Destruct the QQmlComponent. | - | ||||||||||||||||||
368 | */ | - | ||||||||||||||||||
369 | QQmlComponent::~QQmlComponent() | - | ||||||||||||||||||
370 | { | - | ||||||||||||||||||
371 | Q_D(QQmlComponent); | - | ||||||||||||||||||
372 | - | |||||||||||||||||||
373 | if (d->state.completePending) {
| 2-68621 | ||||||||||||||||||
374 | qWarning("QQmlComponent: Component destroyed while completion pending"); | - | ||||||||||||||||||
375 | - | |||||||||||||||||||
376 | if (isError()) {
| 0-2 | ||||||||||||||||||
377 | qWarning() << "This may have been caused by one of the following errors:"; | - | ||||||||||||||||||
378 | for (const QQmlError &error : qAsConst(d->state.errors)) | - | ||||||||||||||||||
379 | qWarning().nospace().noquote() << QLatin1String(" ") << error; executed 2 times by 1 test: QMessageLogger(__FILE__, 379, __PRETTY_FUNCTION__).warning().nospace().noquote() << QLatin1String(" ") << error; Executed by:
| 2 | ||||||||||||||||||
380 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
381 | - | |||||||||||||||||||
382 | d->completeCreate(); | - | ||||||||||||||||||
383 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
384 | - | |||||||||||||||||||
385 | if (d->typeData) {
| 12-68611 | ||||||||||||||||||
386 | d->typeData->unregisterCallback(d); | - | ||||||||||||||||||
387 | d->typeData = nullptr; | - | ||||||||||||||||||
388 | } executed 12 times by 3 tests: end of block Executed by:
| 12 | ||||||||||||||||||
389 | } executed 68623 times by 141 tests: end of block Executed by:
| 68623 | ||||||||||||||||||
390 | - | |||||||||||||||||||
391 | /*! | - | ||||||||||||||||||
392 | \qmlproperty enumeration Component::status | - | ||||||||||||||||||
393 | This property holds the status of component loading. The status can be one of the | - | ||||||||||||||||||
394 | following: | - | ||||||||||||||||||
395 | \list | - | ||||||||||||||||||
396 | \li Component.Null - no data is available for the component | - | ||||||||||||||||||
397 | \li Component.Ready - the component has been loaded, and can be used to create instances. | - | ||||||||||||||||||
398 | \li Component.Loading - the component is currently being loaded | - | ||||||||||||||||||
399 | \li Component.Error - an error occurred while loading the component. | - | ||||||||||||||||||
400 | Calling errorString() will provide a human-readable description of any errors. | - | ||||||||||||||||||
401 | \endlist | - | ||||||||||||||||||
402 | */ | - | ||||||||||||||||||
403 | - | |||||||||||||||||||
404 | /*! | - | ||||||||||||||||||
405 | \property QQmlComponent::status | - | ||||||||||||||||||
406 | The component's current \l{QQmlComponent::Status} {status}. | - | ||||||||||||||||||
407 | */ | - | ||||||||||||||||||
408 | QQmlComponent::Status QQmlComponent::status() const | - | ||||||||||||||||||
409 | { | - | ||||||||||||||||||
410 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
411 | - | |||||||||||||||||||
412 | if (d->typeData)
| 716-159466 | ||||||||||||||||||
413 | return Loading; executed 716 times by 13 tests: return Loading; Executed by:
| 716 | ||||||||||||||||||
414 | else if (!d->state.errors.isEmpty())
| 712-158754 | ||||||||||||||||||
415 | return Error; executed 712 times by 21 tests: return Error; Executed by:
| 712 | ||||||||||||||||||
416 | else if (d->engine && d->compilationUnit)
| 2-158752 | ||||||||||||||||||
417 | return Ready; executed 158746 times by 141 tests: return Ready; Executed by:
| 158746 | ||||||||||||||||||
418 | else | - | ||||||||||||||||||
419 | return Null; executed 8 times by 2 tests: return Null; Executed by:
| 8 | ||||||||||||||||||
420 | } | - | ||||||||||||||||||
421 | - | |||||||||||||||||||
422 | /*! | - | ||||||||||||||||||
423 | Returns true if status() == QQmlComponent::Null. | - | ||||||||||||||||||
424 | */ | - | ||||||||||||||||||
425 | bool QQmlComponent::isNull() const | - | ||||||||||||||||||
426 | { | - | ||||||||||||||||||
427 | return status() == Null; executed 4 times by 1 test: return status() == Null; Executed by:
| 4 | ||||||||||||||||||
428 | } | - | ||||||||||||||||||
429 | - | |||||||||||||||||||
430 | /*! | - | ||||||||||||||||||
431 | Returns true if status() == QQmlComponent::Ready. | - | ||||||||||||||||||
432 | */ | - | ||||||||||||||||||
433 | bool QQmlComponent::isReady() const | - | ||||||||||||||||||
434 | { | - | ||||||||||||||||||
435 | return status() == Ready; executed 63598 times by 140 tests: return status() == Ready; Executed by:
| 63598 | ||||||||||||||||||
436 | } | - | ||||||||||||||||||
437 | - | |||||||||||||||||||
438 | /*! | - | ||||||||||||||||||
439 | Returns true if status() == QQmlComponent::Error. | - | ||||||||||||||||||
440 | */ | - | ||||||||||||||||||
441 | bool QQmlComponent::isError() const | - | ||||||||||||||||||
442 | { | - | ||||||||||||||||||
443 | return status() == Error; executed 15112 times by 111 tests: return status() == Error; Executed by:
| 15112 | ||||||||||||||||||
444 | } | - | ||||||||||||||||||
445 | - | |||||||||||||||||||
446 | /*! | - | ||||||||||||||||||
447 | Returns true if status() == QQmlComponent::Loading. | - | ||||||||||||||||||
448 | */ | - | ||||||||||||||||||
449 | bool QQmlComponent::isLoading() const | - | ||||||||||||||||||
450 | { | - | ||||||||||||||||||
451 | return status() == Loading; executed 6256 times by 90 tests: return status() == Loading; Executed by:
| 6256 | ||||||||||||||||||
452 | } | - | ||||||||||||||||||
453 | - | |||||||||||||||||||
454 | /*! | - | ||||||||||||||||||
455 | \qmlproperty real Component::progress | - | ||||||||||||||||||
456 | The progress of loading the component, from 0.0 (nothing loaded) | - | ||||||||||||||||||
457 | to 1.0 (finished). | - | ||||||||||||||||||
458 | */ | - | ||||||||||||||||||
459 | - | |||||||||||||||||||
460 | /*! | - | ||||||||||||||||||
461 | \property QQmlComponent::progress | - | ||||||||||||||||||
462 | The progress of loading the component, from 0.0 (nothing loaded) | - | ||||||||||||||||||
463 | to 1.0 (finished). | - | ||||||||||||||||||
464 | */ | - | ||||||||||||||||||
465 | qreal QQmlComponent::progress() const | - | ||||||||||||||||||
466 | { | - | ||||||||||||||||||
467 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
468 | return d->progress; executed 24 times by 1 test: return d->progress; Executed by:
| 24 | ||||||||||||||||||
469 | } | - | ||||||||||||||||||
470 | - | |||||||||||||||||||
471 | /*! | - | ||||||||||||||||||
472 | \fn void QQmlComponent::progressChanged(qreal progress) | - | ||||||||||||||||||
473 | - | |||||||||||||||||||
474 | Emitted whenever the component's loading progress changes. \a progress will be the | - | ||||||||||||||||||
475 | current progress between 0.0 (nothing loaded) and 1.0 (finished). | - | ||||||||||||||||||
476 | */ | - | ||||||||||||||||||
477 | - | |||||||||||||||||||
478 | /*! | - | ||||||||||||||||||
479 | \fn void QQmlComponent::statusChanged(QQmlComponent::Status status) | - | ||||||||||||||||||
480 | - | |||||||||||||||||||
481 | Emitted whenever the component's status changes. \a status will be the | - | ||||||||||||||||||
482 | new status. | - | ||||||||||||||||||
483 | */ | - | ||||||||||||||||||
484 | - | |||||||||||||||||||
485 | /*! | - | ||||||||||||||||||
486 | Create a QQmlComponent with no data and give it the specified | - | ||||||||||||||||||
487 | \a engine and \a parent. Set the data with setData(). | - | ||||||||||||||||||
488 | */ | - | ||||||||||||||||||
489 | QQmlComponent::QQmlComponent(QQmlEngine *engine, QObject *parent) | - | ||||||||||||||||||
490 | : QObject(*(new QQmlComponentPrivate), parent) | - | ||||||||||||||||||
491 | { | - | ||||||||||||||||||
492 | Q_D(QQmlComponent); | - | ||||||||||||||||||
493 | d->engine = engine; | - | ||||||||||||||||||
494 | } executed 68723 times by 141 tests: end of block Executed by:
| 68723 | ||||||||||||||||||
495 | - | |||||||||||||||||||
496 | /*! | - | ||||||||||||||||||
497 | Create a QQmlComponent from the given \a url and give it the | - | ||||||||||||||||||
498 | specified \a parent and \a engine. | - | ||||||||||||||||||
499 | - | |||||||||||||||||||
500 | \include qqmlcomponent.qdoc url-note | - | ||||||||||||||||||
501 | - | |||||||||||||||||||
502 | \sa loadUrl() | - | ||||||||||||||||||
503 | */ | - | ||||||||||||||||||
504 | QQmlComponent::QQmlComponent(QQmlEngine *engine, const QUrl &url, QObject *parent) | - | ||||||||||||||||||
505 | : QQmlComponent(engine, url, QQmlComponent::PreferSynchronous, parent) | - | ||||||||||||||||||
506 | { | - | ||||||||||||||||||
507 | } executed 11224 times by 121 tests: end of block Executed by:
| 11224 | ||||||||||||||||||
508 | - | |||||||||||||||||||
509 | /*! | - | ||||||||||||||||||
510 | Create a QQmlComponent from the given \a url and give it the | - | ||||||||||||||||||
511 | specified \a parent and \a engine. If \a mode is \l Asynchronous, | - | ||||||||||||||||||
512 | the component will be loaded and compiled asynchronously. | - | ||||||||||||||||||
513 | - | |||||||||||||||||||
514 | \include qqmlcomponent.qdoc url-note | - | ||||||||||||||||||
515 | - | |||||||||||||||||||
516 | \sa loadUrl() | - | ||||||||||||||||||
517 | */ | - | ||||||||||||||||||
518 | QQmlComponent::QQmlComponent(QQmlEngine *engine, const QUrl &url, CompilationMode mode, | - | ||||||||||||||||||
519 | QObject *parent) | - | ||||||||||||||||||
520 | : QQmlComponent(engine, parent) | - | ||||||||||||||||||
521 | { | - | ||||||||||||||||||
522 | Q_D(QQmlComponent); | - | ||||||||||||||||||
523 | d->loadUrl(url, mode); | - | ||||||||||||||||||
524 | } executed 11822 times by 123 tests: end of block Executed by:
| 11822 | ||||||||||||||||||
525 | - | |||||||||||||||||||
526 | /*! | - | ||||||||||||||||||
527 | Create a QQmlComponent from the given \a fileName and give it the specified | - | ||||||||||||||||||
528 | \a parent and \a engine. | - | ||||||||||||||||||
529 | - | |||||||||||||||||||
530 | \sa loadUrl() | - | ||||||||||||||||||
531 | */ | - | ||||||||||||||||||
532 | QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName, | - | ||||||||||||||||||
533 | QObject *parent) | - | ||||||||||||||||||
534 | : QQmlComponent(engine, fileName, QQmlComponent::PreferSynchronous, parent) | - | ||||||||||||||||||
535 | { | - | ||||||||||||||||||
536 | } executed 70 times by 8 tests: end of block Executed by:
| 70 | ||||||||||||||||||
537 | - | |||||||||||||||||||
538 | /*! | - | ||||||||||||||||||
539 | Create a QQmlComponent from the given \a fileName and give it the specified | - | ||||||||||||||||||
540 | \a parent and \a engine. If \a mode is \l Asynchronous, | - | ||||||||||||||||||
541 | the component will be loaded and compiled asynchronously. | - | ||||||||||||||||||
542 | - | |||||||||||||||||||
543 | \sa loadUrl() | - | ||||||||||||||||||
544 | */ | - | ||||||||||||||||||
545 | QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName, | - | ||||||||||||||||||
546 | CompilationMode mode, QObject *parent) | - | ||||||||||||||||||
547 | : QQmlComponent(engine, parent) | - | ||||||||||||||||||
548 | { | - | ||||||||||||||||||
549 | Q_D(QQmlComponent); | - | ||||||||||||||||||
550 | const QUrl url = QDir::isAbsolutePath(fileName) ? QUrl::fromLocalFile(fileName) : QUrl(fileName);
| 0-100 | ||||||||||||||||||
551 | d->loadUrl(url, mode); | - | ||||||||||||||||||
552 | } executed 100 times by 8 tests: end of block Executed by:
| 100 | ||||||||||||||||||
553 | - | |||||||||||||||||||
554 | /*! | - | ||||||||||||||||||
555 | \internal | - | ||||||||||||||||||
556 | */ | - | ||||||||||||||||||
557 | QQmlComponent::QQmlComponent(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *compilationUnit, int start, QObject *parent) | - | ||||||||||||||||||
558 | : QQmlComponent(engine, parent) | - | ||||||||||||||||||
559 | { | - | ||||||||||||||||||
560 | Q_D(QQmlComponent); | - | ||||||||||||||||||
561 | d->compilationUnit = compilationUnit; | - | ||||||||||||||||||
562 | d->start = start; | - | ||||||||||||||||||
563 | d->url = compilationUnit->finalUrl(); | - | ||||||||||||||||||
564 | d->progress = 1.0; | - | ||||||||||||||||||
565 | } executed 10280 times by 39 tests: end of block Executed by:
| 10280 | ||||||||||||||||||
566 | - | |||||||||||||||||||
567 | /*! | - | ||||||||||||||||||
568 | Sets the QQmlComponent to use the given QML \a data. If \a url | - | ||||||||||||||||||
569 | is provided, it is used to set the component name and to provide | - | ||||||||||||||||||
570 | a base path for items resolved by this component. | - | ||||||||||||||||||
571 | */ | - | ||||||||||||||||||
572 | void QQmlComponent::setData(const QByteArray &data, const QUrl &url) | - | ||||||||||||||||||
573 | { | - | ||||||||||||||||||
574 | Q_D(QQmlComponent); | - | ||||||||||||||||||
575 | - | |||||||||||||||||||
576 | d->clear(); | - | ||||||||||||||||||
577 | - | |||||||||||||||||||
578 | d->url = url; | - | ||||||||||||||||||
579 | - | |||||||||||||||||||
580 | QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(d->engine)->typeLoader.getType(data, url); | - | ||||||||||||||||||
581 | - | |||||||||||||||||||
582 | if (typeData->isCompleteOrError()) {
| 6-45668 | ||||||||||||||||||
583 | d->fromTypeData(typeData); | - | ||||||||||||||||||
584 | } else { executed 45668 times by 51 tests: end of block Executed by:
| 45668 | ||||||||||||||||||
585 | d->typeData = typeData; | - | ||||||||||||||||||
586 | d->typeData->registerCallback(d); | - | ||||||||||||||||||
587 | } executed 6 times by 2 tests: end of block Executed by:
| 6 | ||||||||||||||||||
588 | - | |||||||||||||||||||
589 | d->progress = 1.0; | - | ||||||||||||||||||
590 | emit statusChanged(status()); | - | ||||||||||||||||||
591 | emit progressChanged(d->progress); | - | ||||||||||||||||||
592 | } executed 45674 times by 51 tests: end of block Executed by:
| 45674 | ||||||||||||||||||
593 | - | |||||||||||||||||||
594 | /*! | - | ||||||||||||||||||
595 | Returns the QQmlContext the component was created in. This is only | - | ||||||||||||||||||
596 | valid for components created directly from QML. | - | ||||||||||||||||||
597 | */ | - | ||||||||||||||||||
598 | QQmlContext *QQmlComponent::creationContext() const | - | ||||||||||||||||||
599 | { | - | ||||||||||||||||||
600 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
601 | if(d->creationContext)
| 216-93209 | ||||||||||||||||||
602 | return d->creationContext->asQQmlContext(); executed 93209 times by 38 tests: return d->creationContext->asQQmlContext(); Executed by:
| 93209 | ||||||||||||||||||
603 | - | |||||||||||||||||||
604 | return qmlContext(this); executed 216 times by 14 tests: return qmlContext(this); Executed by:
| 216 | ||||||||||||||||||
605 | } | - | ||||||||||||||||||
606 | - | |||||||||||||||||||
607 | /*! | - | ||||||||||||||||||
608 | Load the QQmlComponent from the provided \a url. | - | ||||||||||||||||||
609 | - | |||||||||||||||||||
610 | \include qqmlcomponent.qdoc url-note | - | ||||||||||||||||||
611 | */ | - | ||||||||||||||||||
612 | void QQmlComponent::loadUrl(const QUrl &url) | - | ||||||||||||||||||
613 | { | - | ||||||||||||||||||
614 | Q_D(QQmlComponent); | - | ||||||||||||||||||
615 | d->loadUrl(url); | - | ||||||||||||||||||
616 | } executed 772 times by 10 tests: end of block Executed by:
| 772 | ||||||||||||||||||
617 | - | |||||||||||||||||||
618 | /*! | - | ||||||||||||||||||
619 | Load the QQmlComponent from the provided \a url. | - | ||||||||||||||||||
620 | If \a mode is \l Asynchronous, the component will be loaded and compiled asynchronously. | - | ||||||||||||||||||
621 | - | |||||||||||||||||||
622 | \include qqmlcomponent.qdoc url-note | - | ||||||||||||||||||
623 | */ | - | ||||||||||||||||||
624 | void QQmlComponent::loadUrl(const QUrl &url, QQmlComponent::CompilationMode mode) | - | ||||||||||||||||||
625 | { | - | ||||||||||||||||||
626 | Q_D(QQmlComponent); | - | ||||||||||||||||||
627 | d->loadUrl(url, mode); | - | ||||||||||||||||||
628 | } executed 10 times by 2 tests: end of block Executed by:
| 10 | ||||||||||||||||||
629 | - | |||||||||||||||||||
630 | void QQmlComponentPrivate::loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode) | - | ||||||||||||||||||
631 | { | - | ||||||||||||||||||
632 | Q_Q(QQmlComponent); | - | ||||||||||||||||||
633 | clear(); | - | ||||||||||||||||||
634 | - | |||||||||||||||||||
635 | if (newUrl.isRelative()) {
| 6-12698 | ||||||||||||||||||
636 | // The new URL is a relative URL like QUrl("main.qml"). | - | ||||||||||||||||||
637 | url = engine->baseUrl().resolved(QUrl(newUrl.toString())); | - | ||||||||||||||||||
638 | } else if (engine->baseUrl().isLocalFile() && newUrl.isLocalFile() && !QDir::isAbsolutePath(newUrl.toLocalFile())) { executed 6 times by 2 tests: end of block Executed by:
| 0-12698 | ||||||||||||||||||
639 | // The new URL is a file on disk but it's a relative path; e.g.: | - | ||||||||||||||||||
640 | // QUrl::fromLocalFile("main.qml") or QUrl("file:main.qml") | - | ||||||||||||||||||
641 | // We need to remove the scheme so that it becomes a relative URL with a relative path: | - | ||||||||||||||||||
642 | QUrl fixedUrl(newUrl); | - | ||||||||||||||||||
643 | fixedUrl.setScheme(QString()); | - | ||||||||||||||||||
644 | // Then, turn it into an absolute URL with an absolute path by resolving it against the engine's baseUrl(). | - | ||||||||||||||||||
645 | // This is a compatibility hack for QTBUG-58837. | - | ||||||||||||||||||
646 | url = engine->baseUrl().resolved(fixedUrl); | - | ||||||||||||||||||
647 | } else { executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||
648 | url = newUrl; | - | ||||||||||||||||||
649 | } executed 12694 times by 125 tests: end of block Executed by:
| 12694 | ||||||||||||||||||
650 | - | |||||||||||||||||||
651 | if (newUrl.isEmpty()) {
| 2-12702 | ||||||||||||||||||
652 | QQmlError error; | - | ||||||||||||||||||
653 | error.setDescription(QQmlComponent::tr("Invalid empty URL")); | - | ||||||||||||||||||
654 | state.errors << error; | - | ||||||||||||||||||
655 | return; executed 2 times by 1 test: return; Executed by:
| 2 | ||||||||||||||||||
656 | } | - | ||||||||||||||||||
657 | - | |||||||||||||||||||
658 | if (progress != 0.0) {
| 0-12702 | ||||||||||||||||||
659 | progress = 0.0; | - | ||||||||||||||||||
660 | emit q->progressChanged(progress); | - | ||||||||||||||||||
661 | } never executed: end of block | 0 | ||||||||||||||||||
662 | - | |||||||||||||||||||
663 | QQmlTypeLoader::Mode loaderMode = (mode == QQmlComponent::Asynchronous)
| 124-12578 | ||||||||||||||||||
664 | ? QQmlTypeLoader::Asynchronous | - | ||||||||||||||||||
665 | : QQmlTypeLoader::PreferSynchronous; | - | ||||||||||||||||||
666 | - | |||||||||||||||||||
667 | QQmlRefPointer<QQmlTypeData> data = QQmlEnginePrivate::get(engine)->typeLoader.getType(url, loaderMode); | - | ||||||||||||||||||
668 | - | |||||||||||||||||||
669 | if (data->isCompleteOrError()) {
| 140-12562 | ||||||||||||||||||
670 | fromTypeData(data); | - | ||||||||||||||||||
671 | progress = 1.0; | - | ||||||||||||||||||
672 | } else { executed 12562 times by 126 tests: end of block Executed by:
| 12562 | ||||||||||||||||||
673 | typeData = data; | - | ||||||||||||||||||
674 | typeData->registerCallback(this); | - | ||||||||||||||||||
675 | progress = data->progress(); | - | ||||||||||||||||||
676 | } executed 140 times by 12 tests: end of block Executed by:
| 140 | ||||||||||||||||||
677 | - | |||||||||||||||||||
678 | emit q->statusChanged(q->status()); | - | ||||||||||||||||||
679 | if (progress != 0.0)
| 137-12565 | ||||||||||||||||||
680 | emit q->progressChanged(progress); executed 12565 times by 126 tests: q->progressChanged(progress); Executed by:
| 12565 | ||||||||||||||||||
681 | } executed 12702 times by 126 tests: end of block Executed by:
| 12702 | ||||||||||||||||||
682 | - | |||||||||||||||||||
683 | /*! | - | ||||||||||||||||||
684 | Returns the list of errors that occurred during the last compile or create | - | ||||||||||||||||||
685 | operation. An empty list is returned if isError() is not set. | - | ||||||||||||||||||
686 | */ | - | ||||||||||||||||||
687 | QList<QQmlError> QQmlComponent::errors() const | - | ||||||||||||||||||
688 | { | - | ||||||||||||||||||
689 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
690 | if (isError())
| 226-446 | ||||||||||||||||||
691 | return d->state.errors; executed 226 times by 18 tests: return d->state.errors; Executed by:
| 226 | ||||||||||||||||||
692 | else | - | ||||||||||||||||||
693 | return QList<QQmlError>(); executed 446 times by 25 tests: return QList<QQmlError>(); Executed by:
| 446 | ||||||||||||||||||
694 | } | - | ||||||||||||||||||
695 | - | |||||||||||||||||||
696 | /*! | - | ||||||||||||||||||
697 | \qmlmethod string Component::errorString() | - | ||||||||||||||||||
698 | - | |||||||||||||||||||
699 | Returns a human-readable description of any error. | - | ||||||||||||||||||
700 | - | |||||||||||||||||||
701 | The string includes the file, location, and description of each error. | - | ||||||||||||||||||
702 | If multiple errors are present, they are separated by a newline character. | - | ||||||||||||||||||
703 | - | |||||||||||||||||||
704 | If no errors are present, an empty string is returned. | - | ||||||||||||||||||
705 | */ | - | ||||||||||||||||||
706 | - | |||||||||||||||||||
707 | /*! | - | ||||||||||||||||||
708 | \internal | - | ||||||||||||||||||
709 | errorString is only meant as a way to get the errors in script | - | ||||||||||||||||||
710 | */ | - | ||||||||||||||||||
711 | QString QQmlComponent::errorString() const | - | ||||||||||||||||||
712 | { | - | ||||||||||||||||||
713 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
714 | QString ret; | - | ||||||||||||||||||
715 | if(!isError())
| 16-428 | ||||||||||||||||||
716 | return ret; executed 428 times by 9 tests: return ret; Executed by:
| 428 | ||||||||||||||||||
717 | for (const QQmlError &e : d->state.errors) { | - | ||||||||||||||||||
718 | ret += e.url().toString() + QLatin1Char(':') + | - | ||||||||||||||||||
719 | QString::number(e.line()) + QLatin1Char(' ') + | - | ||||||||||||||||||
720 | e.description() + QLatin1Char('\n'); | - | ||||||||||||||||||
721 | } executed 18 times by 5 tests: end of block Executed by:
| 18 | ||||||||||||||||||
722 | return ret; executed 16 times by 5 tests: return ret; Executed by:
| 16 | ||||||||||||||||||
723 | } | - | ||||||||||||||||||
724 | - | |||||||||||||||||||
725 | /*! | - | ||||||||||||||||||
726 | \qmlproperty url Component::url | - | ||||||||||||||||||
727 | The component URL. This is the URL that was used to construct the component. | - | ||||||||||||||||||
728 | */ | - | ||||||||||||||||||
729 | - | |||||||||||||||||||
730 | /*! | - | ||||||||||||||||||
731 | \property QQmlComponent::url | - | ||||||||||||||||||
732 | The component URL. This is the URL passed to either the constructor, | - | ||||||||||||||||||
733 | or the loadUrl(), or setData() methods. | - | ||||||||||||||||||
734 | */ | - | ||||||||||||||||||
735 | QUrl QQmlComponent::url() const | - | ||||||||||||||||||
736 | { | - | ||||||||||||||||||
737 | Q_D(const QQmlComponent); | - | ||||||||||||||||||
738 | return d->url; executed 57642 times by 139 tests: return d->url; Executed by:
| 57642 | ||||||||||||||||||
739 | } | - | ||||||||||||||||||
740 | - | |||||||||||||||||||
741 | /*! | - | ||||||||||||||||||
742 | \internal | - | ||||||||||||||||||
743 | */ | - | ||||||||||||||||||
744 | QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent) | - | ||||||||||||||||||
745 | : QObject(dd, parent) | - | ||||||||||||||||||
746 | { | - | ||||||||||||||||||
747 | } never executed: end of block | 0 | ||||||||||||||||||
748 | - | |||||||||||||||||||
749 | /*! | - | ||||||||||||||||||
750 | Create an object instance from this component. Returns 0 if creation | - | ||||||||||||||||||
751 | failed. \a context specifies the context within which to create the object | - | ||||||||||||||||||
752 | instance. | - | ||||||||||||||||||
753 | - | |||||||||||||||||||
754 | If \a context is 0 (the default), it will create the instance in the | - | ||||||||||||||||||
755 | engine' s \l {QQmlEngine::rootContext()}{root context}. | - | ||||||||||||||||||
756 | - | |||||||||||||||||||
757 | The ownership of the returned object instance is transferred to the caller. | - | ||||||||||||||||||
758 | - | |||||||||||||||||||
759 | If the object being created from this component is a visual item, it must | - | ||||||||||||||||||
760 | have a visual parent, which can be set by calling | - | ||||||||||||||||||
761 | QQuickItem::setParentItem(). See \l {Concepts - Visual Parent in Qt Quick} | - | ||||||||||||||||||
762 | for more details. | - | ||||||||||||||||||
763 | - | |||||||||||||||||||
764 | \sa QQmlEngine::ObjectOwnership | - | ||||||||||||||||||
765 | */ | - | ||||||||||||||||||
766 | QObject *QQmlComponent::create(QQmlContext *context) | - | ||||||||||||||||||
767 | { | - | ||||||||||||||||||
768 | Q_D(QQmlComponent); | - | ||||||||||||||||||
769 | QML_MEMORY_SCOPE_URL(url()); | - | ||||||||||||||||||
770 | - | |||||||||||||||||||
771 | if (!context)
| 14502-42500 | ||||||||||||||||||
772 | context = d->engine->rootContext(); executed 14502 times by 138 tests: context = d->engine->rootContext(); Executed by:
| 14502 | ||||||||||||||||||
773 | - | |||||||||||||||||||
774 | QObject *rv = beginCreate(context); | - | ||||||||||||||||||
775 | if (rv)
| 56-56946 | ||||||||||||||||||
776 | completeCreate(); executed 56946 times by 139 tests: completeCreate(); Executed by:
| 56946 | ||||||||||||||||||
777 | return rv; executed 57002 times by 139 tests: return rv; Executed by:
| 57002 | ||||||||||||||||||
778 | } | - | ||||||||||||||||||
779 | - | |||||||||||||||||||
780 | /*! | - | ||||||||||||||||||
781 | This method provides advanced control over component instance creation. | - | ||||||||||||||||||
782 | In general, programmers should use QQmlComponent::create() to create object | - | ||||||||||||||||||
783 | instances. | - | ||||||||||||||||||
784 | - | |||||||||||||||||||
785 | Create an object instance from this component. Returns 0 if creation | - | ||||||||||||||||||
786 | failed. \a publicContext specifies the context within which to create the object | - | ||||||||||||||||||
787 | instance. | - | ||||||||||||||||||
788 | - | |||||||||||||||||||
789 | When QQmlComponent constructs an instance, it occurs in three steps: | - | ||||||||||||||||||
790 | \list 1 | - | ||||||||||||||||||
791 | \li The object hierarchy is created, and constant values are assigned. | - | ||||||||||||||||||
792 | \li Property bindings are evaluated for the first time. | - | ||||||||||||||||||
793 | \li If applicable, QQmlParserStatus::componentComplete() is called on objects. | - | ||||||||||||||||||
794 | \endlist | - | ||||||||||||||||||
795 | QQmlComponent::beginCreate() differs from QQmlComponent::create() in that it | - | ||||||||||||||||||
796 | only performs step 1. QQmlComponent::completeCreate() must be called to | - | ||||||||||||||||||
797 | complete steps 2 and 3. | - | ||||||||||||||||||
798 | - | |||||||||||||||||||
799 | This breaking point is sometimes useful when using attached properties to | - | ||||||||||||||||||
800 | communicate information to an instantiated component, as it allows their | - | ||||||||||||||||||
801 | initial values to be configured before property bindings take effect. | - | ||||||||||||||||||
802 | - | |||||||||||||||||||
803 | The ownership of the returned object instance is transferred to the caller. | - | ||||||||||||||||||
804 | - | |||||||||||||||||||
805 | \sa completeCreate(), QQmlEngine::ObjectOwnership | - | ||||||||||||||||||
806 | */ | - | ||||||||||||||||||
807 | QObject *QQmlComponent::beginCreate(QQmlContext *publicContext) | - | ||||||||||||||||||
808 | { | - | ||||||||||||||||||
809 | Q_D(QQmlComponent); | - | ||||||||||||||||||
810 | - | |||||||||||||||||||
811 | Q_ASSERT(publicContext); | - | ||||||||||||||||||
812 | QQmlContextData *context = QQmlContextData::get(publicContext); | - | ||||||||||||||||||
813 | - | |||||||||||||||||||
814 | return d->beginCreate(context); executed 62501 times by 139 tests: return d->beginCreate(context); Executed by:
| 62501 | ||||||||||||||||||
815 | } | - | ||||||||||||||||||
816 | - | |||||||||||||||||||
817 | QObject * | - | ||||||||||||||||||
818 | QQmlComponentPrivate::beginCreate(QQmlContextData *context) | - | ||||||||||||||||||
819 | { | - | ||||||||||||||||||
820 | Q_Q(QQmlComponent); | - | ||||||||||||||||||
821 | if (!context) {
| 0-62501 | ||||||||||||||||||
822 | qWarning("QQmlComponent: Cannot create a component in a null context"); | - | ||||||||||||||||||
823 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
824 | } | - | ||||||||||||||||||
825 | - | |||||||||||||||||||
826 | if (!context->isValid()) {
| 0-62501 | ||||||||||||||||||
827 | qWarning("QQmlComponent: Cannot create a component in an invalid context"); | - | ||||||||||||||||||
828 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
829 | } | - | ||||||||||||||||||
830 | - | |||||||||||||||||||
831 | if (context->engine != engine) {
| 0-62501 | ||||||||||||||||||
832 | qWarning("QQmlComponent: Must create component in context from the same QQmlEngine"); | - | ||||||||||||||||||
833 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
834 | } | - | ||||||||||||||||||
835 | - | |||||||||||||||||||
836 | if (state.completePending) {
| 0-62501 | ||||||||||||||||||
837 | qWarning("QQmlComponent: Cannot create new component instance before completing the previous"); | - | ||||||||||||||||||
838 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
839 | } | - | ||||||||||||||||||
840 | - | |||||||||||||||||||
841 | if (!q->isReady()) {
| 58-62443 | ||||||||||||||||||
842 | qWarning("QQmlComponent: Component is not ready"); | - | ||||||||||||||||||
843 | return nullptr; executed 58 times by 7 tests: return nullptr; Executed by:
| 58 | ||||||||||||||||||
844 | } | - | ||||||||||||||||||
845 | - | |||||||||||||||||||
846 | // Do not create infinite recursion in object creation | - | ||||||||||||||||||
847 | static const int maxCreationDepth = 10; | - | ||||||||||||||||||
848 | if (creationDepth.localData() >= maxCreationDepth) {
| 22-62421 | ||||||||||||||||||
849 | qWarning("QQmlComponent: Component creation is recursing - aborting"); | - | ||||||||||||||||||
850 | return nullptr; executed 22 times by 1 test: return nullptr; Executed by:
| 22 | ||||||||||||||||||
851 | } | - | ||||||||||||||||||
852 | - | |||||||||||||||||||
853 | QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); | - | ||||||||||||||||||
854 | - | |||||||||||||||||||
855 | enginePriv->inProgressCreations++; | - | ||||||||||||||||||
856 | state.errors.clear(); | - | ||||||||||||||||||
857 | state.completePending = true; | - | ||||||||||||||||||
858 | - | |||||||||||||||||||
859 | enginePriv->referenceScarceResources(); | - | ||||||||||||||||||
860 | QObject *rv = nullptr; | - | ||||||||||||||||||
861 | state.creator.reset(new QQmlObjectCreator(context, compilationUnit, creationContext)); | - | ||||||||||||||||||
862 | rv = state.creator->create(start); | - | ||||||||||||||||||
863 | if (!rv)
| 4-62417 | ||||||||||||||||||
864 | state.errors = state.creator->errors; executed 4 times by 2 tests: state.errors = state.creator->errors; Executed by:
| 4 | ||||||||||||||||||
865 | enginePriv->dereferenceScarceResources(); | - | ||||||||||||||||||
866 | - | |||||||||||||||||||
867 | if (rv) {
| 4-62417 | ||||||||||||||||||
868 | QQmlData *ddata = QQmlData::get(rv); | - | ||||||||||||||||||
869 | Q_ASSERT(ddata); | - | ||||||||||||||||||
870 | //top level objects should never get JS ownership. | - | ||||||||||||||||||
871 | //if JS ownership is needed this needs to be explicitly undone (like in component.createObject()) | - | ||||||||||||||||||
872 | ddata->indestructible = true; | - | ||||||||||||||||||
873 | ddata->explicitIndestructibleSet = true; | - | ||||||||||||||||||
874 | ddata->rootObjectInCreation = false; | - | ||||||||||||||||||
875 | } executed 62417 times by 139 tests: end of block Executed by:
| 62417 | ||||||||||||||||||
876 | - | |||||||||||||||||||
877 | return rv; executed 62421 times by 139 tests: return rv; Executed by:
| 62421 | ||||||||||||||||||
878 | } | - | ||||||||||||||||||
879 | - | |||||||||||||||||||
880 | void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv, | - | ||||||||||||||||||
881 | QObject *object, DeferredState *deferredState) | - | ||||||||||||||||||
882 | { | - | ||||||||||||||||||
883 | QQmlData *ddata = QQmlData::get(object); | - | ||||||||||||||||||
884 | Q_ASSERT(!ddata->deferredData.isEmpty()); | - | ||||||||||||||||||
885 | - | |||||||||||||||||||
886 | deferredState->constructionStates.reserve(ddata->deferredData.size()); | - | ||||||||||||||||||
887 | - | |||||||||||||||||||
888 | for (QQmlData::DeferredData *deferredData : qAsConst(ddata->deferredData)) { | - | ||||||||||||||||||
889 | enginePriv->inProgressCreations++; | - | ||||||||||||||||||
890 | - | |||||||||||||||||||
891 | ConstructionState *state = new ConstructionState; | - | ||||||||||||||||||
892 | state->completePending = true; | - | ||||||||||||||||||
893 | - | |||||||||||||||||||
894 | QQmlContextData *creationContext = nullptr; | - | ||||||||||||||||||
895 | state->creator.reset(new QQmlObjectCreator(deferredData->context->parent, deferredData->compilationUnit, creationContext)); | - | ||||||||||||||||||
896 | - | |||||||||||||||||||
897 | if (!state->creator->populateDeferredProperties(object, deferredData))
| 0-1680 | ||||||||||||||||||
898 | state->errors << state->creator->errors; never executed: state->errors << state->creator->errors; | 0 | ||||||||||||||||||
899 | - | |||||||||||||||||||
900 | deferredState->constructionStates += state; | - | ||||||||||||||||||
901 | } executed 1680 times by 23 tests: end of block Executed by:
| 1680 | ||||||||||||||||||
902 | } executed 1680 times by 23 tests: end of block Executed by:
| 1680 | ||||||||||||||||||
903 | - | |||||||||||||||||||
904 | void QQmlComponentPrivate::completeDeferred(QQmlEnginePrivate *enginePriv, QQmlComponentPrivate::DeferredState *deferredState) | - | ||||||||||||||||||
905 | { | - | ||||||||||||||||||
906 | for (ConstructionState *state : qAsConst(deferredState->constructionStates)) | - | ||||||||||||||||||
907 | complete(enginePriv, state); executed 1680 times by 23 tests: complete(enginePriv, state); Executed by:
| 1680 | ||||||||||||||||||
908 | } executed 1680 times by 23 tests: end of block Executed by:
| 1680 | ||||||||||||||||||
909 | - | |||||||||||||||||||
910 | void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionState *state) | - | ||||||||||||||||||
911 | { | - | ||||||||||||||||||
912 | if (state->completePending) {
| 0-64101 | ||||||||||||||||||
913 | QQmlInstantiationInterrupt interrupt; | - | ||||||||||||||||||
914 | state->creator->finalize(interrupt); | - | ||||||||||||||||||
915 | - | |||||||||||||||||||
916 | state->completePending = false; | - | ||||||||||||||||||
917 | - | |||||||||||||||||||
918 | enginePriv->inProgressCreations--; | - | ||||||||||||||||||
919 | - | |||||||||||||||||||
920 | if (0 == enginePriv->inProgressCreations) {
| 2187-61914 | ||||||||||||||||||
921 | while (enginePriv->erroredBindings) {
| 512-61914 | ||||||||||||||||||
922 | enginePriv->warning(enginePriv->erroredBindings->removeError()); | - | ||||||||||||||||||
923 | } executed 512 times by 13 tests: end of block Executed by:
| 512 | ||||||||||||||||||
924 | } executed 61914 times by 139 tests: end of block Executed by:
| 61914 | ||||||||||||||||||
925 | } executed 64101 times by 139 tests: end of block Executed by:
| 64101 | ||||||||||||||||||
926 | } executed 64101 times by 139 tests: end of block Executed by:
| 64101 | ||||||||||||||||||
927 | - | |||||||||||||||||||
928 | /*! | - | ||||||||||||||||||
929 | This method provides advanced control over component instance creation. | - | ||||||||||||||||||
930 | In general, programmers should use QQmlComponent::create() to create a | - | ||||||||||||||||||
931 | component. | - | ||||||||||||||||||
932 | - | |||||||||||||||||||
933 | This function completes the component creation begun with QQmlComponent::beginCreate() | - | ||||||||||||||||||
934 | and must be called afterwards. | - | ||||||||||||||||||
935 | - | |||||||||||||||||||
936 | \sa beginCreate() | - | ||||||||||||||||||
937 | */ | - | ||||||||||||||||||
938 | void QQmlComponent::completeCreate() | - | ||||||||||||||||||
939 | { | - | ||||||||||||||||||
940 | Q_D(QQmlComponent); | - | ||||||||||||||||||
941 | - | |||||||||||||||||||
942 | d->completeCreate(); | - | ||||||||||||||||||
943 | } executed 59623 times by 139 tests: end of block Executed by:
| 59623 | ||||||||||||||||||
944 | - | |||||||||||||||||||
945 | void QQmlComponentPrivate::completeCreate() | - | ||||||||||||||||||
946 | { | - | ||||||||||||||||||
947 | if (state.completePending) {
| 0-62421 | ||||||||||||||||||
948 | ++creationDepth.localData(); | - | ||||||||||||||||||
949 | QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); | - | ||||||||||||||||||
950 | complete(ep, &state); | - | ||||||||||||||||||
951 | --creationDepth.localData(); | - | ||||||||||||||||||
952 | } executed 62421 times by 139 tests: end of block Executed by:
| 62421 | ||||||||||||||||||
953 | } executed 62421 times by 139 tests: end of block Executed by:
| 62421 | ||||||||||||||||||
954 | - | |||||||||||||||||||
955 | QQmlComponentAttached::QQmlComponentAttached(QObject *parent) | - | ||||||||||||||||||
956 | : QObject(parent), prev(nullptr), next(nullptr) | - | ||||||||||||||||||
957 | { | - | ||||||||||||||||||
958 | } executed 4459 times by 59 tests: end of block Executed by:
| 4459 | ||||||||||||||||||
959 | - | |||||||||||||||||||
960 | QQmlComponentAttached::~QQmlComponentAttached() | - | ||||||||||||||||||
961 | { | - | ||||||||||||||||||
962 | if (prev) *prev = next; executed 2 times by 1 test: *prev = next; Executed by:
| 2-4107 | ||||||||||||||||||
963 | if (next) next->prev = prev; never executed: next->prev = prev;
| 0-4109 | ||||||||||||||||||
964 | prev = nullptr; | - | ||||||||||||||||||
965 | next = nullptr; | - | ||||||||||||||||||
966 | } executed 4109 times by 55 tests: end of block Executed by:
| 4109 | ||||||||||||||||||
967 | - | |||||||||||||||||||
968 | /*! | - | ||||||||||||||||||
969 | \internal | - | ||||||||||||||||||
970 | */ | - | ||||||||||||||||||
971 | QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj) | - | ||||||||||||||||||
972 | { | - | ||||||||||||||||||
973 | QQmlComponentAttached *a = new QQmlComponentAttached(obj); | - | ||||||||||||||||||
974 | - | |||||||||||||||||||
975 | QQmlEngine *engine = qmlEngine(obj); | - | ||||||||||||||||||
976 | if (!engine)
| 0-4459 | ||||||||||||||||||
977 | return a; never executed: return a; | 0 | ||||||||||||||||||
978 | - | |||||||||||||||||||
979 | QQmlEnginePrivate *p = QQmlEnginePrivate::get(engine); | - | ||||||||||||||||||
980 | if (p->activeObjectCreator) { // XXX should only be allowed during begin
| 2-4457 | ||||||||||||||||||
981 | a->add(p->activeObjectCreator->componentAttachment()); | - | ||||||||||||||||||
982 | } else { executed 4457 times by 59 tests: end of block Executed by:
| 4457 | ||||||||||||||||||
983 | QQmlData *d = QQmlData::get(obj); | - | ||||||||||||||||||
984 | Q_ASSERT(d); | - | ||||||||||||||||||
985 | Q_ASSERT(d->context); | - | ||||||||||||||||||
986 | a->add(&d->context->componentAttached); | - | ||||||||||||||||||
987 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
988 | - | |||||||||||||||||||
989 | return a; executed 4459 times by 59 tests: return a; Executed by:
| 4459 | ||||||||||||||||||
990 | } | - | ||||||||||||||||||
991 | - | |||||||||||||||||||
992 | /*! | - | ||||||||||||||||||
993 | Create an object instance from this component using the provided | - | ||||||||||||||||||
994 | \a incubator. \a context specifies the context within which to create the object | - | ||||||||||||||||||
995 | instance. | - | ||||||||||||||||||
996 | - | |||||||||||||||||||
997 | If \a context is 0 (the default), it will create the instance in the | - | ||||||||||||||||||
998 | engine's \l {QQmlEngine::rootContext()}{root context}. | - | ||||||||||||||||||
999 | - | |||||||||||||||||||
1000 | \a forContext specifies a context that this object creation depends upon. | - | ||||||||||||||||||
1001 | If the \a forContext is being created asynchronously, and the | - | ||||||||||||||||||
1002 | \l QQmlIncubator::IncubationMode is \l QQmlIncubator::AsynchronousIfNested, | - | ||||||||||||||||||
1003 | this object will also be created asynchronously. If \a forContext is 0 | - | ||||||||||||||||||
1004 | (the default), the \a context will be used for this decision. | - | ||||||||||||||||||
1005 | - | |||||||||||||||||||
1006 | The created object and its creation status are available via the | - | ||||||||||||||||||
1007 | \a incubator. | - | ||||||||||||||||||
1008 | - | |||||||||||||||||||
1009 | \sa QQmlIncubator | - | ||||||||||||||||||
1010 | */ | - | ||||||||||||||||||
1011 | - | |||||||||||||||||||
1012 | void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, | - | ||||||||||||||||||
1013 | QQmlContext *forContext) | - | ||||||||||||||||||
1014 | { | - | ||||||||||||||||||
1015 | Q_D(QQmlComponent); | - | ||||||||||||||||||
1016 | - | |||||||||||||||||||
1017 | if (!context)
| 90-314 | ||||||||||||||||||
1018 | context = d->engine->rootContext(); executed 90 times by 4 tests: context = d->engine->rootContext(); Executed by:
| 90 | ||||||||||||||||||
1019 | - | |||||||||||||||||||
1020 | QQmlContextData *contextData = QQmlContextData::get(context); | - | ||||||||||||||||||
1021 | QQmlContextData *forContextData = contextData; | - | ||||||||||||||||||
1022 | if (forContext) forContextData = QQmlContextData::get(forContext); executed 22 times by 1 test: forContextData = QQmlContextData::get(forContext); Executed by:
| 22-382 | ||||||||||||||||||
1023 | - | |||||||||||||||||||
1024 | if (!contextData->isValid()) {
| 0-404 | ||||||||||||||||||
1025 | qWarning("QQmlComponent: Cannot create a component in an invalid context"); | - | ||||||||||||||||||
1026 | return; never executed: return; | 0 | ||||||||||||||||||
1027 | } | - | ||||||||||||||||||
1028 | - | |||||||||||||||||||
1029 | if (contextData->engine != d->engine) {
| 0-404 | ||||||||||||||||||
1030 | qWarning("QQmlComponent: Must create component in context from the same QQmlEngine"); | - | ||||||||||||||||||
1031 | return; never executed: return; | 0 | ||||||||||||||||||
1032 | } | - | ||||||||||||||||||
1033 | - | |||||||||||||||||||
1034 | if (!isReady()) {
| 0-404 | ||||||||||||||||||
1035 | qWarning("QQmlComponent: Component is not ready"); | - | ||||||||||||||||||
1036 | return; never executed: return; | 0 | ||||||||||||||||||
1037 | } | - | ||||||||||||||||||
1038 | - | |||||||||||||||||||
1039 | incubator.clear(); | - | ||||||||||||||||||
1040 | QExplicitlySharedDataPointer<QQmlIncubatorPrivate> p(incubator.d); | - | ||||||||||||||||||
1041 | - | |||||||||||||||||||
1042 | QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(d->engine); | - | ||||||||||||||||||
1043 | - | |||||||||||||||||||
1044 | p->compilationUnit = d->compilationUnit; | - | ||||||||||||||||||
1045 | p->enginePriv = enginePriv; | - | ||||||||||||||||||
1046 | p->creator.reset(new QQmlObjectCreator(contextData, d->compilationUnit, d->creationContext, p.data())); | - | ||||||||||||||||||
1047 | p->subComponentToCreate = d->start; | - | ||||||||||||||||||
1048 | - | |||||||||||||||||||
1049 | enginePriv->incubate(incubator, forContextData); | - | ||||||||||||||||||
1050 | } executed 404 times by 18 tests: end of block Executed by:
| 404 | ||||||||||||||||||
1051 | - | |||||||||||||||||||
1052 | /* | - | ||||||||||||||||||
1053 | This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData | - | ||||||||||||||||||
1054 | arguments instead of QQmlContext which means we don't have to construct the rather weighty | - | ||||||||||||||||||
1055 | wrapper class for every delegate item. | - | ||||||||||||||||||
1056 | - | |||||||||||||||||||
1057 | This is used by QQmlDelegateModel. | - | ||||||||||||||||||
1058 | */ | - | ||||||||||||||||||
1059 | void QQmlComponentPrivate::incubateObject( | - | ||||||||||||||||||
1060 | QQmlIncubator *incubationTask, | - | ||||||||||||||||||
1061 | QQmlComponent *component, | - | ||||||||||||||||||
1062 | QQmlEngine *engine, | - | ||||||||||||||||||
1063 | QQmlContextData *context, | - | ||||||||||||||||||
1064 | QQmlContextData *forContext) | - | ||||||||||||||||||
1065 | { | - | ||||||||||||||||||
1066 | QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask); | - | ||||||||||||||||||
1067 | QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); | - | ||||||||||||||||||
1068 | QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component); | - | ||||||||||||||||||
1069 | - | |||||||||||||||||||
1070 | incubatorPriv->compilationUnit = componentPriv->compilationUnit; | - | ||||||||||||||||||
1071 | incubatorPriv->enginePriv = enginePriv; | - | ||||||||||||||||||
1072 | incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext)); | - | ||||||||||||||||||
1073 | incubatorPriv->subComponentToCreate = componentPriv->start; | - | ||||||||||||||||||
1074 | - | |||||||||||||||||||
1075 | enginePriv->incubate(*incubationTask, forContext); | - | ||||||||||||||||||
1076 | } executed 88407 times by 25 tests: end of block Executed by:
| 88407 | ||||||||||||||||||
1077 | - | |||||||||||||||||||
1078 | - | |||||||||||||||||||
1079 | - | |||||||||||||||||||
1080 | class QQmlComponentIncubator; | - | ||||||||||||||||||
1081 | - | |||||||||||||||||||
1082 | namespace QV4 { | - | ||||||||||||||||||
1083 | - | |||||||||||||||||||
1084 | namespace Heap { | - | ||||||||||||||||||
1085 | - | |||||||||||||||||||
1086 | #define QmlIncubatorObjectMembers(class, Member) \ | - | ||||||||||||||||||
1087 | Member(class, HeapValue, HeapValue, valuemap) \ | - | ||||||||||||||||||
1088 | Member(class, HeapValue, HeapValue, statusChanged) \ | - | ||||||||||||||||||
1089 | Member(class, Pointer, QmlContext *, qmlContext) \ | - | ||||||||||||||||||
1090 | Member(class, NoMark, QQmlComponentIncubator *, incubator) \ | - | ||||||||||||||||||
1091 | Member(class, NoMark, QQmlQPointer<QObject>, parent) | - | ||||||||||||||||||
1092 | - | |||||||||||||||||||
1093 | DECLARE_HEAP_OBJECT(QmlIncubatorObject, Object) { | - | ||||||||||||||||||
1094 | DECLARE_MARKOBJECTS(QmlIncubatorObject); never executed: end of block never executed: o->qmlContext.heapObject()->mark(stack);
| 0 | ||||||||||||||||||
1095 | - | |||||||||||||||||||
1096 | void init(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous); | - | ||||||||||||||||||
1097 | inline void destroy(); | - | ||||||||||||||||||
1098 | }; | - | ||||||||||||||||||
1099 | - | |||||||||||||||||||
1100 | } | - | ||||||||||||||||||
1101 | - | |||||||||||||||||||
1102 | struct QmlIncubatorObject : public QV4::Object | - | ||||||||||||||||||
1103 | { | - | ||||||||||||||||||
1104 | V4_OBJECT2(QmlIncubatorObject, Object) executed 24 times by 2 tests: end of block Executed by:
never executed: end of block executed 54 times by 3 tests: return &static_vtbl; Executed by:
executed 182 times by 3 tests: return static_cast<QV4::Heap::QmlIncubatorObject *>(m()); Executed by:
executed 172 times by 3 tests: return dptr; Executed by:
| 0-182 | ||||||||||||||||||
1105 | V4_NEEDS_DESTROY executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1106 | - | |||||||||||||||||||
1107 | static ReturnedValue method_get_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); | - | ||||||||||||||||||
1108 | static ReturnedValue method_set_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); | - | ||||||||||||||||||
1109 | static ReturnedValue method_get_status(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); | - | ||||||||||||||||||
1110 | static ReturnedValue method_get_object(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); | - | ||||||||||||||||||
1111 | static ReturnedValue method_forceCompletion(const FunctionObject *, const Value *thisObject, const Value *argv, int argc); | - | ||||||||||||||||||
1112 | - | |||||||||||||||||||
1113 | void statusChanged(QQmlIncubator::Status); | - | ||||||||||||||||||
1114 | void setInitialState(QObject *); | - | ||||||||||||||||||
1115 | }; | - | ||||||||||||||||||
1116 | - | |||||||||||||||||||
1117 | } | - | ||||||||||||||||||
1118 | - | |||||||||||||||||||
1119 | DEFINE_OBJECT_VTABLE(QV4::QmlIncubatorObject); | - | ||||||||||||||||||
1120 | - | |||||||||||||||||||
1121 | class QQmlComponentIncubator : public QQmlIncubator | - | ||||||||||||||||||
1122 | { | - | ||||||||||||||||||
1123 | public: | - | ||||||||||||||||||
1124 | QQmlComponentIncubator(QV4::Heap::QmlIncubatorObject *inc, IncubationMode mode) | - | ||||||||||||||||||
1125 | : QQmlIncubator(mode) | - | ||||||||||||||||||
1126 | , incubatorObject(inc) | - | ||||||||||||||||||
1127 | {} executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1128 | - | |||||||||||||||||||
1129 | void statusChanged(Status s) override { | - | ||||||||||||||||||
1130 | QV4::Scope scope(incubatorObject->internalClass->engine); | - | ||||||||||||||||||
1131 | QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject); | - | ||||||||||||||||||
1132 | i->statusChanged(s); | - | ||||||||||||||||||
1133 | } executed 20 times by 3 tests: end of block Executed by:
| 20 | ||||||||||||||||||
1134 | - | |||||||||||||||||||
1135 | void setInitialState(QObject *o) override { | - | ||||||||||||||||||
1136 | QV4::Scope scope(incubatorObject->internalClass->engine); | - | ||||||||||||||||||
1137 | QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject); | - | ||||||||||||||||||
1138 | i->setInitialState(o); | - | ||||||||||||||||||
1139 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1140 | - | |||||||||||||||||||
1141 | QV4::Heap::QmlIncubatorObject *incubatorObject; | - | ||||||||||||||||||
1142 | }; | - | ||||||||||||||||||
1143 | - | |||||||||||||||||||
1144 | - | |||||||||||||||||||
1145 | static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) | - | ||||||||||||||||||
1146 | { | - | ||||||||||||||||||
1147 | if (parent) {
| 316-2490 | ||||||||||||||||||
1148 | me->setParent(parent); | - | ||||||||||||||||||
1149 | typedef QQmlPrivate::AutoParentFunction APF; | - | ||||||||||||||||||
1150 | QList<APF> functions = QQmlMetaType::parentFunctions(); | - | ||||||||||||||||||
1151 | - | |||||||||||||||||||
1152 | bool needParent = false; | - | ||||||||||||||||||
1153 | for (int ii = 0; ii < functions.count(); ++ii) {
| 22-2490 | ||||||||||||||||||
1154 | QQmlPrivate::AutoParentResult res = functions.at(ii)(me, parent); | - | ||||||||||||||||||
1155 | if (res == QQmlPrivate::Parented) {
| 22-2468 | ||||||||||||||||||
1156 | needParent = false; | - | ||||||||||||||||||
1157 | break; executed 2468 times by 10 tests: break; Executed by:
| 2468 | ||||||||||||||||||
1158 | } else if (res == QQmlPrivate::IncompatibleParent) {
| 2-20 | ||||||||||||||||||
1159 | needParent = true; | - | ||||||||||||||||||
1160 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
1161 | } executed 22 times by 4 tests: end of block Executed by:
| 22 | ||||||||||||||||||
1162 | if (needParent)
| 2-2488 | ||||||||||||||||||
1163 | qWarning("QQmlComponent: Created graphical object was not " executed 2 times by 1 test: QMessageLogger(__FILE__, 1163, __PRETTY_FUNCTION__).warning("QQmlComponent: Created graphical object was not " "placed in the graphics scene."); Executed by:
| 2 | ||||||||||||||||||
1164 | "placed in the graphics scene."); executed 2 times by 1 test: QMessageLogger(__FILE__, 1163, __PRETTY_FUNCTION__).warning("QQmlComponent: Created graphical object was not " "placed in the graphics scene."); Executed by:
| 2 | ||||||||||||||||||
1165 | } executed 2490 times by 12 tests: end of block Executed by:
| 2490 | ||||||||||||||||||
1166 | } executed 2806 times by 16 tests: end of block Executed by:
| 2806 | ||||||||||||||||||
1167 | - | |||||||||||||||||||
1168 | /*! | - | ||||||||||||||||||
1169 | \qmlmethod object Component::createObject(QtObject parent, object properties) | - | ||||||||||||||||||
1170 | - | |||||||||||||||||||
1171 | Creates and returns an object instance of this component that will have | - | ||||||||||||||||||
1172 | the given \a parent and \a properties. The \a properties argument is optional. | - | ||||||||||||||||||
1173 | Returns null if object creation fails. | - | ||||||||||||||||||
1174 | - | |||||||||||||||||||
1175 | The object will be created in the same context as the one in which the component | - | ||||||||||||||||||
1176 | was created. This function will always return null when called on components | - | ||||||||||||||||||
1177 | which were not created in QML. | - | ||||||||||||||||||
1178 | - | |||||||||||||||||||
1179 | If you wish to create an object without setting a parent, specify \c null for | - | ||||||||||||||||||
1180 | the \a parent value. Note that if the returned object is to be displayed, you | - | ||||||||||||||||||
1181 | must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent} | - | ||||||||||||||||||
1182 | property, otherwise the object will not be visible. | - | ||||||||||||||||||
1183 | - | |||||||||||||||||||
1184 | If a \a parent is not provided to createObject(), a reference to the returned object must be held so that | - | ||||||||||||||||||
1185 | it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards, | - | ||||||||||||||||||
1186 | because setting the Item parent does not change object ownership. Only the graphical parent is changed. | - | ||||||||||||||||||
1187 | - | |||||||||||||||||||
1188 | As of \c {QtQuick 1.1}, this method accepts an optional \a properties argument that specifies a | - | ||||||||||||||||||
1189 | map of initial property values for the created object. These values are applied before the object | - | ||||||||||||||||||
1190 | creation is finalized. This is more efficient than setting property values after object creation, | - | ||||||||||||||||||
1191 | particularly where large sets of property values are defined, and also allows property bindings | - | ||||||||||||||||||
1192 | to be set up (using \l{Qt::binding}{Qt.binding}) before the object is created. | - | ||||||||||||||||||
1193 | - | |||||||||||||||||||
1194 | The \a properties argument is specified as a map of property-value items. For example, the code | - | ||||||||||||||||||
1195 | below creates an object with initial \c x and \c y values of 100 and 100, respectively: | - | ||||||||||||||||||
1196 | - | |||||||||||||||||||
1197 | \js | - | ||||||||||||||||||
1198 | var component = Qt.createComponent("Button.qml"); | - | ||||||||||||||||||
1199 | if (component.status == Component.Ready) | - | ||||||||||||||||||
1200 | component.createObject(parent, {"x": 100, "y": 100}); | - | ||||||||||||||||||
1201 | \endjs | - | ||||||||||||||||||
1202 | - | |||||||||||||||||||
1203 | Dynamically created instances can be deleted with the \c destroy() method. | - | ||||||||||||||||||
1204 | See \l {Dynamic QML Object Creation from JavaScript} for more information. | - | ||||||||||||||||||
1205 | - | |||||||||||||||||||
1206 | \sa incubateObject() | - | ||||||||||||||||||
1207 | */ | - | ||||||||||||||||||
1208 | - | |||||||||||||||||||
1209 | - | |||||||||||||||||||
1210 | void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v) | - | ||||||||||||||||||
1211 | { | - | ||||||||||||||||||
1212 | QV4::Scope scope(engine); | - | ||||||||||||||||||
1213 | QV4::ScopedObject object(scope); | - | ||||||||||||||||||
1214 | QV4::ScopedObject valueMap(scope, v); | - | ||||||||||||||||||
1215 | QV4::ObjectIterator it(scope, valueMap, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain); | - | ||||||||||||||||||
1216 | QV4::ScopedString name(scope); | - | ||||||||||||||||||
1217 | QV4::ScopedValue val(scope); | - | ||||||||||||||||||
1218 | if (engine->hasException)
| 0-58 | ||||||||||||||||||
1219 | return; never executed: return; | 0 | ||||||||||||||||||
1220 | - | |||||||||||||||||||
1221 | QV4::ScopedStackFrame frame(scope, qmlContext->d()); | - | ||||||||||||||||||
1222 | - | |||||||||||||||||||
1223 | while (1) { | - | ||||||||||||||||||
1224 | name = it.nextPropertyNameAsString(val); | - | ||||||||||||||||||
1225 | if (!name)
| 58-80 | ||||||||||||||||||
1226 | break; executed 58 times by 8 tests: break; Executed by:
| 58 | ||||||||||||||||||
1227 | object = o; | - | ||||||||||||||||||
1228 | const QStringList properties = name->toQString().split(QLatin1Char('.')); | - | ||||||||||||||||||
1229 | for (int i = 0; i < properties.length() - 1; ++i) {
| 6-80 | ||||||||||||||||||
1230 | name = engine->newString(properties.at(i)); | - | ||||||||||||||||||
1231 | object = object->get(name); | - | ||||||||||||||||||
1232 | if (engine->hasException || !object) {
| 0-6 | ||||||||||||||||||
1233 | break; never executed: break; | 0 | ||||||||||||||||||
1234 | } | - | ||||||||||||||||||
1235 | } executed 6 times by 1 test: end of block Executed by:
| 6 | ||||||||||||||||||
1236 | if (engine->hasException || !object) {
| 0-80 | ||||||||||||||||||
1237 | engine->hasException = false; | - | ||||||||||||||||||
1238 | continue; never executed: continue; | 0 | ||||||||||||||||||
1239 | } | - | ||||||||||||||||||
1240 | name = engine->newString(properties.last()); | - | ||||||||||||||||||
1241 | object->put(name, val); | - | ||||||||||||||||||
1242 | if (engine->hasException) {
| 2-78 | ||||||||||||||||||
1243 | engine->hasException = false; | - | ||||||||||||||||||
1244 | continue; executed 2 times by 1 test: continue; Executed by:
| 2 | ||||||||||||||||||
1245 | } | - | ||||||||||||||||||
1246 | } executed 78 times by 5 tests: end of block Executed by:
| 78 | ||||||||||||||||||
1247 | - | |||||||||||||||||||
1248 | engine->hasException = false; | - | ||||||||||||||||||
1249 | } executed 58 times by 8 tests: end of block Executed by:
| 58 | ||||||||||||||||||
1250 | - | |||||||||||||||||||
1251 | /*! | - | ||||||||||||||||||
1252 | \internal | - | ||||||||||||||||||
1253 | */ | - | ||||||||||||||||||
1254 | void QQmlComponent::createObject(QQmlV4Function *args) | - | ||||||||||||||||||
1255 | { | - | ||||||||||||||||||
1256 | Q_D(QQmlComponent); | - | ||||||||||||||||||
1257 | Q_ASSERT(d->engine); | - | ||||||||||||||||||
1258 | Q_ASSERT(args); | - | ||||||||||||||||||
1259 | - | |||||||||||||||||||
1260 | QObject *parent = nullptr; | - | ||||||||||||||||||
1261 | QV4::ExecutionEngine *v4 = args->v4engine(); | - | ||||||||||||||||||
1262 | QV4::Scope scope(v4); | - | ||||||||||||||||||
1263 | QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue()); | - | ||||||||||||||||||
1264 | - | |||||||||||||||||||
1265 | if (args->length() >= 1) {
| 224-2598 | ||||||||||||||||||
1266 | QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, (*args)[0]); | - | ||||||||||||||||||
1267 | if (qobjectWrapper)
| 108-2490 | ||||||||||||||||||
1268 | parent = qobjectWrapper->object(); executed 2490 times by 12 tests: parent = qobjectWrapper->object(); Executed by:
| 2490 | ||||||||||||||||||
1269 | } executed 2598 times by 15 tests: end of block Executed by:
| 2598 | ||||||||||||||||||
1270 | - | |||||||||||||||||||
1271 | if (args->length() >= 2) {
| 34-2788 | ||||||||||||||||||
1272 | QV4::ScopedValue v(scope, (*args)[1]); | - | ||||||||||||||||||
1273 | if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
| 0-34 | ||||||||||||||||||
1274 | qmlWarning(this) << tr("createObject: value is not an object"); | - | ||||||||||||||||||
1275 | args->setReturnValue(QV4::Encode::null()); | - | ||||||||||||||||||
1276 | return; never executed: return; | 0 | ||||||||||||||||||
1277 | } | - | ||||||||||||||||||
1278 | valuemap = v; | - | ||||||||||||||||||
1279 | } executed 34 times by 8 tests: end of block Executed by:
| 34 | ||||||||||||||||||
1280 | - | |||||||||||||||||||
1281 | QQmlContext *ctxt = creationContext(); | - | ||||||||||||||||||
1282 | if (!ctxt) ctxt = d->engine->rootContext(); executed 2 times by 1 test: ctxt = d->engine->rootContext(); Executed by:
| 2-2820 | ||||||||||||||||||
1283 | - | |||||||||||||||||||
1284 | QObject *rv = beginCreate(ctxt); | - | ||||||||||||||||||
1285 | - | |||||||||||||||||||
1286 | if (!rv) {
| 26-2796 | ||||||||||||||||||
1287 | args->setReturnValue(QV4::Encode::null()); | - | ||||||||||||||||||
1288 | return; executed 26 times by 3 tests: return; Executed by:
| 26 | ||||||||||||||||||
1289 | } | - | ||||||||||||||||||
1290 | - | |||||||||||||||||||
1291 | QQmlComponent_setQmlParent(rv, parent); | - | ||||||||||||||||||
1292 | - | |||||||||||||||||||
1293 | QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4, rv)); | - | ||||||||||||||||||
1294 | Q_ASSERT(object->isObject()); | - | ||||||||||||||||||
1295 | - | |||||||||||||||||||
1296 | if (!valuemap->isUndefined()) {
| 34-2762 | ||||||||||||||||||
1297 | QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext()); | - | ||||||||||||||||||
1298 | QQmlComponentPrivate::setInitialProperties(v4, qmlContext, object, valuemap); | - | ||||||||||||||||||
1299 | } executed 34 times by 8 tests: end of block Executed by:
| 34 | ||||||||||||||||||
1300 | - | |||||||||||||||||||
1301 | d->completeCreate(); | - | ||||||||||||||||||
1302 | - | |||||||||||||||||||
1303 | Q_ASSERT(QQmlData::get(rv)); | - | ||||||||||||||||||
1304 | QQmlData::get(rv)->explicitIndestructibleSet = false; | - | ||||||||||||||||||
1305 | QQmlData::get(rv)->indestructible = false; | - | ||||||||||||||||||
1306 | - | |||||||||||||||||||
1307 | args->setReturnValue(object->asReturnedValue()); | - | ||||||||||||||||||
1308 | } executed 2796 times by 15 tests: end of block Executed by:
| 2796 | ||||||||||||||||||
1309 | - | |||||||||||||||||||
1310 | /*! | - | ||||||||||||||||||
1311 | \qmlmethod object Component::incubateObject(Item parent, object properties, enumeration mode) | - | ||||||||||||||||||
1312 | - | |||||||||||||||||||
1313 | Creates an incubator for an instance of this component. Incubators allow new component | - | ||||||||||||||||||
1314 | instances to be instantiated asynchronously and do not cause freezes in the UI. | - | ||||||||||||||||||
1315 | - | |||||||||||||||||||
1316 | The \a parent argument specifies the parent the created instance will have. Omitting the | - | ||||||||||||||||||
1317 | parameter or passing null will create an object with no parent. In this case, a reference | - | ||||||||||||||||||
1318 | to the created object must be held so that it is not destroyed by the garbage collector. | - | ||||||||||||||||||
1319 | - | |||||||||||||||||||
1320 | The \a properties argument is specified as a map of property-value items which will be | - | ||||||||||||||||||
1321 | set on the created object during its construction. \a mode may be Qt.Synchronous or | - | ||||||||||||||||||
1322 | Qt.Asynchronous, and controls whether the instance is created synchronously or asynchronously. | - | ||||||||||||||||||
1323 | The default is asynchronous. In some circumstances, even if Qt.Synchronous is specified, | - | ||||||||||||||||||
1324 | the incubator may create the object asynchronously. This happens if the component calling | - | ||||||||||||||||||
1325 | incubateObject() is itself being created asynchronously. | - | ||||||||||||||||||
1326 | - | |||||||||||||||||||
1327 | All three arguments are optional. | - | ||||||||||||||||||
1328 | - | |||||||||||||||||||
1329 | If successful, the method returns an incubator, otherwise null. The incubator has the following | - | ||||||||||||||||||
1330 | properties: | - | ||||||||||||||||||
1331 | - | |||||||||||||||||||
1332 | \list | - | ||||||||||||||||||
1333 | \li status The status of the incubator. Valid values are Component.Ready, Component.Loading and | - | ||||||||||||||||||
1334 | Component.Error. | - | ||||||||||||||||||
1335 | \li object The created object instance. Will only be available once the incubator is in the | - | ||||||||||||||||||
1336 | Ready status. | - | ||||||||||||||||||
1337 | \li onStatusChanged Specifies a callback function to be invoked when the status changes. The | - | ||||||||||||||||||
1338 | status is passed as a parameter to the callback. | - | ||||||||||||||||||
1339 | \li forceCompletion() Call to complete incubation synchronously. | - | ||||||||||||||||||
1340 | \endlist | - | ||||||||||||||||||
1341 | - | |||||||||||||||||||
1342 | The following example demonstrates how to use an incubator: | - | ||||||||||||||||||
1343 | - | |||||||||||||||||||
1344 | \js | - | ||||||||||||||||||
1345 | var component = Qt.createComponent("Button.qml"); | - | ||||||||||||||||||
1346 | - | |||||||||||||||||||
1347 | var incubator = component.incubateObject(parent, { x: 10, y: 10 }); | - | ||||||||||||||||||
1348 | if (incubator.status != Component.Ready) { | - | ||||||||||||||||||
1349 | incubator.onStatusChanged = function(status) { | - | ||||||||||||||||||
1350 | if (status == Component.Ready) { | - | ||||||||||||||||||
1351 | print ("Object", incubator.object, "is now ready!"); | - | ||||||||||||||||||
1352 | } | - | ||||||||||||||||||
1353 | } | - | ||||||||||||||||||
1354 | } else { | - | ||||||||||||||||||
1355 | print ("Object", incubator.object, "is ready immediately!"); | - | ||||||||||||||||||
1356 | } | - | ||||||||||||||||||
1357 | \endjs | - | ||||||||||||||||||
1358 | - | |||||||||||||||||||
1359 | Dynamically created instances can be deleted with the \c destroy() method. | - | ||||||||||||||||||
1360 | See \l {Dynamic QML Object Creation from JavaScript} for more information. | - | ||||||||||||||||||
1361 | - | |||||||||||||||||||
1362 | \sa createObject() | - | ||||||||||||||||||
1363 | */ | - | ||||||||||||||||||
1364 | - | |||||||||||||||||||
1365 | /*! | - | ||||||||||||||||||
1366 | \internal | - | ||||||||||||||||||
1367 | */ | - | ||||||||||||||||||
1368 | void QQmlComponent::incubateObject(QQmlV4Function *args) | - | ||||||||||||||||||
1369 | { | - | ||||||||||||||||||
1370 | Q_D(QQmlComponent); | - | ||||||||||||||||||
1371 | Q_ASSERT(d->engine); | - | ||||||||||||||||||
1372 | Q_UNUSED(d); | - | ||||||||||||||||||
1373 | Q_ASSERT(args); | - | ||||||||||||||||||
1374 | QV4::ExecutionEngine *v4 = args->v4engine(); | - | ||||||||||||||||||
1375 | QV4::Scope scope(v4); | - | ||||||||||||||||||
1376 | - | |||||||||||||||||||
1377 | QObject *parent = nullptr; | - | ||||||||||||||||||
1378 | QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue()); | - | ||||||||||||||||||
1379 | QQmlIncubator::IncubationMode mode = QQmlIncubator::Asynchronous; | - | ||||||||||||||||||
1380 | - | |||||||||||||||||||
1381 | if (args->length() >= 1) {
| 0-10 | ||||||||||||||||||
1382 | QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, (*args)[0]); | - | ||||||||||||||||||
1383 | if (qobjectWrapper)
| 4-6 | ||||||||||||||||||
1384 | parent = qobjectWrapper->object(); executed 4 times by 2 tests: parent = qobjectWrapper->object(); Executed by:
| 4 | ||||||||||||||||||
1385 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1386 | - | |||||||||||||||||||
1387 | if (args->length() >= 2) {
| 2-8 | ||||||||||||||||||
1388 | QV4::ScopedValue v(scope, (*args)[1]); | - | ||||||||||||||||||
1389 | if (v->isNull()) {
| 2-6 | ||||||||||||||||||
1390 | } else if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) { executed 2 times by 1 test: end of block Executed by:
| 0-6 | ||||||||||||||||||
1391 | qmlWarning(this) << tr("createObject: value is not an object"); | - | ||||||||||||||||||
1392 | args->setReturnValue(QV4::Encode::null()); | - | ||||||||||||||||||
1393 | return; never executed: return; | 0 | ||||||||||||||||||
1394 | } else { | - | ||||||||||||||||||
1395 | valuemap = v; | - | ||||||||||||||||||
1396 | } executed 6 times by 1 test: end of block Executed by:
| 6 | ||||||||||||||||||
1397 | } | - | ||||||||||||||||||
1398 | - | |||||||||||||||||||
1399 | if (args->length() >= 3) {
| 4-6 | ||||||||||||||||||
1400 | QV4::ScopedValue val(scope, (*args)[2]); | - | ||||||||||||||||||
1401 | quint32 v = val->toUInt32(); | - | ||||||||||||||||||
1402 | if (v == 0)
| 2 | ||||||||||||||||||
1403 | mode = QQmlIncubator::Asynchronous; executed 2 times by 1 test: mode = QQmlIncubator::Asynchronous; Executed by:
| 2 | ||||||||||||||||||
1404 | else if (v == 1)
| 0-2 | ||||||||||||||||||
1405 | mode = QQmlIncubator::AsynchronousIfNested; executed 2 times by 1 test: mode = QQmlIncubator::AsynchronousIfNested; Executed by:
| 2 | ||||||||||||||||||
1406 | } executed 4 times by 2 tests: end of block Executed by:
| 4 | ||||||||||||||||||
1407 | - | |||||||||||||||||||
1408 | QQmlComponentExtension *e = componentExtension(args->v4engine()); | - | ||||||||||||||||||
1409 | - | |||||||||||||||||||
1410 | QV4::Scoped<QV4::QmlIncubatorObject> r(scope, v4->memoryManager->allocate<QV4::QmlIncubatorObject>(mode)); | - | ||||||||||||||||||
1411 | QV4::ScopedObject p(scope, e->incubationProto.value()); | - | ||||||||||||||||||
1412 | r->setPrototypeOf(p); | - | ||||||||||||||||||
1413 | - | |||||||||||||||||||
1414 | if (!valuemap->isUndefined())
| 4-6 | ||||||||||||||||||
1415 | r->d()->valuemap.set(scope.engine, valuemap); executed 6 times by 1 test: r->d()->valuemap.set(scope.engine, valuemap); Executed by:
| 6 | ||||||||||||||||||
1416 | r->d()->qmlContext.set(scope.engine, v4->qmlContext()); | - | ||||||||||||||||||
1417 | r->d()->parent = parent; | - | ||||||||||||||||||
1418 | - | |||||||||||||||||||
1419 | QQmlIncubator *incubator = r->d()->incubator; | - | ||||||||||||||||||
1420 | create(*incubator, creationContext()); | - | ||||||||||||||||||
1421 | - | |||||||||||||||||||
1422 | if (incubator->status() == QQmlIncubator::Null) {
| 0-10 | ||||||||||||||||||
1423 | args->setReturnValue(QV4::Encode::null()); | - | ||||||||||||||||||
1424 | } else { never executed: end of block | 0 | ||||||||||||||||||
1425 | args->setReturnValue(r.asReturnedValue()); | - | ||||||||||||||||||
1426 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1427 | } | - | ||||||||||||||||||
1428 | - | |||||||||||||||||||
1429 | // XXX used by QSGLoader | - | ||||||||||||||||||
1430 | void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate) | - | ||||||||||||||||||
1431 | { | - | ||||||||||||||||||
1432 | QV4::ExecutionEngine *v4engine = engine->handle(); | - | ||||||||||||||||||
1433 | QV4::Scope scope(v4engine); | - | ||||||||||||||||||
1434 | - | |||||||||||||||||||
1435 | QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate)); | - | ||||||||||||||||||
1436 | Q_ASSERT(object->as<QV4::Object>()); | - | ||||||||||||||||||
1437 | - | |||||||||||||||||||
1438 | if (!valuemap.isUndefined())
| 0-18 | ||||||||||||||||||
1439 | setInitialProperties(v4engine, qmlContext, object, valuemap); executed 18 times by 3 tests: setInitialProperties(v4engine, qmlContext, object, valuemap); Executed by:
| 18 | ||||||||||||||||||
1440 | } executed 18 times by 3 tests: end of block Executed by:
| 18 | ||||||||||||||||||
1441 | - | |||||||||||||||||||
1442 | QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) | - | ||||||||||||||||||
1443 | { | - | ||||||||||||||||||
1444 | QV4::Scope scope(v4); | - | ||||||||||||||||||
1445 | QV4::ScopedObject proto(scope, v4->newObject()); | - | ||||||||||||||||||
1446 | proto->defineAccessorProperty(QStringLiteral("onStatusChanged"), executed 8 times by 3 tests: return qstring_literal_temp; Executed by:
| 8 | ||||||||||||||||||
1447 | QV4::QmlIncubatorObject::method_get_statusChanged, QV4::QmlIncubatorObject::method_set_statusChanged); | - | ||||||||||||||||||
1448 | proto->defineAccessorProperty(QStringLiteral("status"), QV4::QmlIncubatorObject::method_get_status, nullptr); executed 8 times by 3 tests: return qstring_literal_temp; Executed by:
| 8 | ||||||||||||||||||
1449 | proto->defineAccessorProperty(QStringLiteral("object"), QV4::QmlIncubatorObject::method_get_object, nullptr); executed 8 times by 3 tests: return qstring_literal_temp; Executed by:
| 8 | ||||||||||||||||||
1450 | proto->defineDefaultProperty(QStringLiteral("forceCompletion"), QV4::QmlIncubatorObject::method_forceCompletion); executed 8 times by 3 tests: return qstring_literal_temp; Executed by:
| 8 | ||||||||||||||||||
1451 | - | |||||||||||||||||||
1452 | incubationProto.set(v4, proto); | - | ||||||||||||||||||
1453 | } executed 8 times by 3 tests: end of block Executed by:
| 8 | ||||||||||||||||||
1454 | - | |||||||||||||||||||
1455 | QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
1456 | { | - | ||||||||||||||||||
1457 | QV4::Scope scope(b); | - | ||||||||||||||||||
1458 | QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>()); | - | ||||||||||||||||||
1459 | if (!o)
| 0-14 | ||||||||||||||||||
1460 | THROW_TYPE_ERROR(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
1461 | - | |||||||||||||||||||
1462 | return QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object()); executed 14 times by 2 tests: return QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object()); Executed by:
| 14 | ||||||||||||||||||
1463 | } | - | ||||||||||||||||||
1464 | - | |||||||||||||||||||
1465 | QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
1466 | { | - | ||||||||||||||||||
1467 | QV4::Scope scope(b); | - | ||||||||||||||||||
1468 | QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>()); | - | ||||||||||||||||||
1469 | if (!o)
| 0-2 | ||||||||||||||||||
1470 | THROW_TYPE_ERROR(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
1471 | - | |||||||||||||||||||
1472 | o->d()->incubator->forceCompletion(); | - | ||||||||||||||||||
1473 | - | |||||||||||||||||||
1474 | RETURN_UNDEFINED(); executed 2 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 2 | ||||||||||||||||||
1475 | } | - | ||||||||||||||||||
1476 | - | |||||||||||||||||||
1477 | QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
1478 | { | - | ||||||||||||||||||
1479 | QV4::Scope scope(b); | - | ||||||||||||||||||
1480 | QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>()); | - | ||||||||||||||||||
1481 | if (!o)
| 0-4 | ||||||||||||||||||
1482 | THROW_TYPE_ERROR(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
1483 | - | |||||||||||||||||||
1484 | return QV4::Encode(o->d()->incubator->status()); executed 4 times by 2 tests: return QV4::Encode(o->d()->incubator->status()); Executed by:
| 4 | ||||||||||||||||||
1485 | } | - | ||||||||||||||||||
1486 | - | |||||||||||||||||||
1487 | QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
1488 | { | - | ||||||||||||||||||
1489 | QV4::Scope scope(b); | - | ||||||||||||||||||
1490 | QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>()); | - | ||||||||||||||||||
1491 | if (!o)
| 0 | ||||||||||||||||||
1492 | THROW_TYPE_ERROR(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
1493 | - | |||||||||||||||||||
1494 | return QV4::Encode(o->d()->statusChanged); never executed: return QV4::Encode(o->d()->statusChanged); | 0 | ||||||||||||||||||
1495 | } | - | ||||||||||||||||||
1496 | - | |||||||||||||||||||
1497 | QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||||||||
1498 | { | - | ||||||||||||||||||
1499 | QV4::Scope scope(b); | - | ||||||||||||||||||
1500 | QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>()); | - | ||||||||||||||||||
1501 | if (!o || argc < 1)
| 0-4 | ||||||||||||||||||
1502 | THROW_TYPE_ERROR(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
1503 | - | |||||||||||||||||||
1504 | o->d()->statusChanged.set(scope.engine, argv[0]); | - | ||||||||||||||||||
1505 | - | |||||||||||||||||||
1506 | RETURN_UNDEFINED(); executed 4 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 4 | ||||||||||||||||||
1507 | } | - | ||||||||||||||||||
1508 | - | |||||||||||||||||||
1509 | QQmlComponentExtension::~QQmlComponentExtension() | - | ||||||||||||||||||
1510 | { | - | ||||||||||||||||||
1511 | } | - | ||||||||||||||||||
1512 | - | |||||||||||||||||||
1513 | void QV4::Heap::QmlIncubatorObject::init(QQmlIncubator::IncubationMode m) | - | ||||||||||||||||||
1514 | { | - | ||||||||||||||||||
1515 | Object::init(); | - | ||||||||||||||||||
1516 | valuemap.set(internalClass->engine, QV4::Primitive::undefinedValue()); | - | ||||||||||||||||||
1517 | statusChanged.set(internalClass->engine, QV4::Primitive::undefinedValue()); | - | ||||||||||||||||||
1518 | parent.init(); | - | ||||||||||||||||||
1519 | qmlContext.set(internalClass->engine, nullptr); | - | ||||||||||||||||||
1520 | incubator = new QQmlComponentIncubator(this, m); | - | ||||||||||||||||||
1521 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1522 | - | |||||||||||||||||||
1523 | void QV4::Heap::QmlIncubatorObject::destroy() { | - | ||||||||||||||||||
1524 | delete incubator; | - | ||||||||||||||||||
1525 | parent.destroy(); | - | ||||||||||||||||||
1526 | Object::destroy(); | - | ||||||||||||||||||
1527 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1528 | - | |||||||||||||||||||
1529 | void QV4::QmlIncubatorObject::setInitialState(QObject *o) | - | ||||||||||||||||||
1530 | { | - | ||||||||||||||||||
1531 | QQmlComponent_setQmlParent(o, d()->parent); | - | ||||||||||||||||||
1532 | - | |||||||||||||||||||
1533 | if (!d()->valuemap.isUndefined()) {
| 4-6 | ||||||||||||||||||
1534 | QV4::ExecutionEngine *v4 = engine(); | - | ||||||||||||||||||
1535 | QV4::Scope scope(v4); | - | ||||||||||||||||||
1536 | QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o)); | - | ||||||||||||||||||
1537 | QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, d()->qmlContext); | - | ||||||||||||||||||
1538 | QQmlComponentPrivate::setInitialProperties(v4, qmlCtxt, obj, d()->valuemap); | - | ||||||||||||||||||
1539 | } executed 6 times by 1 test: end of block Executed by:
| 6 | ||||||||||||||||||
1540 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1541 | - | |||||||||||||||||||
1542 | void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) | - | ||||||||||||||||||
1543 | { | - | ||||||||||||||||||
1544 | QV4::Scope scope(engine()); | - | ||||||||||||||||||
1545 | // hold the incubated object in a scoped value to prevent it's destruction before this method returns | - | ||||||||||||||||||
1546 | QV4::ScopedObject incubatedObject(scope, QV4::QObjectWrapper::wrap(scope.engine, d()->incubator->object())); | - | ||||||||||||||||||
1547 | - | |||||||||||||||||||
1548 | if (s == QQmlIncubator::Ready) {
| 10 | ||||||||||||||||||
1549 | Q_ASSERT(QQmlData::get(d()->incubator->object())); | - | ||||||||||||||||||
1550 | QQmlData::get(d()->incubator->object())->explicitIndestructibleSet = false; | - | ||||||||||||||||||
1551 | QQmlData::get(d()->incubator->object())->indestructible = false; | - | ||||||||||||||||||
1552 | } executed 10 times by 3 tests: end of block Executed by:
| 10 | ||||||||||||||||||
1553 | - | |||||||||||||||||||
1554 | QV4::ScopedFunctionObject f(scope, d()->statusChanged); | - | ||||||||||||||||||
1555 | if (f) {
| 4-16 | ||||||||||||||||||
1556 | QV4::JSCallData jsCallData(scope, 1); | - | ||||||||||||||||||
1557 | *jsCallData->thisObject = this; | - | ||||||||||||||||||
1558 | jsCallData->args[0] = QV4::Primitive::fromUInt32(s); | - | ||||||||||||||||||
1559 | f->call(jsCallData); | - | ||||||||||||||||||
1560 | if (scope.hasException()) {
| 0-4 | ||||||||||||||||||
1561 | QQmlError error = scope.engine->catchExceptionAsQmlError(); | - | ||||||||||||||||||
1562 | QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error); | - | ||||||||||||||||||
1563 | } never executed: end of block | 0 | ||||||||||||||||||
1564 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||
1565 | } executed 20 times by 3 tests: end of block Executed by:
| 20 | ||||||||||||||||||
1566 | - | |||||||||||||||||||
1567 | #undef INITIALPROPERTIES_SOURCE | - | ||||||||||||||||||
1568 | - | |||||||||||||||||||
1569 | QT_END_NAMESPACE | - | ||||||||||||||||||
1570 | - | |||||||||||||||||||
1571 | #include "moc_qqmlcomponent.cpp" | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |