Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmlengine_p.h"
5#include "qqmlengine.h"
6
7#include "qqmlcontext_p.h"
8#include "qqml.h"
9#include "qqmlcontext.h"
10#include "qqmlscriptstring.h"
11#include "qqmlglobal_p.h"
12#include "qqmlnotifier_p.h"
13#include "qqmlincubator.h"
15
16#include <private/qqmldirparser_p.h>
17#include <private/qqmlboundsignal_p.h>
18#include <private/qqmljsdiagnosticmessage_p.h>
19#include <private/qqmltype_p_p.h>
20#include <private/qqmlpluginimporter_p.h>
21#include <QtCore/qstandardpaths.h>
22#include <QtCore/qmetaobject.h>
23#include <QDebug>
24#include <QtCore/qcoreapplication.h>
25#include <QtCore/qcryptographichash.h>
26#include <QtCore/qdir.h>
27#include <QtCore/qmutex.h>
28#include <QtCore/qthread.h>
29#include <private/qthread_p.h>
30#include <private/qqmlscriptdata_p.h>
31#include <QtQml/private/qqmlcomponentattached_p.h>
32#include <QtQml/private/qqmlsourcecoordinate_p.h>
33#include <QtQml/private/qqmlcomponent_p.h>
34
35#if QT_CONFIG(qml_network)
37#include <QNetworkAccessManager>
38#endif
39
40#include <private/qobject_p.h>
41#include <private/qmetaobject_p.h>
42#if QT_CONFIG(qml_locale)
43#include <private/qqmllocale_p.h>
44#endif
45#include <private/qqmlbind_p.h>
46#include <private/qqmlconnections_p.h>
47#if QT_CONFIG(qml_animation)
48#include <private/qqmltimer_p.h>
49#endif
50#include <private/qqmlplatform_p.h>
51#include <private/qqmlloggingcategory_p.h>
52#include <private/qv4sequenceobject_p.h>
53
54#ifdef Q_OS_WIN // for %APPDATA%
55# include <qt_windows.h>
56# include <shlobj.h>
57# include <qlibrary.h>
58# ifndef CSIDL_APPDATA
59# define CSIDL_APPDATA 0x001a // <username>\Application Data
60# endif
61#endif // Q_OS_WIN
62
64
121Q_CONSTINIT std::atomic<bool> QQmlEnginePrivate::qml_debugging_enabled{false};
122bool QQmlEnginePrivate::s_designerMode = false;
123
125{
126 return s_designerMode;
127}
128
130{
131 s_designerMode = true;
132}
133
134
189QQmlImageProviderBase::QQmlImageProviderBase()
190{
191}
192
195{
196}
197
199{
201 qWarning() << QQmlEngine::tr("There are still \"%1\" items in the process of being created at engine destruction.").arg(inProgressCreations);
202
204 incubationController = nullptr;
205
207
208#if QT_CONFIG(qml_debug)
209 delete profiler;
210#endif
211 qDeleteAll(cachedValueTypeInstances);
212}
213
215{
217 if (QQmlData *d = QQmlData::get(p)) {
218 if (d->ownContext) {
219 for (QQmlRefPointer<QQmlContextData> lc = d->ownContext->linkedContext(); lc;
220 lc = lc->linkedContext()) {
221 lc->invalidate();
222 if (lc->contextObject() == o)
223 lc->setContextObject(nullptr);
224 }
225 d->ownContext->invalidate();
226 if (d->ownContext->contextObject() == o)
227 d->ownContext->setContextObject(nullptr);
228 d->ownContext.reset();
229 d->context = nullptr;
230 }
231
232 if (d->outerContext && d->outerContext->contextObject() == o)
233 d->outerContext->setContextObject(nullptr);
234
235 if (d->hasVMEMetaObject || d->hasInterceptorMetaObject) {
236 // This is somewhat dangerous because another thread might concurrently
237 // try to resolve the dynamic metaobject. In practice this will then
238 // lead to either the code path that still returns the interceptor
239 // metaobject or the code path that returns the string casted one. Both
240 // is fine if you cannot actually touch the object itself. Since the
241 // other thread is obviously not synchronized to this one, it can't.
242 //
243 // In particular we do this when delivering the frameSwapped() signal
244 // in QQuickWindow. The handler for frameSwapped() is written in a way
245 // that is thread safe as long as QQuickWindow's dtor hasn't finished.
246 // QQuickWindow's dtor does synchronize with the render thread, but it
247 // runs _after_ qdeclarativeelement_destructor.
248 static_cast<QQmlInterceptorMetaObject *>(p->metaObject)->invalidate();
249 d->hasVMEMetaObject = d->hasInterceptorMetaObject = false;
250 }
251
252 // Mark this object as in the process of deletion to
253 // prevent it resolving in bindings
255 }
256}
257
259 : ownMemory(ownership == OwnsMemory), indestructible(true), explicitIndestructibleSet(false),
260 hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
261 hasInterceptorMetaObject(false), hasVMEMetaObject(false), hasConstWrapper(false), dummy(0),
262 bindingBitsArraySize(InlineBindingArraySize)
263{
264 memset(bindingBitsValue, 0, sizeof(bindingBitsValue));
265 init();
266}
267
269{
270}
271
273{
274 QQmlData *ddata = static_cast<QQmlData *>(d);
275 ddata->destroyed(o);
276}
277
278
280{
281public:
283
284 int qt_metacall(QMetaObject::Call, int methodIndex, void **a) override {
285 if (!target)
286 return -1;
287
288 QMetaMethod method = target->metaObject()->method(methodIndex);
289 Q_ASSERT(method.methodType() == QMetaMethod::Signal);
291 QQmlData *ddata = QQmlData::get(target, false);
293 if (ep) QQmlNotifier::emitNotify(ep, a);
294
295 delete this;
296
297 return -1;
298 }
299};
300
302{
303 QQmlData *ddata = QQmlData::get(object, false);
304 if (!ddata) return; // Probably being deleted
305
306 // In general, QML only supports QObject's that live on the same thread as the QQmlEngine
307 // that they're exposed to. However, to make writing "worker objects" that calculate data
308 // in a separate thread easier, QML allows a QObject that lives in the same thread as the
309 // QQmlEngine to emit signals from a different thread. These signals are then automatically
310 // marshalled back onto the QObject's thread and handled by QML from there. This is tested
311 // by the qqmlecmascript::threadSignal() autotest.
312 if (!ddata->notifyList)
313 return;
314
315 auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed();
316 if (QThread::currentThreadId() != objectThreadData->threadId.loadRelaxed()) {
317 if (!objectThreadData->thread.loadAcquire())
318 return;
319
321 QList<QByteArray> parameterTypes = m.parameterTypes();
322
323 auto ev = std::make_unique<QMetaCallEvent>(m.methodIndex(), 0, nullptr,
324 object, index,
325 parameterTypes.size() + 1);
326
327 void **args = ev->args();
328 QMetaType *types = ev->types();
329
330 for (int ii = 0; ii < parameterTypes.size(); ++ii) {
331 const QByteArray &typeName = parameterTypes.at(ii);
332 if (typeName.endsWith('*'))
333 types[ii + 1] = QMetaType(QMetaType::VoidStar);
334 else
336
337 if (!types[ii + 1].isValid()) {
338 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
339 "(Make sure '%s' is registered using qRegisterMetaType().)",
340 typeName.constData(), typeName.constData());
341 return;
342 }
343
344 args[ii + 1] = types[ii + 1].create(a[ii + 1]);
345 }
346
348 mpo->target = object;
349 mpo->moveToThread(objectThreadData->thread.loadAcquire());
350 QCoreApplication::postEvent(mpo, ev.release());
351
352 } else {
353 QQmlNotifierEndpoint *ep = ddata->notify(index);
354 if (ep) QQmlNotifier::emitNotify(ep, a);
355 }
356}
357
359{
360 QQmlData *ddata = static_cast<QQmlData *>(d);
361 return ddata->endpointCount(index);
362}
363
365{
366 QQmlData *ddata = static_cast<QQmlData *>(d);
367 return ddata->signalHasEndpoint(index);
368}
369
371{
372 int count = 0;
374 if (!ep)
375 return count;
376 ++count;
377 while (ep->next) {
378 ++count;
379 ep = ep->next;
380 }
381 return count;
382}
383
385{
387 workStack.push_back(o);
388 while (!workStack.isEmpty()) {
389 auto currentObject = workStack.last();
390 workStack.pop_back();
391 QQmlData::setQueuedForDeletion(currentObject);
392 auto currentObjectPriv = QObjectPrivate::get(currentObject);
393 for (QObject *child: std::as_const(currentObjectPriv->children))
394 workStack.push_back(child);
395 }
396}
397
399{
400 if (object) {
401 if (QQmlData *ddata = QQmlData::get(object)) {
402 if (ddata->ownContext) {
403 Q_ASSERT(ddata->ownContext.data() == ddata->context);
404 ddata->context->emitDestruction();
405 if (ddata->ownContext->contextObject() == object)
406 ddata->ownContext->setContextObject(nullptr);
407 ddata->ownContext.reset();
408 ddata->context = nullptr;
409 }
410 ddata->isQueuedForDeletion = true;
411
412 // Disconnect the notifiers now - during object destruction this would be too late,
413 // since the disconnect call wouldn't be able to call disconnectNotify(), as it isn't
414 // possible to get the metaobject anymore.
415 // Also, there is no point in evaluating bindings in order to set properties on
416 // half-deleted objects.
417 ddata->disconnectNotifiers();
418 }
419 }
420}
421
423{
424 clearPendingBindingBit(coreIndex);
425
426 // Find the binding
428 while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
429 b->targetPropertyIndex().hasValueTypeIndex()))
430 b = b->nextBinding();
431
432 if (b && b->targetPropertyIndex().coreIndex() == coreIndex &&
433 !b->targetPropertyIndex().hasValueTypeIndex())
436}
437
440
441template<>
442int qmlRegisterType<void>(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
443{
446 QMetaType(),
447 QMetaType(),
448 0, nullptr, nullptr,
449 QString(),
450 nullptr,
451 uri,
452 QTypeRevision::fromVersion(versionMajor, versionMinor),
453 qmlName,
454 nullptr,
455 nullptr,
456 nullptr,
457 -1,
458 -1,
459 -1,
460 nullptr,
461 nullptr,
462 nullptr,
464 -1,
466 };
467
469}
470
473{
474 Q_Q(QQmlEngine);
475
477 // Named builtins
478 qmlRegisterType<void>("QML", 1, 0, "void");
479
480 const int varId = qmlRegisterType<QVariant>("QML", 1, 0, "var");
482 qmlRegisterAnonymousSequentialContainer<QList<QVariant>>("QML", 1);
483
484 qmlRegisterType<QObject>("QML", 1, 0, "QtObject");
485 qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component");
486
487 qmlRegisterType<int>("QML", 1, 0, "int");
488 qmlRegisterAnonymousSequentialContainer<QList<int>>("QML", 1);
489
490 const int realId = qmlRegisterType<double>("QML", 1, 0, "real");
492 qmlRegisterAnonymousSequentialContainer<QList<double>>("QML", 1);
493
494 qmlRegisterType<QString>("QML", 1, 0, "string");
495 qmlRegisterAnonymousSequentialContainer<QList<QString>>("QML", 1);
496
497 qmlRegisterType<bool>("QML", 1, 0, "bool");
498 qmlRegisterAnonymousSequentialContainer<QList<bool>>("QML", 1);
499
500 qmlRegisterType<QDateTime>("QML", 1, 0, "date");
501 qmlRegisterAnonymousSequentialContainer<QList<QDateTime>>("QML", 1);
502
503 qmlRegisterType<QUrl>("QML", 1, 0, "url");
504 qmlRegisterAnonymousSequentialContainer<QList<QUrl>>("QML", 1);
505
506#if QT_CONFIG(regularexpression)
507 qmlRegisterType<QRegularExpression>("QML", 1, 0, "regexp");
508 qmlRegisterAnonymousSequentialContainer<QList<QRegularExpression>>("QML", 1);
509#else
510 qmlRegisterType<void>("QML", 1, 0, "regexp");
511#endif
512
513 // Anonymous builtins
514 qmlRegisterAnonymousType<std::nullptr_t>("QML", 1);
515 qmlRegisterAnonymousType<QVariantMap>("QML", 1);
516
517 qmlRegisterAnonymousType<QJSValue>("QML", 1);
518 qmlRegisterAnonymousSequentialContainer<QList<QJSValue>>("QML", 1);
519
520 qmlRegisterAnonymousType<qint8>("QML", 1);
521 qmlRegisterAnonymousSequentialContainer<QList<qint8>>("QML", 1);
522
523 qmlRegisterAnonymousType<quint8>("QML", 1);
524 qmlRegisterAnonymousSequentialContainer<QList<quint8>>("QML", 1);
525
526 qmlRegisterAnonymousType<short>("QML", 1);
527 qmlRegisterAnonymousSequentialContainer<QList<short>>("QML", 1);
528
529 qmlRegisterAnonymousType<ushort>("QML", 1);
530 qmlRegisterAnonymousSequentialContainer<QList<ushort>>("QML", 1);
531
532 qmlRegisterAnonymousType<uint>("QML", 1);
533 qmlRegisterAnonymousSequentialContainer<QList<uint>>("QML", 1);
534
535 qmlRegisterAnonymousType<qlonglong>("QML", 1);
536 qmlRegisterAnonymousSequentialContainer<QList<qlonglong>>("QML", 1);
537
538 qmlRegisterAnonymousType<qulonglong>("QML", 1);
539 qmlRegisterAnonymousSequentialContainer<QList<qulonglong>>("QML", 1);
540
541 qmlRegisterAnonymousType<float>("QML", 1);
542 qmlRegisterAnonymousSequentialContainer<QList<float>>("QML", 1);
543
544 qmlRegisterAnonymousType<QChar>("QML", 1);
545 qmlRegisterAnonymousSequentialContainer<QList<QChar>>("QML", 1);
546
547 qmlRegisterAnonymousType<QDate>("QML", 1);
548 qmlRegisterAnonymousSequentialContainer<QList<QDate>>("QML", 1);
549
550 qmlRegisterAnonymousType<QTime>("QML", 1);
551 qmlRegisterAnonymousSequentialContainer<QList<QTime>>("QML", 1);
552
553 qmlRegisterAnonymousType<QByteArray>("QML", 1);
554 qmlRegisterAnonymousSequentialContainer<QList<QByteArray>>("QML", 1);
555
556 // No need to specifically register those.
557 static_assert(std::is_same_v<QStringList, QList<QString>>);
558 static_assert(std::is_same_v<QVariantList, QList<QVariant>>);
559
560 qRegisterMetaType<QQmlScriptString>();
561 qRegisterMetaType<QQmlComponent::Status>();
562 qRegisterMetaType<QList<QObject*> >();
563 qRegisterMetaType<QQmlBinding*>();
564
567 }
568
569 q->handle()->setQmlEngine(q);
570
571 rootContext = new QQmlContext(q,true);
572}
573
610{
611 Q_D(QQmlEngine);
612 d->init();
614}
615
620: QJSEngine(dd, parent)
621{
622 Q_D(QQmlEngine);
623 d->init();
624}
625
636{
637 Q_D(QQmlEngine);
639
640 // Emit onDestruction signals for the root context before
641 // we destroy the contexts, engine, Singleton Types etc. that
642 // may be required to handle the destruction signal.
644
645 // clean up all singleton type instances which we own.
646 // we do this here and not in the private dtor since otherwise a crash can
647 // occur (if we are the QObject parent of the QObject singleton instance)
648 // XXX TODO: performance -- store list of singleton types separately?
649 d->singletonInstances.clear();
650
651 delete d->rootContext;
652 d->rootContext = nullptr;
653
654 d->typeLoader.invalidate();
655}
656
704{
705 Q_D(QQmlEngine);
706 d->typeLoader.lock();
707 d->typeLoader.clearCache();
708 d->typeLoader.unlock();
709}
710
724{
725 Q_D(QQmlEngine);
726 d->typeLoader.trimCache();
727}
728
745{
746 Q_D(QQmlEngine);
747 d->singletonInstances.clear();
748}
749
762{
763 Q_D(const QQmlEngine);
764 return d->rootContext;
765}
766
767#if QT_DEPRECATED_SINCE(6, 0)
776QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const
777{
778 Q_D(const QQmlEngine);
779 return d->urlInterceptors.last();
780}
781#endif
782
793{
794 Q_D(QQmlEngine);
795 d->urlInterceptors.append(urlInterceptor);
796}
797
807{
808 Q_D(QQmlEngine);
809 d->urlInterceptors.removeOne(urlInterceptor);
810}
811
817{
818 Q_D(const QQmlEngine);
819 QUrl result = url;
820 for (QQmlAbstractUrlInterceptor *interceptor : d->urlInterceptors)
821 result = interceptor->intercept(result, type);
822 return result;
823}
824
829{
830 Q_D(const QQmlEngine);
831 return d->urlInterceptors;
832}
833
835{
836 const QString providerIdLower = providerId.toLower();
838 return imageProviders.value(providerIdLower);
839}
840
841#if QT_CONFIG(qml_network)
854void QQmlEngine::setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory)
855{
856 Q_D(QQmlEngine);
857 QMutexLocker locker(&d->networkAccessManagerMutex);
858 d->networkAccessManagerFactory = factory;
859}
860
866QQmlNetworkAccessManagerFactory *QQmlEngine::networkAccessManagerFactory() const
867{
868 Q_D(const QQmlEngine);
869 return d->networkAccessManagerFactory;
870}
871
872QNetworkAccessManager *QQmlEnginePrivate::createNetworkAccessManager(QObject *parent) const
873{
876 if (networkAccessManagerFactory) {
877 nam = networkAccessManagerFactory->create(parent);
878 } else {
879 nam = new QNetworkAccessManager(parent);
880 }
881
882 return nam;
883}
884
885QNetworkAccessManager *QQmlEnginePrivate::getNetworkAccessManager() const
886{
887 Q_Q(const QQmlEngine);
888 if (!networkAccessManager)
889 networkAccessManager = createNetworkAccessManager(const_cast<QQmlEngine*>(q));
890 return networkAccessManager;
891}
892
905QNetworkAccessManager *QQmlEngine::networkAccessManager() const
906{
907 Q_D(const QQmlEngine);
908 return d->getNetworkAccessManager();
909}
910#endif // qml_network
911
928{
929 Q_D(QQmlEngine);
930 QString providerIdLower = providerId.toLower();
932 QMutexLocker locker(&d->imageProviderMutex);
933 d->imageProviders.insert(std::move(providerIdLower), std::move(sp));
934}
935
942{
943 Q_D(const QQmlEngine);
944 const QString providerIdLower = providerId.toLower();
945 QMutexLocker locker(&d->imageProviderMutex);
946 return d->imageProviders.value(providerIdLower).data();
947}
948
955{
956 Q_D(QQmlEngine);
957 const QString providerIdLower = providerId.toLower();
958 QMutexLocker locker(&d->imageProviderMutex);
959 d->imageProviders.take(providerIdLower);
960}
961
973{
974 Q_D(const QQmlEngine);
975 if (d->baseUrl.isEmpty()) {
976 const QString currentPath = QDir::currentPath();
977 const QString rootPath = QDir::rootPath();
978 return QUrl::fromLocalFile((currentPath == rootPath) ? rootPath : (currentPath + QDir::separator()));
979 } else {
980 return d->baseUrl;
981 }
982}
983
990{
991 Q_D(QQmlEngine);
992 d->baseUrl = url;
993}
994
1002{
1003 Q_D(const QQmlEngine);
1004 return d->outputWarningsToMsgLog;
1005}
1006
1018{
1019 Q_D(QQmlEngine);
1020 d->outputWarningsToMsgLog = enabled;
1021}
1022
1023
1056{
1057 Q_D(QQmlEngine);
1058 if (auto propertyCapture = d->propertyCapture)
1059 propertyCapture->captureTranslation();
1060}
1061
1068{
1069 Q_D(const QQmlEngine);
1070 if (d->propertyCapture && !property.isConstant()) {
1071 d->propertyCapture->captureProperty(
1072 object, property.propertyIndex(),
1074 }
1075}
1076
1122template<>
1123QJSValue QQmlEngine::singletonInstance<QJSValue>(int qmlTypeId)
1124{
1125 Q_D(QQmlEngine);
1127
1128 if (!type.isValid() || !type.isSingleton())
1129 return QJSValue();
1130
1131 return d->singletonInstance<QJSValue>(type);
1132}
1133
1134
1157template<>
1158QJSValue QQmlEngine::singletonInstance<QJSValue>(QAnyStringView uri, QAnyStringView typeName)
1159{
1160 Q_D(QQmlEngine);
1161
1162 auto loadHelper = QQml::makeRefPointer<LoadHelper>(&d->typeLoader, uri);
1163
1164 auto [moduleStatus, type] = loadHelper->resolveType(typeName);
1165
1167 return {};
1168 if (!type.isValid())
1169 return {};
1170 if (!type.isSingleton())
1171 return {};
1172
1173 return d->singletonInstance<QJSValue>(type);
1174}
1175
1186{
1187 Q_D(QQmlEngine);
1188 d->translationLanguage.notify();
1189}
1190
1202{
1203 if(!object)
1204 return nullptr;
1205
1206 QQmlData *data = QQmlData::get(object);
1207 if (data && data->outerContext)
1208 return data->outerContext->asQQmlContext();
1209
1210 return nullptr;
1211}
1212
1222{
1223 if (!object || !context)
1224 return;
1225
1226 QQmlData *data = QQmlData::get(object, true);
1227 if (data->context) {
1228 qWarning("QQmlEngine::setContextForObject(): Object already has a QQmlContext");
1229 return;
1230 }
1231
1233 Q_ASSERT(data->context == nullptr);
1234 data->context = contextData.data();
1235 contextData->addOwnedObject(data);
1236}
1237
1242{
1243 if (e->type() == QEvent::LanguageChange) {
1244 retranslate();
1245 }
1246
1247 return QJSEngine::event(e);
1248}
1249
1251public:
1254
1256};
1257
1259{
1260}
1261
1263{
1264}
1265
1267{
1268 // Add a temporary sentinel at beginning of list. This will be overwritten
1269 // when the end point is inserted into the notifies further down.
1270 endpoint->prev = nullptr;
1271
1272 while (endpoint->next) {
1273 Q_ASSERT(reinterpret_cast<QQmlNotifierEndpoint *>(endpoint->next->prev) == endpoint);
1274 endpoint = endpoint->next;
1275 }
1276
1277 while (endpoint) {
1278 QQmlNotifierEndpoint *ep = (QQmlNotifierEndpoint *) endpoint->prev;
1279
1280 int index = endpoint->sourceSignal;
1281 index = qMin(index, 0xFFFF - 1);
1282
1283 endpoint->next = notifies[index];
1284 if (endpoint->next) endpoint->next->prev = &endpoint->next;
1285 endpoint->prev = &notifies[index];
1286 notifies[index] = endpoint;
1287
1288 endpoint = ep;
1289 }
1290}
1291
1293{
1294 Q_ASSERT(maximumTodoIndex >= notifiesSize);
1295
1296 if (todo) {
1297 QQmlNotifierEndpoint **old = notifies;
1298 const int reallocSize = (maximumTodoIndex + 1) * sizeof(QQmlNotifierEndpoint*);
1299 notifies = (QQmlNotifierEndpoint**)realloc(notifies, reallocSize);
1300 const int memsetSize = (maximumTodoIndex - notifiesSize + 1) *
1301 sizeof(QQmlNotifierEndpoint*);
1302 memset(notifies + notifiesSize, 0, memsetSize);
1303
1304 if (notifies != old) {
1305 for (int ii = 0; ii < notifiesSize; ++ii)
1306 if (notifies[ii])
1307 notifies[ii]->prev = &notifies[ii];
1308 }
1309
1310 notifiesSize = maximumTodoIndex + 1;
1311
1312 layout(todo);
1313 }
1314
1315 maximumTodoIndex = 0;
1316 todo = nullptr;
1317}
1318
1322{
1324 deferData->deferredIdx = objectIndex;
1325 deferData->compilationUnit = compilationUnit;
1326 deferData->context = context;
1327
1328 const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex);
1329 const QV4::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(objectIndex);
1330
1331 const QV4::CompiledData::Binding *binding = compiledObject->bindingTable();
1332 for (quint32 i = 0; i < compiledObject->nBindings; ++i, ++binding) {
1333 const QQmlPropertyData *property = propertyData.at(i);
1335 deferData->bindings.insert(property ? property->coreIndex() : -1, binding);
1336 }
1337
1338 deferredData.append(deferData);
1339}
1340
1342{
1343 auto it = deferredData.begin();
1344 while (it != deferredData.end()) {
1346 if (deferData->bindings.isEmpty()) {
1347 delete deferData;
1348 it = deferredData.erase(it);
1349 } else {
1350 ++it;
1351 }
1352 }
1353}
1354
1356{
1357 if (!notifyList) {
1358 notifyList = (NotifyList *)malloc(sizeof(NotifyList));
1362 notifyList->todo = nullptr;
1363 notifyList->notifies = nullptr;
1364 }
1365
1366 Q_ASSERT(!endpoint->isConnected());
1367
1368 index = qMin(index, 0xFFFF - 1);
1369 notifyList->connectionMask |= (1ULL << quint64(index % 64));
1370
1371 if (index < notifyList->notifiesSize) {
1372
1373 endpoint->next = notifyList->notifies[index];
1374 if (endpoint->next) endpoint->next->prev = &endpoint->next;
1375 endpoint->prev = &notifyList->notifies[index];
1376 notifyList->notifies[index] = endpoint;
1377
1378 } else {
1380
1381 endpoint->next = notifyList->todo;
1382 if (endpoint->next) endpoint->next->prev = &endpoint->next;
1383 endpoint->prev = &notifyList->todo;
1384 notifyList->todo = endpoint;
1385 }
1386}
1387
1389{
1390 if (notifyList) {
1391 while (notifyList->todo)
1393 for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
1394 while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii])
1395 ep->disconnect();
1396 }
1397 free(notifyList->notifies);
1398 free(notifyList);
1399 notifyList = nullptr;
1400 }
1401}
1402
1404{
1405 if (!extendedData) extendedData = new QQmlDataExtended;
1406 return &extendedData->attachedProperties;
1407}
1408
1410{
1415 else if (outerContext && outerContext->ownedObjects() == this)
1417
1418 QQmlAbstractBinding *binding = bindings;
1419 while (binding) {
1420 binding->setAddedToObject(false);
1421 binding = binding->nextBinding();
1422 }
1423 if (bindings && !bindings->ref.deref())
1424 delete bindings;
1425
1427
1429 deferredData.clear();
1430
1431 QQmlBoundSignal *signalHandler = signalHandlers;
1432 while (signalHandler) {
1433 if (signalHandler->isNotifying()) {
1434 // The object is being deleted during signal handler evaluation.
1435 // This will cause a crash due to invalid memory access when the
1436 // evaluation has completed.
1437 // Abort with a friendly message instead.
1438 QString locationString;
1439 QQmlBoundSignalExpression *expr = signalHandler->expression();
1440 if (expr) {
1442 if (location.sourceFile.isEmpty())
1443 location.sourceFile = QStringLiteral("<Unknown File>");
1444 locationString.append(location.sourceFile);
1445 locationString.append(QStringLiteral(":%0: ").arg(location.line));
1446 QString source = expr->expression();
1447 if (source.size() > 100) {
1448 source.truncate(96);
1449 source.append(QLatin1String(" ..."));
1450 }
1451 locationString.append(source);
1452 } else {
1453 locationString = QStringLiteral("<Unknown Location>");
1454 }
1455 qFatal("Object %p destroyed while one of its QML signal handlers is in progress.\n"
1456 "Most likely the object was deleted synchronously (use QObject::deleteLater() "
1457 "instead), or the application is running a nested event loop.\n"
1458 "This behavior is NOT supported!\n"
1459 "%s", object, qPrintable(locationString));
1460 }
1461
1462 QQmlBoundSignal *next = signalHandler->m_nextSignal;
1463 signalHandler->m_prevSignal = nullptr;
1464 signalHandler->m_nextSignal = nullptr;
1465 delete signalHandler;
1466 signalHandler = next;
1467 }
1468
1470 free(bindingBits);
1471
1472 if (propertyCache)
1474
1475 ownContext.reset();
1476
1477 while (guards) {
1478 auto *guard = guards;
1479 guard->setObject(nullptr);
1480 if (guard->objectDestroyed)
1481 guard->objectDestroyed(guard);
1482 }
1483
1485
1486 if (extendedData)
1487 delete extendedData;
1488
1489 // Dispose the handle.
1490 jsWrapper.clear();
1491
1492 if (ownMemory)
1493 delete this;
1494 else
1495 this->~QQmlData();
1496}
1497
1498QQmlData::BindingBitsType *QQmlData::growBits(QObject *obj, int bit)
1499{
1502 Q_ASSERT(bit < 2 * props);
1503 Q_UNUSED(bit); // .. for Q_NO_DEBUG mode when the assert above expands to empty
1504
1505 uint arraySize = (2 * static_cast<uint>(props) + BitsPerType - 1) / BitsPerType;
1506 Q_ASSERT(arraySize > 1);
1507 Q_ASSERT(arraySize <= 0xffff); // max for bindingBitsArraySize
1508
1509 BindingBitsType *newBits = static_cast<BindingBitsType *>(malloc(arraySize*sizeof(BindingBitsType)));
1510 memcpy(newBits, bits, bindingBitsArraySize * sizeof(BindingBitsType));
1511 memset(newBits + bindingBitsArraySize, 0, sizeof(BindingBitsType) * (arraySize - bindingBitsArraySize));
1512
1514 free(bits);
1515 bindingBits = newBits;
1516 bits = newBits;
1517 bindingBitsArraySize = arraySize;
1518 return bits;
1519}
1520
1521QQmlData *QQmlData::createQQmlData(QObjectPrivate *priv)
1522{
1523 Q_ASSERT(priv);
1524 Q_ASSERT(!priv->isDeletingChildren);
1525 priv->declarativeData = new QQmlData(OwnsMemory);
1526 return static_cast<QQmlData *>(priv->declarativeData);
1527}
1528
1529QQmlPropertyCache::ConstPtr QQmlData::createPropertyCache(QObject *object)
1530{
1531 QQmlData *ddata = QQmlData::get(object, /*create*/true);
1533 return ddata->propertyCache;
1534}
1535
1537{
1538 Q_Q(QQmlEngine);
1539 emit q->quit();
1540 if (q->receivers(SIGNAL(quit())) == 0) {
1541 qWarning("Signal QQmlEngine::quit() emitted, but no receivers connected to handle it.");
1542 }
1543}
1544
1546{
1547 Q_Q(QQmlEngine);
1548 if (q->receivers(SIGNAL(exit(int))) == 0)
1549 qWarning("Signal QQmlEngine::exit() emitted, but no receivers connected to handle it.");
1550 emit q->exit(retCode);
1551}
1552
1553static void dumpwarning(const QQmlError &error)
1554{
1555 switch (error.messageType()) {
1556 case QtDebugMsg:
1557 QMessageLogger(error.url().toString().toLatin1().constData(),
1558 error.line(), nullptr).debug().noquote().nospace()
1559 << error.toString();
1560 break;
1561 case QtInfoMsg:
1562 QMessageLogger(error.url().toString().toLatin1().constData(),
1563 error.line(), nullptr).info().noquote().nospace()
1564 << error.toString();
1565 break;
1566 case QtWarningMsg:
1567 case QtFatalMsg: // fatal does not support streaming, and furthermore, is actually fatal. Probably not desirable for QML.
1568 QMessageLogger(error.url().toString().toLatin1().constData(),
1569 error.line(), nullptr).warning().noquote().nospace()
1570 << error.toString();
1571 break;
1572 case QtCriticalMsg:
1573 QMessageLogger(error.url().toString().toLatin1().constData(),
1574 error.line(), nullptr).critical().noquote().nospace()
1575 << error.toString();
1576 break;
1577 }
1578}
1579
1580static void dumpwarning(const QList<QQmlError> &errors)
1581{
1582 for (int ii = 0; ii < errors.size(); ++ii)
1583 dumpwarning(errors.at(ii));
1584}
1585
1587{
1588 Q_Q(QQmlEngine);
1589 emit q->warnings(QList<QQmlError>({error}));
1590 if (outputWarningsToMsgLog)
1592}
1593
1595{
1596 Q_Q(QQmlEngine);
1597 emit q->warnings(errors);
1598 if (outputWarningsToMsgLog)
1599 dumpwarning(errors);
1600}
1601
1603{
1604 if (engine)
1606 else
1608}
1609
1611{
1612 if (engine)
1614 else
1616}
1617
1619{
1620 if (engine)
1621 engine->warning(error);
1622 else
1624}
1625
1627{
1628 if (engine)
1629 engine->warning(error);
1630 else
1632}
1633
1635 const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages)
1636{
1637 QList<QQmlError> errors;
1638 for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
1639 if (m.isWarning()) {
1640 qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message));
1641 continue;
1642 }
1643
1645 error.setUrl(QUrl(fileName));
1646 error.setDescription(m.message);
1647 error.setLine(qmlConvertSourceCoordinate<quint32, int>(m.loc.startLine));
1648 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(m.loc.startColumn));
1649 errors << error;
1650 }
1651 return errors;
1652}
1653
1654void QQmlEnginePrivate::cleanupScarceResources()
1655{
1656 // iterate through the list and release them all.
1657 // note that the actual SRD is owned by the JS engine,
1658 // so we cannot delete the SRD; but we can free the
1659 // memory used by the variant in the SRD.
1660 QV4::ExecutionEngine *engine = v4engine();
1661 while (QV4::ExecutionEngine::ScarceResourceData *sr = engine->scarceResources.first()) {
1662 sr->data = QVariant();
1663 engine->scarceResources.remove(sr);
1664 }
1665}
1666
1684{
1685 Q_D(QQmlEngine);
1686 d->importDatabase.addImportPath(path);
1687}
1688
1705{
1706 Q_D(const QQmlEngine);
1707 return d->importDatabase.importPathList();
1708}
1709
1723{
1724 Q_D(QQmlEngine);
1725 d->importDatabase.setImportPathList(paths);
1726}
1727
1728
1741{
1742 Q_D(QQmlEngine);
1743 d->importDatabase.addPluginPath(path);
1744}
1745
1756{
1757 Q_D(const QQmlEngine);
1758 return d->importDatabase.pluginPathList();
1759}
1760
1772{
1773 Q_D(QQmlEngine);
1774 d->importDatabase.setPluginPathList(paths);
1775}
1776
1777#if QT_CONFIG(library)
1778#if QT_DEPRECATED_SINCE(6, 4)
1793bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
1794{
1795 Q_D(QQmlEngine);
1797 QQmlPluginImporter importer(
1798 uri, QTypeRevision(), &d->importDatabase, &qmldir, &d->typeLoader, errors);
1799 return importer.importDynamicPlugin(filePath, uri, false).isValid();
1800}
1801#endif
1802#endif
1803
1830{
1831 Q_D(QQmlEngine);
1832 if (dir == d->offlineStoragePath)
1833 return;
1834 d->offlineStoragePath = dir;
1835 Q_EMIT offlineStoragePathChanged();
1836}
1837
1839{
1840 Q_D(const QQmlEngine);
1841
1842 if (d->offlineStoragePath.isEmpty()) {
1844 QQmlEnginePrivate *e = const_cast<QQmlEnginePrivate *>(d);
1845 if (!dataLocation.isEmpty()) {
1846 e->offlineStoragePath = dataLocation.replace(QLatin1Char('/'), QDir::separator())
1847 + QDir::separator() + QLatin1String("QML")
1848 + QDir::separator() + QLatin1String("OfflineStorage");
1849 Q_EMIT e->q_func()->offlineStoragePathChanged();
1850 }
1851 }
1852
1853 return d->offlineStoragePath;
1854}
1855
1864{
1865 Q_D(const QQmlEngine);
1867 md5.addData(databaseName.toUtf8());
1868 return d->offlineStorageDatabaseDirectory() + QLatin1String(md5.result().toHex());
1869}
1870
1872{
1873 Q_Q(const QQmlEngine);
1874 return q->offlineStoragePath() + QDir::separator() + QLatin1String("Databases") + QDir::separator();
1875}
1876
1877template<>
1878QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type)
1879{
1880 Q_Q(QQmlEngine);
1881
1882 QJSValue value = singletonInstances.value(type);
1883 if (!value.isUndefined()) {
1884 return value;
1885 }
1886
1887 QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo();
1888 Q_ASSERT(siinfo != nullptr);
1889
1890 if (siinfo->scriptCallback) {
1891 value = siinfo->scriptCallback(q, q);
1892 if (value.isQObject()) {
1893 QObject *o = value.toQObject();
1894 // even though the object is defined in C++, qmlContext(obj) and qmlEngine(obj)
1895 // should behave identically to QML singleton types.
1896 q->setContextForObject(o, new QQmlContext(q->rootContext(), q));
1897 }
1898 singletonInstances.convertAndInsert(v4engine(), type, &value);
1899
1900 } else if (siinfo->qobjectCallback) {
1901 QObject *o = siinfo->qobjectCallback(q, q);
1902 if (!o) {
1904 error.setMessageType(QtMsgType::QtCriticalMsg);
1905 error.setDescription(QString::asprintf("qmlRegisterSingletonType(): \"%s\" is not available because the callback function returns a null pointer.",
1906 qPrintable(QString::fromUtf8(type.typeName()))));
1907 warning(error);
1908 } else {
1909 type.createProxy(o);
1910
1911 // if this object can use a property cache, create it now
1913
1914 // even though the object is defined in C++, qmlContext(obj) and qmlEngine(obj)
1915 // should behave identically to QML singleton types. You can, however, manually
1916 // assign a context; and clearSingletons() retains the contexts, in which case
1917 // we don't want to see warnings about the object already having a context.
1918 QQmlData *data = QQmlData::get(o, true);
1919 if (!data->context) {
1920 auto contextData = QQmlContextData::get(new QQmlContext(q->rootContext(), q));
1921 data->context = contextData.data();
1922 contextData->addOwnedObject(data);
1923 }
1924 }
1925
1926 value = q->newQObject(o);
1927 singletonInstances.convertAndInsert(v4engine(), type, &value);
1928 } else if (!siinfo->url.isEmpty()) {
1930 if (component.isError()) {
1931 warning(component.errors());
1932 v4engine()->throwError(QLatin1String("Due to the preceding error(s), Singleton \"%1\" could not be loaded.").arg(QString::fromUtf8(type.typeName())));
1933
1935 }
1936 QObject *o = component.beginCreate(q->rootContext());
1937 value = q->newQObject(o);
1938 singletonInstances.convertAndInsert(v4engine(), type, &value);
1939 component.completeCreate();
1940 }
1941
1942 return value;
1943}
1944
1946{
1947 return typeLoader.isTypeLoaded(url);
1948}
1949
1951{
1952 return typeLoader.isScriptLoaded(url);
1953}
1954
1956 QObject *thisObject, int argc, void **args,
1958{
1959 const auto unit = compilationUnitFromUrl(url);
1960 if (!unit)
1961 return;
1962 executeRuntimeFunction(unit, functionIndex, thisObject, argc, args, types);
1963}
1964
1966 qsizetype functionIndex, QObject *thisObject,
1967 int argc, void **args, QMetaType *types)
1968{
1969 Q_ASSERT(unit);
1970 Q_ASSERT((functionIndex >= 0) && (functionIndex < unit->runtimeFunctions.size()));
1971 Q_ASSERT(thisObject);
1972
1973 QQmlData *ddata = QQmlData::get(thisObject);
1974 Q_ASSERT(ddata && ddata->outerContext);
1975
1976 QV4::Function *function = unit->runtimeFunctions[functionIndex];
1978 Q_ASSERT(function->compiledFunction);
1979
1980 QV4::ExecutionEngine *v4 = v4engine();
1981
1982 // NB: always use scriptContext() by default as this method ignores whether
1983 // there's already a stack frame (except when dealing with closures). the
1984 // method is called from C++ (through QQmlEngine::executeRuntimeFunction())
1985 // and thus the caller must ensure correct setup
1986 QV4::Scope scope(v4);
1988 QV4::Scoped<QV4::ExecutionContext> callContext(scope,
1989 QV4::QmlContext::create(ctx, ddata->outerContext, thisObject));
1990
1991 if (auto nested = function->nestedFunction()) {
1992 // if a nested function is already known, call the closure directly
1993 function = nested;
1994 } else if (function->isClosureWrapper()) {
1995 // if there is a nested function, but we don't know it, we need to call
1996 // an outer function first and then the inner function. we fetch the
1997 // return value of a function call (that is a closure) by calling a
1998 // different version of ExecutionEngine::callInContext() that returns a
1999 // QV4::ReturnedValue with no arguments since they are not needed by the
2000 // outer function anyhow
2002 v4->callInContext(function, thisObject, callContext, 0, nullptr));
2003 Q_ASSERT(result->function());
2004 Q_ASSERT(result->function()->compilationUnit == function->compilationUnit);
2005
2006 // overwrite the function and its context
2007 function = result->function();
2008 callContext = QV4::Scoped<QV4::ExecutionContext>(scope, result->scope());
2009 }
2010
2011 v4->callInContext(function, thisObject, callContext, argc, args, types);
2012}
2013
2015{
2016 auto unit = typeLoader.getType(url)->compilationUnit();
2017 if (!unit)
2018 return nullptr;
2019 if (!unit->engine)
2020 unit->linkToEngine(v4engine());
2021 return unit;
2022}
2023
2026 const QQmlRefPointer<QQmlContextData> &parentContext,
2027 int subComponentIndex, bool isComponentRoot)
2028{
2029 Q_ASSERT(unit);
2030
2033 context->setInternal(true);
2034 context->setImports(unit->typeNameCache);
2035 context->initFromTypeCompilationUnit(unit, subComponentIndex);
2036
2037 if (isComponentRoot && unit->dependentScripts.size()) {
2038 QV4::ExecutionEngine *v4 = v4engine();
2039 Q_ASSERT(v4);
2040 QV4::Scope scope(v4);
2041
2042 QV4::ScopedObject scripts(scope, v4->newArrayObject(unit->dependentScripts.size()));
2044 QV4::ScopedValue v(scope);
2045 for (int i = 0; i < unit->dependentScripts.size(); ++i) {
2046 QQmlRefPointer<QQmlScriptData> s = unit->dependentScripts.at(i);
2047 scripts->put(i, (v = s->scriptValueForContext(context)));
2048 }
2049 }
2050
2051 return context;
2052}
2053
2054#if defined(Q_OS_WIN)
2055// Normalize a file name using Shell API. As opposed to converting it
2056// to a short 8.3 name and back, this also works for drives where 8.3 notation
2057// is disabled (see 8dot3name options of fsutil.exe).
2058static inline QString shellNormalizeFileName(const QString &name)
2059{
2060 const QString nativeSeparatorName(QDir::toNativeSeparators(name));
2061 const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(nativeSeparatorName.utf16());
2062// The correct declaration of the SHGetPathFromIDList symbol is
2063// being used in mingw-w64 as of r6215, which is a v3 snapshot.
2064#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
2065 ITEMIDLIST *file;
2066 if (FAILED(SHParseDisplayName(nameC, NULL, reinterpret_cast<LPITEMIDLIST>(&file), 0, NULL)))
2067 return name;
2068#else
2069 PIDLIST_ABSOLUTE file;
2070 if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL)))
2071 return name;
2072#endif
2073 TCHAR buffer[MAX_PATH];
2074 bool gotPath = SHGetPathFromIDList(file, buffer);
2075 ILFree(file);
2076
2077 if (!gotPath)
2078 return name;
2079
2080 QString canonicalName = QString::fromWCharArray(buffer);
2081 // Upper case drive letter
2082 if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':'))
2083 canonicalName[0] = canonicalName.at(0).toUpper();
2084 return QDir::cleanPath(canonicalName);
2085}
2086#endif // Q_OS_WIN
2087
2088bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */)
2089{
2090#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
2092 const QString absolute = info.absoluteFilePath();
2093
2094#if defined(Q_OS_DARWIN)
2095 const QString canonical = info.canonicalFilePath();
2096#elif defined(Q_OS_WIN)
2097 // No difference if the path is qrc based
2098 if (absolute[0] == QLatin1Char(':'))
2099 return true;
2100 const QString canonical = shellNormalizeFileName(absolute);
2101#endif
2102
2103 const int absoluteLength = absolute.length();
2104 const int canonicalLength = canonical.length();
2105
2106 int length = qMin(absoluteLength, canonicalLength);
2107 if (lengthIn >= 0) {
2108 length = qMin(lengthIn, length);
2109 } else {
2110 // No length given: Limit to file name. Do not trigger
2111 // on drive letters or folder names.
2112 int lastSlash = absolute.lastIndexOf(QLatin1Char('/'));
2113 if (lastSlash < 0)
2114 lastSlash = absolute.lastIndexOf(QLatin1Char('\\'));
2115 if (lastSlash >= 0) {
2116 const int fileNameLength = absoluteLength - 1 - lastSlash;
2117 length = qMin(length, fileNameLength);
2118 }
2119 }
2120
2121 for (int ii = 0; ii < length; ++ii) {
2122 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2123 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2124
2125 if (a.toLower() != c.toLower())
2126 return true;
2127 if (a != c)
2128 return false;
2129 }
2130#else
2131 Q_UNUSED(lengthIn);
2133#endif
2134 return true;
2135}
2136
2162
2165 , m_uri(uri.toString())
2166
2167{
2168 auto import = std::make_shared<PendingImport>();
2169 import->uri = m_uri;
2170 QList<QQmlError> errorList;
2171 if (!Blob::addImport(import, &errorList)) {
2172 qCDebug(lcQmlImport) << "LoadHelper: Errors loading " << m_uri << errorList;
2173 m_uri.clear(); // reset m_uri to remember the failure
2174 }
2175}
2176
2178{
2179 QQmlType type;
2180 if (!couldFindModule())
2183 if (module) {
2184 type = module->type(typeName.toString(), {});
2185 if (type.isValid())
2187 }
2188 // The module exists (see check above), but there is no QQmlTypeModule
2189 // ==> pure QML module, attempt resolveType
2190 QTypeRevision versionReturn;
2192 QQmlImportNamespace *ns_return = nullptr;
2193 m_importCache->resolveType(typeName.toString(), &type, &versionReturn,
2194 &ns_return,
2195 &errors);
2197}
2198
2199bool LoadHelper::couldFindModule() const
2200{
2201 if (m_uri.isEmpty())
2202 return false;
2203 for (const auto &import: std::as_const(m_unresolvedImports))
2204 if (import->priority == 0) // compare QQmlTypeData::allDependenciesDone
2205 return false;
2206 return true;
2207}
2208
2210
2211#include "moc_qqmlengine_p.cpp"
2212
2213#include "moc_qqmlengine.cpp"
2214
static bool(* isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int)
Definition qobject_p.h:69
static int(* receivers)(QAbstractDeclarativeData *, const QObject *, int)
Definition qobject_p.h:68
static void(* destroyed)(QAbstractDeclarativeData *, QObject *)
Definition qobject_p.h:66
static void(* signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **)
Definition qobject_p.h:67
\inmodule QtCore
Type loadRelaxed() const noexcept
\inmodule QtCore
Definition qbytearray.h:57
QByteArray toHex(char separator='\0') const
Returns a hex encoded copy of the byte array.
\inmodule QtCore
Definition qchar.h:48
QChar toUpper() const noexcept
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition qchar.h:449
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
void addData(QByteArrayView data) noexcept
Adds the characters in bytes to the cryptographic hash.
QByteArray result() const
Returns the final hash value.
static QChar separator()
Returns the native directory separator: "/" under Unix and "\\" under Windows.
Definition qdir.h:206
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2395
static QString toNativeSeparators(const QString &pathName)
Definition qdir.cpp:929
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2051
static QString rootPath()
Returns the absolute path of the root directory.
Definition qdir.cpp:2156
\inmodule QtCore
Definition qcoreevent.h:45
@ LanguageChange
Definition qcoreevent.h:123
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
QString absoluteFilePath() const
Returns an absolute path including the file name.
QString canonicalFilePath() const
Returns the canonical path including the file name, i.e.
\inmodule QtCore
Definition qhash.h:818
T value(const Key &key) const noexcept
Definition qhash.h:1044
static void addToDebugServer(QJSEngine *q)
static void removeFromDebugServer(QJSEngine *q)
The QJSEngine class provides an environment for evaluating JavaScript code.
Definition qjsengine.h:26
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
@ UndefinedValue
Definition qjsvalue.h:35
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void clear()
Definition qlist.h:417
\inmodule QtCore
Definition qlogging.h:68
void void Q_DECL_COLD_FUNCTION void warning(const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(2
Logs a warning message specified with format msg.
Definition qlogging.cpp:648
void void Q_DECL_COLD_FUNCTION void Q_DECL_COLD_FUNCTION void critical(const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(2
Logs a critical message specified with format msg.
Definition qlogging.cpp:764
void void void info(const QLoggingCategory &cat, const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(3
Logs an informational message specified with format msg for the context cat.
Definition qlogging.cpp:548
void debug(const char *msg,...) const Q_ATTRIBUTE_FORMAT_PRINTF(2
Logs a debug message specified with format msg.
Definition qlogging.cpp:385
\inmodule QtCore
Definition qmetaobject.h:18
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:320
static QMetaType fromName(QByteArrayView name)
Returns a QMetaType matching typeName.
\inmodule QtCore
Definition qmutex.h:317
The QNetworkAccessManager class allows the application to send network requests and receive replies.
QObject * parent
Definition qobject.h:61
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:153
QAtomicPointer< QThreadData > threadData
Definition qobject_p.h:202
\inmodule QtCore
Definition qobject.h:90
void moveToThread(QThread *thread)
Changes the thread affinity for this object and its children.
Definition qobject.cpp:1606
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
\inmodule QtCore
Definition qpointer.h:18
QQmlAbstractBinding * nextBinding() const
virtual void setEnabled(bool e, QQmlPropertyData::WriteFlags f=QQmlPropertyData::DontRemoveBinding)=0
DataType
Specifies where URL interception is taking place.
QQmlBoundSignalExpression * expression() const
Returns the signal expression.
The QQmlComponent class encapsulates a QML component definition.
void setOwnedObjects(QQmlData *ownedObjects)
void setInternal(bool isInternal)
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
QQmlData * ownedObjects() const
void initFromTypeCompilationUnit(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &unit, int subComponentIndex)
void setImportedScripts(const QV4::PersistentValue &scripts)
void setImports(const QQmlRefPointer< QQmlTypeNameCache > &imports)
static QQmlRefPointer< QQmlContextData > createRefCounted(const QQmlRefPointer< QQmlContextData > &parent)
static QQmlContextPrivate * get(QQmlContext *context)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
QList< QQmlError > errors() const
Return the errors on this blob.
Type type() const
Returns the type provided to the constructor.
QHash< QQmlAttachedPropertiesFunc, QObject * > attachedProperties
static void init()
Definition qqmldata_p.h:63
QHash< QQmlAttachedPropertiesFunc, QObject * > * attachedProperties() const
static void flushPendingBinding(QObject *object, int coreIndex)
Definition qqmldata_p.h:393
static void markAsDeleted(QObject *)
QV4::WeakValue jsWrapper
Definition qqmldata_p.h:193
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
Definition qqmldata_p.h:252
QQmlNotifierEndpoint * notify(int index)
Definition qqmldata_p.h:321
QVector< DeferredData * > deferredData
Definition qqmldata_p.h:187
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
Definition qqmldata_p.h:186
void addNotify(int index, QQmlNotifierEndpoint *)
@ InlineBindingArraySize
Definition qqmldata_p.h:119
QQmlPropertyCache::ConstPtr propertyCache
Definition qqmldata_p.h:195
QQmlData(Ownership ownership)
bool signalHasEndpoint(int index) const
Definition qqmldata_p.h:344
QQmlRefPointer< QQmlContextData > ownContext
Definition qqmldata_p.h:150
void disconnectNotifiers()
void releaseDeferredData()
BindingBitsType bindingBitsValue[InlineBindingArraySize]
Definition qqmldata_p.h:123
static void destroyed(QAbstractDeclarativeData *, QObject *)
QQmlBoundSignal * signalHandlers
Definition qqmldata_p.h:153
QQmlContextData * context
Definition qqmldata_p.h:147
QQmlData ** prevContextObject
Definition qqmldata_p.h:158
BindingBitsType * bindingBits
Definition qqmldata_p.h:122
quint32 bindingBitsArraySize
Definition qqmldata_p.h:115
void clearPendingBindingBit(int)
Definition qqmldata_p.h:386
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
void deferData(int objectIndex, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &, const QQmlRefPointer< QQmlContextData > &)
int endpointCount(int index)
QQmlGuardImpl * guards
Definition qqmldata_p.h:197
quint32 ownMemory
Definition qqmldata_p.h:87
QQmlData * nextContextObject
Definition qqmldata_p.h:157
static void setQueuedForDeletion(QObject *)
quintptr BindingBitsType
Definition qqmldata_p.h:116
QQmlContextData * outerContext
Definition qqmldata_p.h:149
NotifyList * notifyList
Definition qqmldata_p.h:138
QQmlAbstractBinding * bindings
Definition qqmldata_p.h:152
static void activateDesignerMode()
QHash< QString, QSharedPointer< QQmlImageProviderBase > > imageProviders
QMutex networkAccessManagerMutex
QSharedPointer< QQmlImageProviderBase > imageProvider(const QString &providerId) const
QV4::ExecutableCompilationUnit * compilationUnitFromUrl(const QUrl &url)
static std::atomic< bool > qml_debugging_enabled
\qmltype QtObject \instantiates QObject \inqmlmodule QtQml
void sendExit(int retCode=0)
void warning(const QQmlError &)
void executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, QObject *thisObject, int argc=0, void **args=nullptr, QMetaType *types=nullptr)
static bool baseModulesUninitialized
static QList< QQmlError > qmlErrorFromDiagnostics(const QString &fileName, const QList< QQmlJS::DiagnosticMessage > &diagnosticMessages)
~QQmlEnginePrivate() override
bool isTypeLoaded(const QUrl &url) const
static QQmlEnginePrivate * get(QQmlEngine *e)
QQmlContext * rootContext
QString offlineStorageDatabaseDirectory() const
bool isScriptLoaded(const QUrl &url) const
QQmlIncubationController * incubationController
static const quintptr profiler
QRecursiveMutex imageProviderMutex
static bool designerMode()
QQmlRefPointer< QQmlContextData > createInternalContext(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &unit, const QQmlRefPointer< QQmlContextData > &parentContext, int subComponentIndex, bool isComponentRoot)
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
static QQmlContext * contextForObject(const QObject *)
Returns the QQmlContext for the object, or nullptr if no context has been set.
void addPluginPath(const QString &dir)
Adds path as a directory where the engine searches for native plugins for imported modules (reference...
void removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
Remove a urlInterceptor that was previously added using \l addUrlInterceptor.
QQmlEngine(QObject *p=nullptr)
Create a new QQmlEngine with the given parent.
void setImportPathList(const QStringList &paths)
Sets paths as the list of directories where the engine searches for installed modules in a URL-based ...
QStringList importPathList() const
Returns the list of directories where the engine searches for installed modules in a URL-based direct...
QList< QQmlAbstractUrlInterceptor * > urlInterceptors() const
Returns the list of currently active URL interceptors.
bool outputWarningsToStandardError() const
Returns true if warning messages will be output to stderr in addition to being emitted by the warning...
static void setContextForObject(QObject *, QQmlContext *)
Sets the QQmlContext for the object to context.
void addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor)
Adds a urlInterceptor to be used when resolving URLs in QML.
void setOfflineStoragePath(const QString &dir)
QQmlImageProviderBase * imageProvider(const QString &id) const
Returns the image provider set for providerId if found; otherwise returns \nullptr.
QQmlContext * rootContext() const
Returns the engine's root context.
QUrl baseUrl() const
Return the base URL for this engine.
void captureProperty(QObject *object, const QMetaProperty &property) const
QString offlineStoragePath
the directory for storing offline user data
Definition qqmlengine.h:58
bool event(QEvent *) override
\reimp
void setOutputWarningsToStandardError(bool)
Set whether warning messages will be output to stderr to enabled.
void trimComponentCache()
Trims the engine's internal component cache.
QStringList pluginPathList() const
Returns the list of directories where the engine searches for native plugins for imported modules (re...
void setPluginPathList(const QStringList &paths)
Sets the list of directories where the engine searches for native plugins for imported modules (refer...
void clearSingletons()
Clears all singletons the engine owns.
void setBaseUrl(const QUrl &)
Set the base URL for this engine to url.
void addImportPath(const QString &dir)
Adds path as a directory where the engine searches for installed modules in a URL-based directory str...
void markCurrentFunctionAsTranslationBinding()
QString offlineStorageDatabaseFilePath(const QString &databaseName) const
Returns the file path where a \l{QtQuick.LocalStorage}{Local Storage} database with the identifier da...
void clearComponentCache()
Clears the engine's internal component cache.
void addImageProvider(const QString &id, QQmlImageProviderBase *)
Sets the provider to use for images requested via the image: url scheme, with host providerId.
QUrl interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const
Run the current URL interceptors on the given url of the given type and return the result.
void retranslate()
Refreshes all binding expressions that use strings marked for translation.
~QQmlEngine() override
Destroys the QQmlEngine.
void removeImageProvider(const QString &id)
Removes the image provider for providerId.
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
void setObject(QObject *g)
The QQmlImageProviderBase class is used to register image providers in the QML engine.
Definition qqmlengine.h:18
virtual ~QQmlImageProviderBase()
bool resolveType(const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList< QQmlError > *errors=nullptr, QQmlType::RegistrationType registrationType=QQmlType::AnyRegistrationType, bool *typeRecursionDetected=nullptr) const
virtual QQmlSourceLocation sourceLocation() const
int propertyCount() const
static QQmlType qmlTypeById(int qmlTypeId)
Returns the type (if any) that corresponds to qmlTypeId.
static void registerTypeAlias(int typeId, const QString &name)
static QQmlTypeModule * typeModule(const QString &uri, QTypeRevision version)
static QQmlPropertyCache::ConstPtr propertyCache(QObject *object, QTypeRevision version=QTypeRevision())
Returns a QQmlPropertyCache for obj if one is available.
static void freeUnusedTypesAndCaches()
bool isNotifying() const
Returns true if a notify is in progress.
T * data() const
void reset(T *t=nullptr)
int qt_metacall(QMetaObject::Call, int methodIndex, void **a) override
QPointer< QObject > target
QVector< PendingImportPtr > m_unresolvedImports
QQmlRefPointer< QQmlImports > m_importCache
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
QQmlType type(const QHashedStringRef &name, QTypeRevision version) const
\inmodule QtCore
static QString writableLocation(StandardLocation type)
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.h:279
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3794
void truncate(qsizetype pos)
Truncates the string at the given position index.
Definition qstring.cpp:6159
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString toLower() const &
Definition qstring.h:368
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1164
QString & append(QChar c)
Definition qstring.cpp:3227
QByteArray toUtf8() const &
Definition qstring.h:563
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition qstring.cpp:7005
qsizetype length() const
Returns the number of characters in this string.
Definition qstring.h:187
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
Definition qthread.h:154
\inmodule QtCore
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given majorVersion and minorVersion, both of which need to be a val...
static constexpr QTypeRevision zero()
Produces a QTypeRevision with major and minor version {0}.
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3354
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition qurl.cpp:1888
const CompiledObject * objectAt(int index) const
QVector< BindingPropertyData > bindingPropertyDataPerObject
QV4::Function * linkToEngine(QV4::ExecutionEngine *engine)
bool isEmpty() const
void push_back(const T &t)
\inmodule QtCore
Definition qvariant.h:64
EGLContext ctx
#define this
Definition dialogs.cpp:9
qDeleteAll(list.begin(), list.end())
double e
QSet< QString >::iterator it
auto signalIndex
short next
Definition keywords.cpp:445
void Q_QML_EXPORT qdeclarativeelement_destructor(QObject *)
int Q_QML_EXPORT qmlregister(RegistrationType, void *)
Definition qqml.cpp:483
Combined button and popup list for selecting options.
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
@ QtCriticalMsg
Definition qlogging.h:32
@ QtInfoMsg
Definition qlogging.h:34
@ QtWarningMsg
Definition qlogging.h:31
@ QtFatalMsg
Definition qlogging.h:33
@ QtDebugMsg
Definition qlogging.h:30
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
#define qCDebug(category,...)
static const QMetaObjectPrivate * priv(const uint *data)
const char * typeName
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLint location
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLsizei GLenum GLenum * types
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLuint object
[3]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLuint buffer
GLenum type
GLsizei const GLuint * paths
GLenum target
GLenum GLuint GLsizei const GLenum * props
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLsizei GLsizei GLchar * source
GLhandleARB obj
[2]
const GLubyte * c
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
static qreal component(const QPointF &point, unsigned int i)
int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
Definition qqml.cpp:337
static void dumpwarning(const QQmlError &error)
void hasJsOwnershipIndicator(QQmlGuardImpl *)
bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn)
Returns true if the case of fileName is equivalent to the file case of fileName on disk,...
int qmlRegisterType< void >(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
const QLoggingCategory & lcQmlImport()
int qmlConvertSourceCoordinate< quint32, int >(quint32 n)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define MAX_PATH
SSL_CTX int(*) void arg)
#define qPrintable(string)
Definition qstring.h:1391
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define sp
#define Q_EMIT
#define emit
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:45
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
#define enabled
const char property[13]
Definition qwizard.cpp:101
if(qFloatDistance(a, b)<(1<< 7))
[0]
QFile file
[0]
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]
QVBoxLayout * layout
QString dir
[11]
QItemEditorFactory * factory
QLayoutItem * child
[0]
QJSValueList args
QJSEngine engine
[0]
LoadHelper(QQmlTypeLoader *loader, QAnyStringView uri)
ResolveTypeResult resolveType(QAnyStringView typeName)
\inmodule QtCore \reentrant
Definition qchar.h:17
static Q_CORE_EXPORT QMetaMethod signal(const QMetaObject *m, int signal_index)
static Q_CORE_EXPORT int signalIndex(const QMetaMethod &m)
QQmlNotifierEndpoint ** notifies
Definition qqmldata_p.h:133
QQmlNotifierEndpoint * todo
Definition qqmldata_p.h:132
std::function< QObject *(QQmlEngine *, QJSEngine *)> qobjectCallback
Definition qqmltype_p.h:125
std::function< QJSValue(QQmlEngine *, QJSEngine *)> scriptCallback
Definition qqmltype_p.h:124
bool hasFlag(Flag flag) const
const Binding * bindingTable() const
ExecutionContext * scriptContext() const
Heap::ArrayObject * newArrayObject(int count=0)
void callInContext(QV4::Function *function, QObject *self, QV4::ExecutionContext *ctxt, int argc, void **args, QMetaType *types)
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent