blob: e639190fdad092e1f6bc3cfd1fa134d21a924afc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2019 Luxoft Sweden AB
// Copyright (C) 2018 Pelagicore AG
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDir>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlInfo>
#include <private/qqmlmetatype_p.h>
#include <private/qv4engine_p.h>
#include <private/qqmlcontext_p.h>
#include <private/qqmlcontextdata_p.h>
#include "logging.h"
#include "utilities.h"
#include "qml-utilities.h"
using namespace Qt::StringLiterals;
QT_BEGIN_NAMESPACE_AM
QVariant convertFromJSVariant(const QVariant &variant)
{
int type = variant.userType();
if (type == qMetaTypeId<QJSValue>()) {
return convertFromJSVariant(variant.value<QJSValue>().toVariant());
} else if (type == QMetaType::QVariant) {
// got a matryoshka variant
return convertFromJSVariant(variant.value<QVariant>());
} else if (type == QMetaType::QVariantList) {
QVariantList outList;
QVariantList inList = variant.toList();
for (auto it = inList.cbegin(); it != inList.cend(); ++it)
outList.append(convertFromJSVariant(*it));
return outList;
} else if (type == QMetaType::QVariantMap) {
QVariantMap outMap;
QVariantMap inMap = variant.toMap();
for (auto it = inMap.cbegin(); it != inMap.cend(); ++it)
outMap.insert(it.key(), convertFromJSVariant(it.value()));
return outMap;
} else {
return variant;
}
}
static const char *qmlContextTag = "_q_am_context_tag";
QVariant findTaggedQmlContext(QObject *object)
{
auto findTag = [](QQmlContext *context) -> QVariant {
while (context) {
auto v = context->property(qmlContextTag);
if (v.isValid())
return v;
context = context->parentContext();
}
return { };
};
// check the context the object lives in
QVariant v = findTag(QQmlEngine::contextForObject(object));
if (!v.isValid()) {
// if this didn't work out, check out the calling context
if (QQmlEngine *engine = qmlEngine(object)) {
if (QV4::ExecutionEngine *v4 = engine->handle()) {
if (QQmlContextData *callingContext = v4->callingQmlContext().data())
v = findTag(callingContext->asQQmlContext());
}
}
}
return v;
}
bool tagQmlContext(QQmlContext *context, const QVariant &value)
{
if (!context || !value.isValid())
return false;
return !context->setProperty(qmlContextTag, value);
}
bool ensureCurrentContextIsSystemUI(QObject *object)
{
static const char *error = "This object can not be used in an Application context";
if (findTaggedQmlContext(object).isValid()) {
qmlWarning(object) << error;
Q_ASSERT_X(false, object ? object->metaObject()->className() : "", error);
return false;
}
return true;
}
bool ensureCurrentContextIsInProcessApplication(QObject *object)
{
static const char *error = "This object can not be used in the SystemUI context";
if (!findTaggedQmlContext(object).isValid()) {
qmlWarning(object) << error;
Q_ASSERT_X(false, object ? object->metaObject()->className() : "", error);
return false;
}
return true;
}
QT_END_NAMESPACE_AM
|