QmlDesigner: add qmldebugtranslationclient

Change-Id: I4b863a454831f469823e03355d87861eed9be046
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Tim Jenssen
2020-05-28 12:35:25 +02:00
parent 48b6ae2e1f
commit 6079a317b9
6 changed files with 265 additions and 57 deletions

View File

@@ -0,0 +1,98 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "qmldebugtranslationclient.h"
#include <qmldebug/qpacketprotocol.h>
#include <QUrl>
namespace QmlPreview {
QmlDebugTranslationClient::QmlDebugTranslationClient(QmlDebug::QmlDebugConnection *connection) :
QmlDebug::QmlDebugClient(QLatin1String("DebugTranslation"), connection)
{
}
void QmlDebugTranslationClient::changeLanguage(const QUrl &url, const QString &locale)
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(ChangeLanguage) << url << locale;
sendMessage(packet.data());
}
void QmlDebugTranslationClient::changeWarningColor(const QColor &warningColor)
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(ChangeWarningColor) << warningColor;
sendMessage(packet.data());
}
void QmlDebugTranslationClient::changeElidedTextWarningString(const QString &warningString)
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(ChangeElidedTextWarningString) << warningString;
sendMessage(packet.data());
}
void QmlDebugTranslationClient::setDebugTranslationServiceLogFile(const QString &logFilePath)
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(SetDebugTranslationServiceLogFile) << logFilePath;
sendMessage(packet.data());
}
void QmlDebugTranslationClient::enableElidedTextWarning()
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(EnableElidedTextWarning);
sendMessage(packet.data());
}
void QmlDebugTranslationClient::disableElidedTextWarning()
{
QmlDebug::QPacket packet(dataStreamVersion());
packet << static_cast<qint8>(DisableElidedTextWarning);
sendMessage(packet.data());
}
void QmlDebugTranslationClient::messageReceived(const QByteArray &data)
{
QmlDebug::QPacket packet(dataStreamVersion(), data);
qint8 command;
packet >> command;
switch (command) {
default:
qDebug() << "invalid command" << command;
break;
}
}
void QmlDebugTranslationClient::stateChanged(QmlDebug::QmlDebugClient::State state)
{
if (state == Unavailable)
emit debugServiceUnavailable();
}
} // namespace QmlPreview

View File

@@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "qmlpreview_global.h"
#include <qmldebug/qmldebugclient.h>
namespace QmlPreview {
class QMLPREVIEW_EXPORT QmlDebugTranslationClient : public QmlDebug::QmlDebugClient
{
Q_OBJECT
public:
//needs to be in sync with QQmlDebugTranslationClient in qtdeclarative/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h
enum Command {
ChangeLanguage,
ChangeWarningColor,
ChangeElidedTextWarningString,
SetDebugTranslationServiceLogFile,
EnableElidedTextWarning,
DisableElidedTextWarning,
TestAllLanguages
};
explicit QmlDebugTranslationClient(QmlDebug::QmlDebugConnection *connection);
void changeLanguage(const QUrl &url, const QString &locale);
void changeWarningColor(const QColor &warningColor);
void changeElidedTextWarningString(const QString &warningString); //is QByteArray better here?
void setDebugTranslationServiceLogFile(const QString &logFilePath);
void enableElidedTextWarning();
void disableElidedTextWarning();
void messageReceived(const QByteArray &message) override;
void stateChanged(State state) override;
signals:
// void pathRequested(const QString &path);
// void errorReported(const QString &error);
void debugServiceUnavailable();
};
} // namespace QmlPreview

View File

@@ -9,6 +9,7 @@ include(tests/tests.pri)
HEADERS += \ HEADERS += \
qmlpreview_global.h \ qmlpreview_global.h \
qmldebugtranslationclient.h \
qmlpreviewclient.h \ qmlpreviewclient.h \
qmlpreviewplugin.h \ qmlpreviewplugin.h \
qmlpreviewruncontrol.h \ qmlpreviewruncontrol.h \
@@ -17,6 +18,7 @@ HEADERS += \
SOURCES += \ SOURCES += \
qmlpreviewplugin.cpp \ qmlpreviewplugin.cpp \
qmldebugtranslationclient.cpp \
qmlpreviewclient.cpp \ qmlpreviewclient.cpp \
qmlpreviewruncontrol.cpp \ qmlpreviewruncontrol.cpp \
qmlpreviewconnectionmanager.cpp \ qmlpreviewconnectionmanager.cpp \

View File

@@ -24,6 +24,8 @@ QtcPlugin {
files: [ files: [
"qmlpreviewclient.cpp", "qmlpreviewclient.cpp",
"qmlpreviewclient.h", "qmlpreviewclient.h",
"qmldebugtranslationclient.cpp",
"qmldebugtranslationclient.h",
"qmlpreviewconnectionmanager.cpp", "qmlpreviewconnectionmanager.cpp",
"qmlpreviewconnectionmanager.h", "qmlpreviewconnectionmanager.h",
"qmlpreviewfileontargetfinder.cpp", "qmlpreviewfileontargetfinder.cpp",

View File

@@ -70,40 +70,12 @@ void QmlPreviewConnectionManager::setFpsHandler(QmlPreviewFpsHandler fpsHandler)
void QmlPreviewConnectionManager::createClients() void QmlPreviewConnectionManager::createClients()
{ {
m_clientPlugin = new QmlPreviewClient(connection()); createPreviewClient();
createDebugTranslationClient();
QObject::connect( }
this, &QmlPreviewConnectionManager::loadFile, m_clientPlugin.data(),
[this](const QString &filename, const QString &changedFile,
const QByteArray &contents) {
if (!m_fileClassifier(changedFile)) {
emit restart();
return;
}
bool success = false;
const QString remoteChangedFile = m_targetFileFinder.findPath(changedFile, &success);
if (success)
m_clientPlugin->announceFile(remoteChangedFile, contents);
else
m_clientPlugin->clearCache();
m_lastLoadedUrl = m_targetFileFinder.findUrl(filename);
m_clientPlugin->loadUrl(m_lastLoadedUrl);
});
QObject::connect(this, &QmlPreviewConnectionManager::rerun,
m_clientPlugin.data(), &QmlPreviewClient::rerun);
QObject::connect(this, &QmlPreviewConnectionManager::zoom,
m_clientPlugin.data(), &QmlPreviewClient::zoom);
QObject::connect(this, &QmlPreviewConnectionManager::language,
m_clientPlugin.data(), [this](const QString &locale) {
// The preview service expects a context URL.
// Search the parent directories of the last loaded URL for i18n files.
QUrl QmlPreviewConnectionManager::findValidI18nDirectoryAsUrl(const QString &locale)
{
const QString shortLocale = locale.left(locale.indexOf("_")); const QString shortLocale = locale.left(locale.indexOf("_"));
QString path = m_lastLoadedUrl.path(); QString path = m_lastLoadedUrl.path();
@@ -130,11 +102,65 @@ void QmlPreviewConnectionManager::createClients()
QUrl url = m_lastLoadedUrl; QUrl url = m_lastLoadedUrl;
url.setPath(path); url.setPath(path);
return url;
}
m_clientPlugin->language(url, locale); void QmlPreviewConnectionManager::createDebugTranslationClient()
{
m_qmlDebugTranslationClient = new QmlDebugTranslationClient(connection());
QObject::connect(this, &QmlPreviewConnectionManager::language,
m_qmlDebugTranslationClient.data(), [this](const QString &locale) {
// service expects a context URL.
// Search the parent directories of the last loaded URL for i18n files.
m_qmlDebugTranslationClient->changeLanguage(findValidI18nDirectoryAsUrl(locale), locale);
});
QObject::connect(m_qmlDebugTranslationClient.data(), &QmlDebugTranslationClient::debugServiceUnavailable,
this, []() {
QMessageBox::warning(Core::ICore::mainWindow(), "Error connect to QML DebugTranslation service",
"QML DebugTranslation feature is not available for this version of Qt.");
}, Qt::QueuedConnection); // Queue it, so that it interfere with the connection timer
}
void QmlPreviewConnectionManager::createPreviewClient()
{
m_qmlPreviewClient = new QmlPreviewClient(connection());
QObject::connect(
this, &QmlPreviewConnectionManager::loadFile, m_qmlPreviewClient.data(),
[this](const QString &filename, const QString &changedFile,
const QByteArray &contents) {
if (!m_fileClassifier(changedFile)) {
emit restart();
return;
}
bool success = false;
const QString remoteChangedFile = m_targetFileFinder.findPath(changedFile, &success);
if (success)
m_qmlPreviewClient->announceFile(remoteChangedFile, contents);
else
m_qmlPreviewClient->clearCache();
m_lastLoadedUrl = m_targetFileFinder.findUrl(filename);
m_qmlPreviewClient->loadUrl(m_lastLoadedUrl);
}); });
QObject::connect(m_clientPlugin.data(), &QmlPreviewClient::pathRequested, QObject::connect(this, &QmlPreviewConnectionManager::rerun,
m_qmlPreviewClient.data(), &QmlPreviewClient::rerun);
QObject::connect(this, &QmlPreviewConnectionManager::zoom,
m_qmlPreviewClient.data(), &QmlPreviewClient::zoom);
QObject::connect(this, &QmlPreviewConnectionManager::language,
m_qmlPreviewClient.data(), [this](const QString &locale) {
// service expects a context URL.
// Search the parent directories of the last loaded URL for i18n files.
m_qmlPreviewClient->language(findValidI18nDirectoryAsUrl(locale), locale);
});
QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::pathRequested,
this, [this](const QString &path) { this, [this](const QString &path) {
const bool found = m_projectFileFinder.findFileOrDirectory( const bool found = m_projectFileFinder.findFileOrDirectory(
path, [&](const QString &filename, int confidence) { path, [&](const QString &filename, int confidence) {
@@ -146,31 +172,31 @@ void QmlPreviewConnectionManager::createClients()
m_fileSystemWatcher.addFile(filename, m_fileSystemWatcher.addFile(filename,
Utils::FileSystemWatcher::WatchModifiedDate); Utils::FileSystemWatcher::WatchModifiedDate);
} }
m_clientPlugin->announceFile(path, contents); m_qmlPreviewClient->announceFile(path, contents);
} else { } else {
m_clientPlugin->announceError(path); m_qmlPreviewClient->announceError(path);
} }
} else { } else {
m_clientPlugin->announceError(path); m_qmlPreviewClient->announceError(path);
} }
}, [&](const QStringList &entries, int confidence) { }, [&](const QStringList &entries, int confidence) {
if (confidence == path.length()) if (confidence == path.length())
m_clientPlugin->announceDirectory(path, entries); m_qmlPreviewClient->announceDirectory(path, entries);
else else
m_clientPlugin->announceError(path); m_qmlPreviewClient->announceError(path);
}); });
if (!found) if (!found)
m_clientPlugin->announceError(path); m_qmlPreviewClient->announceError(path);
}); });
QObject::connect(m_clientPlugin.data(), &QmlPreviewClient::errorReported, QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::errorReported,
this, [](const QString &error) { this, [](const QString &error) {
Core::MessageManager::write("Error loading QML Live Preview:"); Core::MessageManager::write("Error loading QML Live Preview:");
Core::MessageManager::write(error); Core::MessageManager::write(error);
}); });
QObject::connect(m_clientPlugin.data(), &QmlPreviewClient::fpsReported, QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::fpsReported,
this, [this](const QmlPreviewClient::FpsInfo &frames) { this, [this](const QmlPreviewClient::FpsInfo &frames) {
if (m_fpsHandler) { if (m_fpsHandler) {
quint16 stats[] = { quint16 stats[] = {
@@ -181,14 +207,14 @@ void QmlPreviewConnectionManager::createClients()
} }
}); });
QObject::connect(m_clientPlugin.data(), &QmlPreviewClient::debugServiceUnavailable, QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::debugServiceUnavailable,
this, []() { this, []() {
QMessageBox::warning(Core::ICore::mainWindow(), "Error loading QML Live Preview", QMessageBox::warning(Core::ICore::mainWindow(), "Error loading QML Live Preview",
"QML Live Preview is not available for this version of Qt."); "QML Live Preview is not available for this version of Qt.");
}, Qt::QueuedConnection); // Queue it, so that it interfere with the connection timer }, Qt::QueuedConnection); // Queue it, so that it interfere with the connection timer
QObject::connect(&m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged, QObject::connect(&m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged,
m_clientPlugin.data(), [this](const QString &changedFile) { m_qmlPreviewClient.data(), [this](const QString &changedFile) {
if (!m_fileLoader || !m_lastLoadedUrl.isValid()) if (!m_fileLoader || !m_lastLoadedUrl.isValid())
return; return;
@@ -205,20 +231,28 @@ void QmlPreviewConnectionManager::createClients()
const QString remoteChangedFile = m_targetFileFinder.findPath(changedFile, &success); const QString remoteChangedFile = m_targetFileFinder.findPath(changedFile, &success);
if (success) if (success)
m_clientPlugin->announceFile(remoteChangedFile, contents); m_qmlPreviewClient->announceFile(remoteChangedFile, contents);
else else
m_clientPlugin->clearCache(); m_qmlPreviewClient->clearCache();
m_clientPlugin->loadUrl(m_lastLoadedUrl); m_qmlPreviewClient->loadUrl(m_lastLoadedUrl);
}); });
} }
void QmlPreviewConnectionManager::clearClient(QObject *client)
{
if (client) {
disconnect(client, nullptr, this, nullptr);
disconnect(this, nullptr, client, nullptr);
client->deleteLater();
}
};
void QmlPreviewConnectionManager::destroyClients() void QmlPreviewConnectionManager::destroyClients()
{ {
disconnect(m_clientPlugin.data(), nullptr, this, nullptr); clearClient(m_qmlPreviewClient);
disconnect(this, nullptr, m_clientPlugin.data(), nullptr); clearClient(m_qmlDebugTranslationClient);
m_clientPlugin->deleteLater();
m_clientPlugin.clear();
m_fileSystemWatcher.removeFiles(m_fileSystemWatcher.files()); m_fileSystemWatcher.removeFiles(m_fileSystemWatcher.files());
QTC_ASSERT(m_fileSystemWatcher.directories().isEmpty(), QTC_ASSERT(m_fileSystemWatcher.directories().isEmpty(),
m_fileSystemWatcher.removeDirectories(m_fileSystemWatcher.directories())); m_fileSystemWatcher.removeDirectories(m_fileSystemWatcher.directories()));

View File

@@ -27,6 +27,7 @@
#include "qmlpreviewplugin.h" #include "qmlpreviewplugin.h"
#include "qmlpreviewclient.h" #include "qmlpreviewclient.h"
#include "qmldebugtranslationclient.h"
#include "qmlpreviewfileontargetfinder.h" #include "qmlpreviewfileontargetfinder.h"
#include <qmldebug/qmldebugconnectionmanager.h> #include <qmldebug/qmldebugconnectionmanager.h>
@@ -64,9 +65,14 @@ protected:
void destroyClients() override; void destroyClients() override;
private: private:
void createPreviewClient();
void createDebugTranslationClient();
QUrl findValidI18nDirectoryAsUrl(const QString &locale);
void clearClient(QObject *client);
Utils::FileInProjectFinder m_projectFileFinder; Utils::FileInProjectFinder m_projectFileFinder;
QmlPreviewFileOnTargetFinder m_targetFileFinder; QmlPreviewFileOnTargetFinder m_targetFileFinder;
QPointer<QmlPreviewClient> m_clientPlugin; QPointer<QmlPreviewClient> m_qmlPreviewClient;
QPointer<QmlDebugTranslationClient> m_qmlDebugTranslationClient;
Utils::FileSystemWatcher m_fileSystemWatcher; Utils::FileSystemWatcher m_fileSystemWatcher;
QUrl m_lastLoadedUrl; QUrl m_lastLoadedUrl;
QmlPreviewFileLoader m_fileLoader = nullptr; QmlPreviewFileLoader m_fileLoader = nullptr;