/**************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QML preview debug service. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ****************************************************************************/ #include "qqmlpreviewservice.h" #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE const QString QQmlPreviewServiceImpl::s_key = QStringLiteral("QmlPreview"); using QQmlDebugPacket = QVersionedPacket; QQmlPreviewServiceImpl::QQmlPreviewServiceImpl(QObject *parent) : QQmlDebugService(s_key, 1.0f, parent) { m_loader.reset(new QQmlPreviewFileLoader(this)); connect(this, &QQmlPreviewServiceImpl::load, m_loader.data(), &QQmlPreviewFileLoader::whitelist, Qt::DirectConnection); connect(this, &QQmlPreviewServiceImpl::load, &m_handler, &QQmlPreviewHandler::loadUrl); connect(this, &QQmlPreviewServiceImpl::rerun, &m_handler, &QQmlPreviewHandler::rerun); connect(this, &QQmlPreviewServiceImpl::zoom, &m_handler, &QQmlPreviewHandler::zoom); #if QT_CONFIG(translation) connect(this, &QQmlPreviewServiceImpl::language, &m_handler, &QQmlPreviewHandler::language); #endif connect(&m_handler, &QQmlPreviewHandler::error, this, &QQmlPreviewServiceImpl::forwardError, Qt::DirectConnection); connect(&m_handler, &QQmlPreviewHandler::fps, this, &QQmlPreviewServiceImpl::forwardFps, Qt::DirectConnection); } QQmlPreviewServiceImpl::~QQmlPreviewServiceImpl() { } void QQmlPreviewServiceImpl::messageReceived(const QByteArray &data) { QQmlDebugPacket packet(data); qint8 command; packet >> command; switch (command) { case File: { QString path; QByteArray contents; packet >> path >> contents; emit file(path, contents); // Replace the whole scene with the first file successfully loaded over the debug // connection. This is an OK approximation of the root component, and if the client wants // something specific, it will send an explicit Load anyway. if (m_currentUrl.isEmpty() && path.endsWith(".qml")) { if (path.startsWith(':')) m_currentUrl = QUrl("qrc" + path); else m_currentUrl = QUrl::fromLocalFile(path); emit load(m_currentUrl); } break; } case Directory: { QString path; QStringList entries; packet >> path >> entries; emit directory(path, entries); break; } case Load: { QUrl url; packet >> url; if (url.isEmpty()) url = m_currentUrl; else m_currentUrl = url; emit load(url); break; } case Error: { QString file; packet >> file; emit error(file); break; } case Rerun: emit rerun(); break; case ClearCache: emit clearCache(); break; case Zoom: { float factor; packet >> factor; emit zoom(static_cast(factor)); break; } #if QT_CONFIG(translation) case Language: { QUrl context; QString locale; packet >> context >> locale; emit language(context.isEmpty() ? m_currentUrl : context, locale.isEmpty() ? QLocale() : QLocale(locale)); break; } #endif default: forwardError(QString::fromLatin1("Invalid command: %1").arg(command)); break; } } void QQmlPreviewServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { if (QQmlEngine *qmlEngine = qobject_cast(engine)) m_handler.addEngine(qmlEngine); emit attachedToEngine(engine); } void QQmlPreviewServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { if (QQmlEngine *qmlEngine = qobject_cast(engine)) m_handler.removeEngine(qmlEngine); emit detachedFromEngine(engine); } void QQmlPreviewServiceImpl::stateChanged(QQmlDebugService::State state) { m_fileEngine.reset(state == Enabled ? new QQmlPreviewFileEngineHandler(m_loader.data()) : nullptr); } void QQmlPreviewServiceImpl::forwardRequest(const QString &file) { QQmlDebugPacket packet; packet << static_cast(Request) << file; emit messageToClient(name(), packet.data()); } void QQmlPreviewServiceImpl::forwardError(const QString &error) { QQmlDebugPacket packet; packet << static_cast(Error) << error; emit messageToClient(name(), packet.data()); } void QQmlPreviewServiceImpl::forwardFps(const QQmlPreviewHandler::FpsInfo &frames) { QQmlDebugPacket packet; packet << static_cast(Fps) << frames.numSyncs << frames.minSync << frames.maxSync << frames.totalSync << frames.numRenders << frames.minRender << frames.maxRender << frames.totalRender; emit messageToClient(name(), packet.data()); } QT_END_NAMESPACE