Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqmlpreviewservice.cpp
Go to the documentation of this file.
1
// Copyright (C) 2018 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
// Qt-Security score:significant
4
5
#
include
"qqmlpreviewservice.h"
6
#
include
"qqmlclassicpreviewhandler.h"
7
#
include
"qqmlinplacepreviewhandler.h"
8
9
#
include
<
QtCore
/
qpointer
.
h
>
10
#
include
<
QtQml
/
qqmlengine
.
h
>
11
#
include
<
QtQml
/
qqmlcomponent
.
h
>
12
#
include
<
QtQuick
/
qquickwindow
.
h
>
13
#
include
<
QtQuick
/
qquickitem
.
h
>
14
#
include
<
QtGui
/
qguiapplication
.
h
>
15
16
#
include
<
private
/
qquickpixmap_p
.
h
>
17
#
include
<
private
/
qqmldebugconnector_p
.
h
>
18
#
include
<
private
/
qversionedpacket_p
.
h
>
19
20
QT_BEGIN_NAMESPACE
21
22
inline
bool
convertQmlPreviewHotReload
(
const
char
*v)
23
{
24
// Either not set or explicitly "1" or "true";
25
return
v ==
nullptr
|| qstrcmp(v,
"1"
) == 0 || qstrcmp(v,
"true"
) == 0;
26
}
27
28
static
bool
qmlPreviewHotReloadEnabled
()
29
{
30
static
const
bool
enabled =
31
qmlGetConfigOption<
bool
,
convertQmlPreviewHotReload
>(
"QMLPREVIEW_HOTRELOAD"
);
32
return
enabled;
33
}
34
35
const
QString
QQmlPreviewServiceImpl
::
s_key
= QStringLiteral(
"QmlPreview"
);
36
using
QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
37
38
QQmlPreviewServiceImpl
::
QQmlPreviewServiceImpl
(QObject *parent) :
39
QQmlDebugService
(
s_key
, 1.0f,
parent
),
40
m_handler
(
std
::
make_unique
<
QQmlClassicPreviewHandler
>())
41
{
42
m_handler->connectToService(
this
);
43
}
44
45
QQmlPreviewServiceImpl
::~
QQmlPreviewServiceImpl
()
46
{
47
}
48
49
void
QQmlPreviewServiceImpl
::switchToInPlaceHandler()
50
{
51
// Transfer engines from the old handler to the new one
52
const
auto
engineList = m_handler->engines();
53
m_handler = std::make_unique<QQmlInPlacePreviewHandler>();
54
m_handler->connectToService(
this
);
55
for
(QQmlEngine *engine : engineList)
56
m_handler->addEngine(engine);
57
58
// Send confirmation back to the client
59
QQmlDebugPacket response;
60
const
bool
enableInPlaceUpdates =
true
;
61
response <<
static_cast
<qint8>(Confirmation) << enableInPlaceUpdates;
62
emit messageToClient(name(), response.data());
63
}
64
65
void
QQmlPreviewServiceImpl
::
messageReceived
(
const
QByteArray &data)
66
{
67
QQmlDebugPacket packet(data);
68
qint8 command;
69
70
packet >> command;
71
switch
(command) {
72
case
File: {
73
QString path;
74
QByteArray contents;
75
packet >> path >> contents;
76
77
const
QUrl url = path.startsWith(QLatin1Char(
':'
))
78
? QUrl(QLatin1String(
"qrc"
) + path)
79
: QUrl::fromLocalFile(path);
80
81
// Only a re-serve of a URL we already saw is an actual edit that needs relinking. The
82
// first time any file is served (e.g. while the whole app is still starting up) isn't
83
// dropping anything; treating it as such piles up the entire type registry as "dropped"
84
// and causes a mass relink storm on the first Load.
85
if
(m_servedUrls.contains(url))
86
emit drop(url);
87
else
88
m_servedUrls.insert(url);
89
emit file(path, contents);
90
91
// Remember the first .qml file as the current URL, so that a Load command
92
// without an explicit URL can fall back to it.
93
if
(m_currentUrl.isEmpty() && path.endsWith(
".qml"
))
94
m_currentUrl = url;
95
96
// Never auto-load here. The client must send an explicit Load command
97
// to trigger loading. Auto-loading based on File responses is racy
98
// (the Configuration message may not have arrived yet) and creates
99
// duplicate objects when the host process has already loaded the scene.
100
break
;
101
}
102
case
Directory: {
103
QString path;
104
QStringList entries;
105
packet >> path >> entries;
106
emit directory(path, entries);
107
break
;
108
}
109
case
Load: {
110
QUrl url;
111
packet >> url;
112
if
(url.isEmpty())
113
url = m_currentUrl;
114
else
115
m_currentUrl = url;
116
emit load(url);
117
break
;
118
}
119
case
Error: {
120
QString file;
121
packet >> file;
122
emit error(file);
123
break
;
124
}
125
case
Rerun:
126
emit rerun();
127
break
;
128
case
ClearCache:
129
emit
clearCache
();
130
break
;
131
case
Zoom: {
132
float
factor;
133
packet >> factor;
134
emit zoom(
static_cast
<qreal>(factor));
135
break
;
136
}
137
case
AnimationSpeed: {
138
float
factor;
139
packet >> factor;
140
emit animationSpeed(qreal(factor));
141
break
;
142
}
143
case
Configuration: {
144
if
(
qmlPreviewHotReloadEnabled
(
)
) {
145
bool
enableInPlaceUpdates;
146
packet >> enableInPlaceUpdates;
147
if
(enableInPlaceUpdates
148
&& !qobject_cast<QQmlInPlacePreviewHandler *>(m_handler.get())) {
149
// Schedule this to the main thread where the handler lives
150
// We're on the debug server thread here.
151
QMetaObject::invokeMethod(
this
, &QQmlPreviewServiceImpl::switchToInPlaceHandler);
152
}
else
if
(!enableInPlaceUpdates
153
&& qobject_cast<QQmlInPlacePreviewHandler *>(m_handler.get())) {
154
forwardError(QLatin1String(
"Cannot disable in-place updates once enabled"
));
155
}
156
break
;
157
}
else
{
158
Q_FALLTHROUGH();
159
}
160
}
161
default
:
162
forwardError(QString::fromLatin1(
"Invalid command: %1"
).arg(command));
163
break
;
164
}
165
}
166
167
void
QQmlPreviewServiceImpl
::
engineAboutToBeAdded
(QJSEngine *engine)
168
{
169
if
(QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
170
m_handler->addEngine(qmlEngine);
171
emit attachedToEngine(engine);
172
}
173
174
void
QQmlPreviewServiceImpl
::
engineAboutToBeRemoved
(QJSEngine *engine)
175
{
176
if
(QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine))
177
m_handler->removeEngine(qmlEngine);
178
emit detachedFromEngine(engine);
179
}
180
181
void
QQmlPreviewServiceImpl
::
stateChanged
(QQmlDebugService::State state)
182
{
183
if
(state == Enabled) {
184
m_loader.reset(
new
QQmlPreviewFileLoader(
this
));
185
connect(
this
, &QQmlPreviewServiceImpl::load,
186
m_loader.data(), &QQmlPreviewFileLoader::whitelist, Qt::DirectConnection);
187
QV4::ExecutionEngine::setPreviewing(
true
);
188
m_fileEngine.reset(
new
QQmlPreviewFileEngineHandler(m_loader.data()));
189
}
else
{
190
QV4::ExecutionEngine::setPreviewing(
false
);
191
m_fileEngine.reset();
192
m_loader.reset();
193
}
194
}
195
196
void
QQmlPreviewServiceImpl
::
forwardRequest
(
const
QString &file)
197
{
198
QQmlDebugPacket packet;
199
packet <<
static_cast
<qint8>(Request) << file;
200
emit messageToClient(name(), packet.data());
201
}
202
203
void
QQmlPreviewServiceImpl
::
forwardError
(
const
QString &error)
204
{
205
QQmlDebugPacket packet;
206
packet <<
static_cast
<qint8>(Error) << error;
207
emit messageToClient(name(), packet.data());
208
}
209
210
void
QQmlPreviewServiceImpl
::
forwardFps
(
const
QQmlPreviewHandler::FpsInfo &frames)
211
{
212
QQmlDebugPacket packet;
213
packet <<
static_cast
<qint8>(Fps)
214
<< frames.numSyncs << frames.minSync << frames.maxSync << frames.totalSync
215
<< frames.numRenders << frames.minRender << frames.maxRender << frames.totalRender;
216
emit messageToClient(name(), packet.data());
217
}
218
219
void
QQmlPreviewServiceImpl
::
forwardHotReloadFailure
(
const
QString &reason)
220
{
221
QQmlDebugPacket packet;
222
packet <<
static_cast
<qint8>(HotReloadFailure) << reason;
223
emit messageToClient(name(), packet.data());
224
}
225
226
QQuickItem *
QQmlPreviewServiceImpl
::
currentRootItem
()
227
{
228
return
m_handler->currentRootItem();
229
}
230
231
QT_END_NAMESPACE
232
233
#
include
"moc_qqmlpreviewservice.cpp"
QQmlPreviewServiceImpl
Definition
qqmlpreviewservice.h:31
QQmlPreviewServiceImpl::forwardRequest
void forwardRequest(const QString &file)
Definition
qqmlpreviewservice.cpp:196
QQmlPreviewServiceImpl::s_key
static const QString s_key
Definition
qqmlpreviewservice.h:51
QQmlPreviewServiceImpl::engineAboutToBeRemoved
void engineAboutToBeRemoved(QJSEngine *engine) override
Definition
qqmlpreviewservice.cpp:174
QQmlPreviewServiceImpl::currentRootItem
QQuickItem * currentRootItem()
Definition
qqmlpreviewservice.cpp:226
QQmlPreviewServiceImpl::QQmlPreviewServiceImpl
QQmlPreviewServiceImpl(QObject *parent=nullptr)
Definition
qqmlpreviewservice.cpp:38
QQmlPreviewServiceImpl::forwardHotReloadFailure
void forwardHotReloadFailure(const QString &reason)
Definition
qqmlpreviewservice.cpp:219
QQmlPreviewServiceImpl::~QQmlPreviewServiceImpl
virtual ~QQmlPreviewServiceImpl()
Definition
qqmlpreviewservice.cpp:45
QQmlPreviewServiceImpl::engineAboutToBeAdded
void engineAboutToBeAdded(QJSEngine *engine) override
Definition
qqmlpreviewservice.cpp:167
QQmlPreviewServiceImpl::forwardFps
void forwardFps(const QQmlPreviewHandler::FpsInfo &frames)
Definition
qqmlpreviewservice.cpp:210
QQmlPreviewServiceImpl::stateChanged
void stateChanged(State state) override
Definition
qqmlpreviewservice.cpp:181
QQmlPreviewServiceImpl::forwardError
void forwardError(const QString &error)
Definition
qqmlpreviewservice.cpp:203
QQmlPreviewServiceImpl::messageReceived
void messageReceived(const QByteArray &message) override
Definition
qqmlpreviewservice.cpp:65
QQmlTypeLoader::clearCache
void clearCache()
Clears cached information about loaded files, including any type data, scripts and qmldir information...
Definition
qqmltypeloader.cpp:1745
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
convertQmlPreviewHotReload
QT_BEGIN_NAMESPACE bool convertQmlPreviewHotReload(const char *v)
Definition
qqmlpreviewservice.cpp:22
qmlPreviewHotReloadEnabled
static bool qmlPreviewHotReloadEnabled()
Definition
qqmlpreviewservice.cpp:28
qtdeclarative
src
plugins
qmltooling
qmldbg_preview
qqmlpreviewservice.cpp
Generated on
for Qt by
1.18.0