forked from qt-creator/qt-creator
qmlpreview: add debugtranslation ui
action in the menu will only be shown if a QtStudio Qt is found qtversion.xml <value type="QString" key="overrideFeatures">QtStudio</value> - still have some issues with multiple file test runs so disable it for now - elideWarning is not tested Change-Id: I68c9f774a980b84cd4eea1595775fd01afa6f3cf Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -9,6 +9,7 @@ add_qtc_plugin(QmlPreview
|
|||||||
qmlpreviewruncontrol.cpp qmlpreviewruncontrol.h
|
qmlpreviewruncontrol.cpp qmlpreviewruncontrol.h
|
||||||
qmldebugtranslationclient.cpp qmldebugtranslationclient.h
|
qmldebugtranslationclient.cpp qmldebugtranslationclient.h
|
||||||
qmlpreview_global.h
|
qmlpreview_global.h
|
||||||
|
projectfileselectionswidget.cpp projectfileselectionswidget.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlPreview
|
extend_qtc_plugin(QmlPreview
|
||||||
|
156
src/plugins/qmlpreview/projectfileselectionswidget.cpp
Normal file
156
src/plugins/qmlpreview/projectfileselectionswidget.cpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "projectfileselectionswidget.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
|
||||||
|
#include <utils/treemodel.h>
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
namespace QmlPreview {
|
||||||
|
|
||||||
|
class ProjectFileItem : public Utils::TreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProjectFileItem() = default;
|
||||||
|
ProjectFileItem(const Utils::FilePath &f, bool d)
|
||||||
|
: filePath(f)
|
||||||
|
, disabled(d)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(int) const override
|
||||||
|
{
|
||||||
|
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant data(int , int role) const override
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return filePath.toUserOutput();
|
||||||
|
if (role == Qt::CheckStateRole) {
|
||||||
|
if (disabled)
|
||||||
|
return Qt::Unchecked;
|
||||||
|
else
|
||||||
|
return Qt::Checked;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setData(int , const QVariant &data, int role) override
|
||||||
|
{
|
||||||
|
if (role != Qt::CheckStateRole)
|
||||||
|
return false;
|
||||||
|
disabled = (data == Qt::Unchecked);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePath filePath;
|
||||||
|
bool disabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ProjectFileSelectionsWidget::ProjectFileSelectionsWidget(const QString &projectSettingsKey, ProjectExplorer::FileType fileType, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_projectSettingsKey(projectSettingsKey)
|
||||||
|
, m_fileType(fileType)
|
||||||
|
{
|
||||||
|
auto model = new Utils::TreeModel<ProjectFileItem>(this);
|
||||||
|
model->setHeader({tr("Files to test:")});
|
||||||
|
auto updateCheckedFiles = [this, model] () {
|
||||||
|
m_checkedFiles.clear();
|
||||||
|
QStringList uncheckedFiles;
|
||||||
|
model->forAllItems([&, this](ProjectFileItem *item) {
|
||||||
|
if (item->disabled)
|
||||||
|
uncheckedFiles.append(item->filePath.toString());
|
||||||
|
else
|
||||||
|
m_checkedFiles.append(item->filePath);
|
||||||
|
});
|
||||||
|
if (auto project = ProjectExplorer::SessionManager::startupProject())
|
||||||
|
project->setNamedSettings(m_projectSettingsKey, uncheckedFiles);
|
||||||
|
emit selectionChanged(m_checkedFiles);
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(model, &QAbstractItemModel::dataChanged, updateCheckedFiles);
|
||||||
|
|
||||||
|
auto view = new QTreeView(this);
|
||||||
|
view->setMinimumSize(QSize(100, 100));
|
||||||
|
view->setTextElideMode(Qt::ElideMiddle);
|
||||||
|
view->setWordWrap(false);
|
||||||
|
view->setUniformRowHeights(true);
|
||||||
|
view->setModel(model);
|
||||||
|
|
||||||
|
const auto viewLayout = new QHBoxLayout;
|
||||||
|
viewLayout->addWidget(view);
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addLayout(viewLayout);
|
||||||
|
|
||||||
|
auto initModel = [this, model, updateCheckedFiles] (ProjectExplorer::Project *project) {
|
||||||
|
auto refreshModel = [this, model, updateCheckedFiles] () {
|
||||||
|
model->clear();
|
||||||
|
if (auto project = ProjectExplorer::SessionManager::startupProject()) {
|
||||||
|
const auto settingsDisabledFiles = project->namedSettings(m_projectSettingsKey).toStringList();
|
||||||
|
|
||||||
|
if (auto rootProjectNode = project->rootProjectNode()) {
|
||||||
|
rootProjectNode->forEachNode([this, settingsDisabledFiles, model](ProjectExplorer::FileNode *fileNode) {
|
||||||
|
if (fileNode->fileType() == m_fileType) {
|
||||||
|
bool isDisabled = settingsDisabledFiles.contains(fileNode->filePath().toString());
|
||||||
|
model->rootItem()->appendChild(new ProjectFileItem(fileNode->filePath(), isDisabled));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateCheckedFiles();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// deploymentDataChanged is only triggered if the active project changed, so it is not a
|
||||||
|
// problem that maybe many different targets are connected to refreshModel
|
||||||
|
this->connect(project->activeTarget(), &ProjectExplorer::Target::deploymentDataChanged,
|
||||||
|
model, refreshModel, Qt::UniqueConnection);
|
||||||
|
refreshModel();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto project = ProjectExplorer::SessionManager::startupProject()) {
|
||||||
|
initModel(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(ProjectExplorer::SessionManager::instance(),
|
||||||
|
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||||
|
initModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePaths ProjectFileSelectionsWidget::checkedFiles()
|
||||||
|
{
|
||||||
|
return m_checkedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlPreview
|
50
src/plugins/qmlpreview/projectfileselectionswidget.h
Normal file
50
src/plugins/qmlpreview/projectfileselectionswidget.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <projectexplorer/projectnodes.h>
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace QmlPreview {
|
||||||
|
|
||||||
|
class ProjectFileSelectionsWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ProjectFileSelectionsWidget(const QString &projectSettingsKey, ProjectExplorer::FileType fileType, QWidget *parent = nullptr);
|
||||||
|
Utils::FilePaths checkedFiles();
|
||||||
|
signals:
|
||||||
|
void selectionChanged(const Utils::FilePaths &selectedFiles);
|
||||||
|
private:
|
||||||
|
const QString m_projectSettingsKey;
|
||||||
|
ProjectExplorer::FileType m_fileType;
|
||||||
|
|
||||||
|
Utils::FilePaths m_checkedFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlPreview
|
@@ -57,6 +57,14 @@ void QmlDebugTranslationClient::changeElidedTextWarningString(const QString &war
|
|||||||
sendMessage(packet.data());
|
sendMessage(packet.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationClient::changeElideWarning(bool elideWarning)
|
||||||
|
{
|
||||||
|
if (elideWarning)
|
||||||
|
enableElidedTextWarning();
|
||||||
|
else
|
||||||
|
disableElidedTextWarning();
|
||||||
|
}
|
||||||
|
|
||||||
void QmlDebugTranslationClient::setDebugTranslationServiceLogFile(const QString &logFilePath)
|
void QmlDebugTranslationClient::setDebugTranslationServiceLogFile(const QString &logFilePath)
|
||||||
{
|
{
|
||||||
QmlDebug::QPacket packet(dataStreamVersion());
|
QmlDebug::QPacket packet(dataStreamVersion());
|
||||||
|
@@ -50,6 +50,7 @@ public:
|
|||||||
void changeLanguage(const QUrl &url, const QString &locale);
|
void changeLanguage(const QUrl &url, const QString &locale);
|
||||||
void changeWarningColor(const QColor &warningColor);
|
void changeWarningColor(const QColor &warningColor);
|
||||||
void changeElidedTextWarningString(const QString &warningString); //is QByteArray better here?
|
void changeElidedTextWarningString(const QString &warningString); //is QByteArray better here?
|
||||||
|
void changeElideWarning(bool elideWarning);
|
||||||
void setDebugTranslationServiceLogFile(const QString &logFilePath);
|
void setDebugTranslationServiceLogFile(const QString &logFilePath);
|
||||||
void enableElidedTextWarning();
|
void enableElidedTextWarning();
|
||||||
void disableElidedTextWarning();
|
void disableElidedTextWarning();
|
||||||
|
454
src/plugins/qmlpreview/qmldebugtranslationwidget.cpp
Normal file
454
src/plugins/qmlpreview/qmldebugtranslationwidget.cpp
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "qmldebugtranslationwidget.h"
|
||||||
|
#include "qmlpreviewruncontrol.h"
|
||||||
|
#include "qmlpreviewplugin.h"
|
||||||
|
#include "projectfileselectionswidget.h"
|
||||||
|
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/editormanager/ieditor.h>
|
||||||
|
#include <coreplugin/outputwindow.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/runcontrol.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
|
|
||||||
|
#include <utils/outputformatter.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
#include <extensionsystem/pluginspec.h>
|
||||||
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/projectnodes.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/task.h>
|
||||||
|
#include <projectexplorer/taskhub.h>
|
||||||
|
|
||||||
|
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
|
||||||
|
|
||||||
|
#include <qtsupport/qtoutputformatter.h>
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QSpacerItem>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QTextBlock>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QObject *getPreviewPlugin()
|
||||||
|
{
|
||||||
|
auto pluginIt = std::find_if(ExtensionSystem::PluginManager::plugins().begin(),
|
||||||
|
ExtensionSystem::PluginManager::plugins().end(),
|
||||||
|
[](const ExtensionSystem::PluginSpec *p) {
|
||||||
|
return p->name() == "QmlPreview";
|
||||||
|
});
|
||||||
|
|
||||||
|
if (pluginIt != ExtensionSystem::PluginManager::plugins().constEnd())
|
||||||
|
return (*pluginIt)->plugin();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlPreview {
|
||||||
|
|
||||||
|
QmlDebugTranslationWidget::QmlDebugTranslationWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
auto mainLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
auto buttonGroup = new QButtonGroup(this);
|
||||||
|
// it gets the text from updateCurrentEditor method
|
||||||
|
m_singleFileButton = new QRadioButton();
|
||||||
|
m_singleFileButton->setChecked(true);
|
||||||
|
buttonGroup->addButton(m_singleFileButton);
|
||||||
|
|
||||||
|
const QString projectSettingsKey = "QmlPreview.DisabledDebugTranslationFiles";
|
||||||
|
const ProjectExplorer::FileType filterFileType = ProjectExplorer::FileType::QML;
|
||||||
|
auto checkableProjectFileView = new ProjectFileSelectionsWidget(projectSettingsKey, filterFileType);
|
||||||
|
checkableProjectFileView->setVisible(false);
|
||||||
|
connect(checkableProjectFileView, &ProjectFileSelectionsWidget::selectionChanged, this, &QmlDebugTranslationWidget::setFiles);
|
||||||
|
m_multipleFileButton = new QRadioButton(tr("multiple files"));
|
||||||
|
// TODO: fix multiple files issues, because it have some issues disable it for now
|
||||||
|
m_multipleFileButton->setDisabled(true);
|
||||||
|
buttonGroup->addButton(m_multipleFileButton);
|
||||||
|
connect(m_multipleFileButton, &QAbstractButton::toggled, [checkableProjectFileView, this](bool checked) {
|
||||||
|
checkableProjectFileView->setVisible(checked);
|
||||||
|
setFiles(checkableProjectFileView->checkedFiles());
|
||||||
|
});
|
||||||
|
|
||||||
|
mainLayout->addWidget(m_singleFileButton);
|
||||||
|
mainLayout->addWidget(m_multipleFileButton);
|
||||||
|
mainLayout->addWidget(checkableProjectFileView);
|
||||||
|
|
||||||
|
// language checkboxes are add in updateAvailableTranslations method
|
||||||
|
m_selectLanguageLayout = new QHBoxLayout;
|
||||||
|
mainLayout->addLayout(m_selectLanguageLayout);
|
||||||
|
|
||||||
|
auto elideWarningCheckBox = new QCheckBox(tr("Enable elide warning"));
|
||||||
|
layout()->addWidget(elideWarningCheckBox);
|
||||||
|
connect(elideWarningCheckBox, &QCheckBox::stateChanged, [this] (int state) {
|
||||||
|
m_elideWarning = (state == Qt::Checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto controlLayout = new QHBoxLayout;
|
||||||
|
mainLayout->addLayout(controlLayout);
|
||||||
|
|
||||||
|
auto showLogButton = new QToolButton;
|
||||||
|
showLogButton->setText(tr("Show log"));
|
||||||
|
showLogButton->setCheckable(true);
|
||||||
|
controlLayout->addWidget(showLogButton);
|
||||||
|
|
||||||
|
// TODO: do we still need this buttons?
|
||||||
|
// auto pauseButton = new QToolButton;
|
||||||
|
// pauseButton->setText(tr("Pause"));
|
||||||
|
// pauseButton->setCheckable(true);
|
||||||
|
// controlLayout->addWidget(pauseButton);
|
||||||
|
|
||||||
|
// auto onTheFlyButton = new QToolButton;
|
||||||
|
// onTheFlyButton->setText(tr("On the fly"));
|
||||||
|
// controlLayout->addWidget(onTheFlyButton);
|
||||||
|
|
||||||
|
m_runTestButton = new QPushButton();
|
||||||
|
m_runTestButton->setCheckable(true);
|
||||||
|
m_runTestButton->setText(runButtonText());
|
||||||
|
connect(m_runTestButton, &QPushButton::toggled, [this](bool checked) {
|
||||||
|
m_runTestButton->setText(runButtonText(checked));
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_runTestButton, &QPushButton::clicked, [this](bool checked) {
|
||||||
|
if (checked)
|
||||||
|
runTest();
|
||||||
|
else {
|
||||||
|
if (m_currentRunControl)
|
||||||
|
m_currentRunControl->initiateStop();
|
||||||
|
// TODO: what happens if we already have a preview running?
|
||||||
|
// QmlPreviewPlugin::stopAllRunControls();
|
||||||
|
// qWarning() << "not implemented"; // TODO: stop still running tests
|
||||||
|
}
|
||||||
|
});
|
||||||
|
controlLayout->addWidget(m_runTestButton);
|
||||||
|
|
||||||
|
m_runOutputWindow = new Core::OutputWindow(Core::Context("QmlPreview.DebugTranslation"),
|
||||||
|
"QmlPreview/OutputWindow/Zoom");
|
||||||
|
|
||||||
|
m_runOutputWindow->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
m_runOutputWindow->setReadOnly(true);
|
||||||
|
m_runOutputWindow->setVisible(false);
|
||||||
|
mainLayout->addWidget(m_runOutputWindow);
|
||||||
|
|
||||||
|
QSpacerItem *endSpacerItem = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
mainLayout->addItem(endSpacerItem);
|
||||||
|
|
||||||
|
connect(showLogButton, &QToolButton::toggled, m_runOutputWindow, [this, mainLayout, endSpacerItem](bool checked) {
|
||||||
|
m_runOutputWindow->setVisible(checked);
|
||||||
|
if (m_runOutputWindow->isVisible())
|
||||||
|
mainLayout->takeAt(mainLayout->count() - 1);
|
||||||
|
else
|
||||||
|
mainLayout->addItem(endSpacerItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto loadLogButton = new QToolButton;
|
||||||
|
loadLogButton->setText(tr("Load"));
|
||||||
|
controlLayout->addWidget(loadLogButton);
|
||||||
|
connect(loadLogButton, &QToolButton::clicked, this, &QmlDebugTranslationWidget::loadLogFile);
|
||||||
|
|
||||||
|
auto saveLogButton = new QToolButton;
|
||||||
|
saveLogButton->setText(tr("Save"));
|
||||||
|
controlLayout->addWidget(saveLogButton);
|
||||||
|
connect(saveLogButton, &QToolButton::clicked, this, &QmlDebugTranslationWidget::saveLogToFile);
|
||||||
|
|
||||||
|
auto clearButton = new QToolButton;
|
||||||
|
clearButton->setText(tr("Clear"));
|
||||||
|
controlLayout->addWidget(clearButton);
|
||||||
|
connect(clearButton, &QToolButton::clicked, this, &QmlDebugTranslationWidget::clear);
|
||||||
|
|
||||||
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
|
connect(editorManager, &Core::EditorManager::currentEditorChanged, this, &QmlDebugTranslationWidget::updateCurrentEditor);
|
||||||
|
updateCurrentEditor(Core::EditorManager::currentEditor());
|
||||||
|
|
||||||
|
connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::startupProjectChanged,
|
||||||
|
this, &QmlDebugTranslationWidget::updateCurrentTranslations);
|
||||||
|
|
||||||
|
updateStartupProjectTranslations();
|
||||||
|
|
||||||
|
ProjectExplorer::TaskHub::addCategory("QmlPreview.Translation", tr("Translation issues"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlDebugTranslationWidget::~QmlDebugTranslationWidget()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::updateCurrentEditor(const Core::IEditor *editor)
|
||||||
|
{
|
||||||
|
if (editor && editor->document())
|
||||||
|
m_currentFilePath = editor->document()->filePath();
|
||||||
|
else
|
||||||
|
m_currentFilePath.clear();
|
||||||
|
m_singleFileButton->setText(singleFileButtonText(m_currentFilePath.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::updateStartupProjectTranslations()
|
||||||
|
{
|
||||||
|
updateCurrentTranslations(ProjectExplorer::SessionManager::startupProject());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::updateCurrentTranslations(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
for (int i = m_selectLanguageLayout->count()-1; i >= 0; --i) {
|
||||||
|
auto layoutItem = m_selectLanguageLayout->takeAt(i);
|
||||||
|
delete layoutItem->widget();
|
||||||
|
delete layoutItem;
|
||||||
|
}
|
||||||
|
if (!project)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(project)) {
|
||||||
|
connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed,
|
||||||
|
this, &QmlDebugTranslationWidget::updateStartupProjectTranslations,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
if (multiLanguageAspect->value()) {
|
||||||
|
m_selectLanguageLayout->addWidget(new QLabel(
|
||||||
|
tr("Current language is \'<b>%1</b>\' can be changed in the 'Translation' tab.")
|
||||||
|
.arg(multiLanguageAspect->currentLocale())));
|
||||||
|
m_testLanguages.clear();
|
||||||
|
} else {
|
||||||
|
m_selectLanguageLayout->addWidget(new QLabel(tr("Select which language should be tested:")));
|
||||||
|
QString errorMessage;
|
||||||
|
for (auto language : project->availableQmlPreviewTranslations(&errorMessage)) {
|
||||||
|
auto languageCheckBox = new QCheckBox(language);
|
||||||
|
m_selectLanguageLayout->addWidget(languageCheckBox);
|
||||||
|
connect(languageCheckBox, &QCheckBox::stateChanged, [this, language] (int state) {
|
||||||
|
if (state == Qt::Checked)
|
||||||
|
m_testLanguages.append(language);
|
||||||
|
else
|
||||||
|
m_testLanguages.removeAll(language);
|
||||||
|
});
|
||||||
|
languageCheckBox->setChecked(true);
|
||||||
|
}
|
||||||
|
m_selectLanguageLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::setFiles(const Utils::FilePaths &filePathes)
|
||||||
|
{
|
||||||
|
m_selectedFilePaths = filePathes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::runTest()
|
||||||
|
{
|
||||||
|
m_runOutputWindow->grayOutOldContent();
|
||||||
|
|
||||||
|
auto runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE);
|
||||||
|
QTC_ASSERT(runControl, qWarning("Can not create a QmlPreviewRunner"); return;);
|
||||||
|
auto previewPlugin = qobject_cast<Internal::QmlPreviewPlugin*>(getPreviewPlugin());
|
||||||
|
|
||||||
|
connect(runControl, &ProjectExplorer::RunControl::started, [this, runControl, previewPlugin]() {
|
||||||
|
//Q_ASSERT(m_currentRunControl == nullptr); //TODO: who deletes the runcontrol
|
||||||
|
m_currentRunControl = runControl;
|
||||||
|
m_runOutputWindow->setFormatter(runControl->outputFormatter());
|
||||||
|
int timerCounter = 1;
|
||||||
|
auto testLanguages = [this, previewPlugin](int timerCounter, const QString &previewedFile = QString()) {
|
||||||
|
qDebug() << "testLanguages" << previewedFile;
|
||||||
|
for (auto language : m_testLanguages) {
|
||||||
|
QTimer::singleShot(timerCounter * 1000, previewPlugin, [this, previewPlugin, language, previewedFile]() {
|
||||||
|
if (m_currentRunControl && m_currentRunControl->isRunning()) {
|
||||||
|
if (!previewedFile.isEmpty())
|
||||||
|
previewPlugin->setPreviewedFile(previewedFile);
|
||||||
|
previewPlugin->setLocale(language);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (m_multipleFileButton->isChecked()) {
|
||||||
|
for (auto filePath : m_selectedFilePaths) {
|
||||||
|
testLanguages(timerCounter++, filePath.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
testLanguages(timerCounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
connect(runControl, &ProjectExplorer::RunControl::stopped, [this]() {
|
||||||
|
m_runTestButton->setChecked(false);
|
||||||
|
//delete m_currentRunControl; // who deletes the runcontrol?
|
||||||
|
m_currentRunControl = nullptr;
|
||||||
|
if (auto previewPlugin = qobject_cast<Internal::QmlPreviewPlugin*>(getPreviewPlugin()))
|
||||||
|
previewPlugin->setLocale(m_lastUsedLanguageBeforeTest);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(runControl, &ProjectExplorer::RunControl::appendMessage,
|
||||||
|
this, &QmlDebugTranslationWidget::appendMessage);
|
||||||
|
|
||||||
|
if (auto project = ProjectExplorer::SessionManager::startupProject()) {
|
||||||
|
if (auto target = project->activeTarget()) {
|
||||||
|
if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(target))
|
||||||
|
m_lastUsedLanguageBeforeTest = multiLanguageAspect->currentLocale();
|
||||||
|
if (auto runConfiguration = target->activeRunConfiguration()) {
|
||||||
|
runControl->setRunConfiguration(runConfiguration);
|
||||||
|
if (runControl->createMainWorker()) {
|
||||||
|
previewPlugin->setLocale(QString());
|
||||||
|
runControl->initiateStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::clear()
|
||||||
|
{
|
||||||
|
m_runOutputWindow->clear();
|
||||||
|
ProjectExplorer::TaskHub::clearTasks("QmlPreview.Translation");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlDebugTranslationWidget::currentDir() const
|
||||||
|
{
|
||||||
|
return m_lastDir.isEmpty() ?
|
||||||
|
ProjectExplorer::ProjectTree::currentFilePath().parentDir().toString() : m_lastDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::setCurrentDir(const QString &path)
|
||||||
|
{
|
||||||
|
m_lastDir = path;
|
||||||
|
const QString currentDir = m_lastDir.isEmpty() ?
|
||||||
|
ProjectExplorer::ProjectTree::currentFilePath().parentDir().toString() : m_lastDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::loadLogFile()
|
||||||
|
{
|
||||||
|
const auto fileName = QFileDialog::getOpenFileName(this, QStringLiteral("Open File"), currentDir());
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
setCurrentDir(QFileInfo(fileName).absolutePath());
|
||||||
|
QFile f(fileName);
|
||||||
|
if (f.open(QFile::ReadOnly)) {
|
||||||
|
clear();
|
||||||
|
while (!f.atEnd())
|
||||||
|
appendMessage(QString::fromUtf8(f.readLine()), Utils::DebugFormat);
|
||||||
|
} else {
|
||||||
|
// TODO: maybe add this message to log and tasks
|
||||||
|
qWarning() << "Failed to open" << fileName << ":" << f.errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::saveLogToFile()
|
||||||
|
{
|
||||||
|
const QString fileName = QFileDialog::getSaveFileName(
|
||||||
|
this, tr("Choose file to save logged issues."), currentDir());
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
setCurrentDir(QFileInfo(fileName).absolutePath());
|
||||||
|
QFile f(fileName);
|
||||||
|
if (f.open(QFile::WriteOnly | QFile::Text))
|
||||||
|
f.write(m_runOutputWindow->toPlainText().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlDebugTranslationWidget::appendMessage(const QString &message, Utils::OutputFormat format)
|
||||||
|
{
|
||||||
|
const auto newLine = QRegularExpression("[\r\n]");
|
||||||
|
const auto messages = message.split(newLine, QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
if (messages.count() > 1) {
|
||||||
|
for (auto m : messages)
|
||||||
|
appendMessage(m + "\n", format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QString serviceSeperator = ": QQmlDebugTranslationService: ";
|
||||||
|
if (!message.contains(serviceSeperator) || message.contains("DebugTranslation service - language changed"))
|
||||||
|
return;
|
||||||
|
QString locationString = message;
|
||||||
|
locationString = locationString.split(serviceSeperator).first();
|
||||||
|
static const QRegularExpression qmlLineColumnLink("^(" QT_QML_URL_REGEXP ")" // url
|
||||||
|
":(\\d+)" // line
|
||||||
|
":(\\d+)$"); // column
|
||||||
|
const QRegularExpressionMatch qmlLineColumnMatch = qmlLineColumnLink.match(locationString);
|
||||||
|
|
||||||
|
auto fileLine = -1;
|
||||||
|
QUrl fileUrl;
|
||||||
|
if (qmlLineColumnMatch.hasMatch()) {
|
||||||
|
fileUrl = QUrl(qmlLineColumnMatch.captured(1));
|
||||||
|
fileLine = qmlLineColumnMatch.captured(2).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_runOutputWindow->formatter()) {
|
||||||
|
auto defaultFormatter = new Utils::OutputFormatter();
|
||||||
|
defaultFormatter->setParent(this);
|
||||||
|
m_runOutputWindow->setFormatter(defaultFormatter);
|
||||||
|
}
|
||||||
|
m_runOutputWindow->appendMessage(message, format);
|
||||||
|
|
||||||
|
|
||||||
|
auto type = ProjectExplorer::Task::TaskType::Warning;
|
||||||
|
auto description = message.split(serviceSeperator).at(1);
|
||||||
|
auto filePath = Utils::FilePath::fromString(fileUrl.toLocalFile());
|
||||||
|
auto category = "QmlPreview.Translation";
|
||||||
|
auto icon = Utils::Icons::WARNING.icon();
|
||||||
|
|
||||||
|
ProjectExplorer::TaskHub::addTask(ProjectExplorer::Task(type,
|
||||||
|
description,
|
||||||
|
filePath,
|
||||||
|
fileLine,
|
||||||
|
category,
|
||||||
|
icon,
|
||||||
|
ProjectExplorer::Task::NoOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlDebugTranslationWidget::singleFileButtonText(const QString &filePath)
|
||||||
|
{
|
||||||
|
auto buttonText = tr("current file: %1");
|
||||||
|
if (filePath.isEmpty())
|
||||||
|
return buttonText.arg(tr("empty"));
|
||||||
|
return buttonText.arg(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlDebugTranslationWidget::runButtonText(bool isRunning)
|
||||||
|
{
|
||||||
|
if (isRunning) {
|
||||||
|
return tr("Stop");
|
||||||
|
}
|
||||||
|
return tr("Run language tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlPreview
|
95
src/plugins/qmlpreview/qmldebugtranslationwidget.h
Normal file
95
src/plugins/qmlpreview/qmldebugtranslationwidget.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <utils/fileutils.h>
|
||||||
|
#include <utils/outputformat.h>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QRadioButton;
|
||||||
|
class QPushButton;
|
||||||
|
class QHBoxLayout;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class IEditor;
|
||||||
|
class OutputWindow;
|
||||||
|
}
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class Project;
|
||||||
|
class RunControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlPreview {
|
||||||
|
|
||||||
|
class QMLPREVIEW_EXPORT QmlDebugTranslationWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QmlDebugTranslationWidget(QWidget *parent = nullptr);
|
||||||
|
~QmlDebugTranslationWidget() override;
|
||||||
|
|
||||||
|
void setCurrentFile(const Utils::FilePath &filepath);
|
||||||
|
void setFiles(const Utils::FilePaths &filePathes);
|
||||||
|
void updateStartupProjectTranslations();
|
||||||
|
private:
|
||||||
|
void updateCurrentEditor(const Core::IEditor *editor);
|
||||||
|
void updateCurrentTranslations(ProjectExplorer::Project *project);
|
||||||
|
void runTest();
|
||||||
|
void appendMessage(const QString &message, Utils::OutputFormat format);
|
||||||
|
void clear();
|
||||||
|
void loadLogFile();
|
||||||
|
void saveLogToFile();
|
||||||
|
QString currentDir() const;
|
||||||
|
void setCurrentDir(const QString &path);
|
||||||
|
|
||||||
|
QString singleFileButtonText(const QString &filePath);
|
||||||
|
QString runButtonText(bool isRunning = false);
|
||||||
|
|
||||||
|
QStringList m_testLanguages;
|
||||||
|
QString m_lastUsedLanguageBeforeTest;
|
||||||
|
bool m_elideWarning = false;
|
||||||
|
|
||||||
|
Core::OutputWindow *m_runOutputWindow = nullptr;
|
||||||
|
|
||||||
|
QRadioButton *m_singleFileButton = nullptr;
|
||||||
|
QRadioButton *m_multipleFileButton = nullptr;
|
||||||
|
QPushButton *m_runTestButton = nullptr;
|
||||||
|
|
||||||
|
Utils::FilePath m_currentFilePath;
|
||||||
|
Utils::FilePaths m_selectedFilePaths;
|
||||||
|
ProjectExplorer::RunControl *m_currentRunControl = nullptr;
|
||||||
|
|
||||||
|
QString m_lastDir;
|
||||||
|
|
||||||
|
QHBoxLayout *m_selectLanguageLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlPreview
|
@@ -10,19 +10,23 @@ include(tests/tests.pri)
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
qmlpreview_global.h \
|
qmlpreview_global.h \
|
||||||
qmldebugtranslationclient.h \
|
qmldebugtranslationclient.h \
|
||||||
|
qmldebugtranslationwidget.h \
|
||||||
qmlpreviewclient.h \
|
qmlpreviewclient.h \
|
||||||
qmlpreviewplugin.h \
|
qmlpreviewplugin.h \
|
||||||
qmlpreviewruncontrol.h \
|
qmlpreviewruncontrol.h \
|
||||||
qmlpreviewconnectionmanager.h \
|
qmlpreviewconnectionmanager.h \
|
||||||
qmlpreviewfileontargetfinder.h
|
qmlpreviewfileontargetfinder.h \
|
||||||
|
projectfileselectionswidget.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
qmlpreviewplugin.cpp \
|
qmlpreviewplugin.cpp \
|
||||||
qmldebugtranslationclient.cpp \
|
qmldebugtranslationclient.cpp \
|
||||||
|
qmldebugtranslationwidget.cpp \
|
||||||
qmlpreviewclient.cpp \
|
qmlpreviewclient.cpp \
|
||||||
qmlpreviewruncontrol.cpp \
|
qmlpreviewruncontrol.cpp \
|
||||||
qmlpreviewconnectionmanager.cpp \
|
qmlpreviewconnectionmanager.cpp \
|
||||||
qmlpreviewfileontargetfinder.cpp
|
qmlpreviewfileontargetfinder.cpp \
|
||||||
|
projectfileselectionswidget.cpp
|
||||||
|
|
||||||
OTHER_FILES += \
|
OTHER_FILES += \
|
||||||
QmlPreview.json.in
|
QmlPreview.json.in
|
||||||
|
@@ -26,6 +26,8 @@ QtcPlugin {
|
|||||||
"qmlpreviewclient.h",
|
"qmlpreviewclient.h",
|
||||||
"qmldebugtranslationclient.cpp",
|
"qmldebugtranslationclient.cpp",
|
||||||
"qmldebugtranslationclient.h",
|
"qmldebugtranslationclient.h",
|
||||||
|
"qmldebugtranslationwidget.cpp",
|
||||||
|
"qmldebugtranslationwidget.h",
|
||||||
"qmlpreviewconnectionmanager.cpp",
|
"qmlpreviewconnectionmanager.cpp",
|
||||||
"qmlpreviewconnectionmanager.h",
|
"qmlpreviewconnectionmanager.h",
|
||||||
"qmlpreviewfileontargetfinder.cpp",
|
"qmlpreviewfileontargetfinder.cpp",
|
||||||
@@ -35,6 +37,8 @@ QtcPlugin {
|
|||||||
"qmlpreviewplugin.h",
|
"qmlpreviewplugin.h",
|
||||||
"qmlpreviewruncontrol.cpp",
|
"qmlpreviewruncontrol.cpp",
|
||||||
"qmlpreviewruncontrol.h",
|
"qmlpreviewruncontrol.h",
|
||||||
|
"projectfileselectionswidget.cpp",
|
||||||
|
"projectfileselectionswidget.h"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -116,7 +116,7 @@ QUrl QmlPreviewConnectionManager::findValidI18nDirectoryAsUrl(const QString &loc
|
|||||||
void QmlPreviewConnectionManager::createDebugTranslationClient()
|
void QmlPreviewConnectionManager::createDebugTranslationClient()
|
||||||
{
|
{
|
||||||
m_qmlDebugTranslationClient = new QmlDebugTranslationClient(connection());
|
m_qmlDebugTranslationClient = new QmlDebugTranslationClient(connection());
|
||||||
QObject::connect(this, &QmlPreviewConnectionManager::language,
|
connect(this, &QmlPreviewConnectionManager::language,
|
||||||
m_qmlDebugTranslationClient.data(), [this](const QString &locale) {
|
m_qmlDebugTranslationClient.data(), [this](const QString &locale) {
|
||||||
|
|
||||||
if (m_lastLoadedUrl.isEmpty()) {
|
if (m_lastLoadedUrl.isEmpty()) {
|
||||||
@@ -128,7 +128,10 @@ void QmlPreviewConnectionManager::createDebugTranslationClient()
|
|||||||
m_qmlDebugTranslationClient->changeLanguage(findValidI18nDirectoryAsUrl(locale), locale);
|
m_qmlDebugTranslationClient->changeLanguage(findValidI18nDirectoryAsUrl(locale), locale);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
QObject::connect(m_qmlDebugTranslationClient.data(), &QmlDebugTranslationClient::debugServiceUnavailable,
|
connect(this, &QmlPreviewConnectionManager::changeElideWarning,
|
||||||
|
m_qmlDebugTranslationClient, &QmlDebugTranslationClient::changeElideWarning);
|
||||||
|
|
||||||
|
connect(m_qmlDebugTranslationClient.data(), &QmlDebugTranslationClient::debugServiceUnavailable,
|
||||||
this, []() {
|
this, []() {
|
||||||
QMessageBox::warning(Core::ICore::dialogParent(), "Error connect to QML DebugTranslation service",
|
QMessageBox::warning(Core::ICore::dialogParent(), "Error connect to QML DebugTranslation service",
|
||||||
"QML DebugTranslation feature is not available for this version of Qt.");
|
"QML DebugTranslation feature is not available for this version of Qt.");
|
||||||
@@ -139,8 +142,7 @@ void QmlPreviewConnectionManager::createPreviewClient()
|
|||||||
{
|
{
|
||||||
m_qmlPreviewClient = new QmlPreviewClient(connection());
|
m_qmlPreviewClient = new QmlPreviewClient(connection());
|
||||||
|
|
||||||
QObject::connect(
|
connect(this, &QmlPreviewConnectionManager::loadFile, m_qmlPreviewClient.data(),
|
||||||
this, &QmlPreviewConnectionManager::loadFile, m_qmlPreviewClient.data(),
|
|
||||||
[this](const QString &filename, const QString &changedFile,
|
[this](const QString &filename, const QString &changedFile,
|
||||||
const QByteArray &contents) {
|
const QByteArray &contents) {
|
||||||
if (!m_fileClassifier(changedFile)) {
|
if (!m_fileClassifier(changedFile)) {
|
||||||
@@ -163,13 +165,13 @@ void QmlPreviewConnectionManager::createPreviewClient()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(this, &QmlPreviewConnectionManager::rerun,
|
connect(this, &QmlPreviewConnectionManager::rerun,
|
||||||
m_qmlPreviewClient.data(), &QmlPreviewClient::rerun);
|
m_qmlPreviewClient.data(), &QmlPreviewClient::rerun);
|
||||||
|
|
||||||
QObject::connect(this, &QmlPreviewConnectionManager::zoom,
|
connect(this, &QmlPreviewConnectionManager::zoom,
|
||||||
m_qmlPreviewClient.data(), &QmlPreviewClient::zoom);
|
m_qmlPreviewClient.data(), &QmlPreviewClient::zoom);
|
||||||
|
|
||||||
QObject::connect(this, &QmlPreviewConnectionManager::language,
|
connect(this, &QmlPreviewConnectionManager::language,
|
||||||
m_qmlPreviewClient.data(), [this](const QString &locale) {
|
m_qmlPreviewClient.data(), [this](const QString &locale) {
|
||||||
|
|
||||||
if (m_lastLoadedUrl.isEmpty()) {
|
if (m_lastLoadedUrl.isEmpty()) {
|
||||||
@@ -182,7 +184,7 @@ void QmlPreviewConnectionManager::createPreviewClient()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::pathRequested,
|
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) {
|
||||||
@@ -212,13 +214,13 @@ void QmlPreviewConnectionManager::createPreviewClient()
|
|||||||
m_qmlPreviewClient->announceError(path);
|
m_qmlPreviewClient->announceError(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::errorReported,
|
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_qmlPreviewClient.data(), &QmlPreviewClient::fpsReported,
|
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[] = {
|
||||||
@@ -229,13 +231,13 @@ void QmlPreviewConnectionManager::createPreviewClient()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(m_qmlPreviewClient.data(), &QmlPreviewClient::debugServiceUnavailable,
|
connect(m_qmlPreviewClient.data(), &QmlPreviewClient::debugServiceUnavailable,
|
||||||
this, []() {
|
this, []() {
|
||||||
QMessageBox::warning(Core::ICore::dialogParent(), "Error loading QML Live Preview",
|
QMessageBox::warning(Core::ICore::dialogParent(), "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,
|
connect(&m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged,
|
||||||
m_qmlPreviewClient.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;
|
||||||
|
@@ -57,6 +57,7 @@ signals:
|
|||||||
void loadFile(const QString &filename, const QString &changedFile, const QByteArray &contents);
|
void loadFile(const QString &filename, const QString &changedFile, const QByteArray &contents);
|
||||||
void zoom(float zoomFactor);
|
void zoom(float zoomFactor);
|
||||||
void language(const QString &locale);
|
void language(const QString &locale);
|
||||||
|
void changeElideWarning(bool elideWarning);
|
||||||
void rerun();
|
void rerun();
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
|
@@ -26,11 +26,14 @@
|
|||||||
#include "qmlpreviewplugin.h"
|
#include "qmlpreviewplugin.h"
|
||||||
#include "qmlpreviewruncontrol.h"
|
#include "qmlpreviewruncontrol.h"
|
||||||
|
|
||||||
|
#include "qmldebugtranslationwidget.h"
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
#include "tests/qmlpreviewclient_test.h"
|
#include "tests/qmlpreviewclient_test.h"
|
||||||
#include "tests/qmlpreviewplugin_test.h"
|
#include "tests/qmlpreviewplugin_test.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
@@ -54,6 +57,11 @@
|
|||||||
#include <qmljstools/qmljstoolsconstants.h>
|
#include <qmljstools/qmljstoolsconstants.h>
|
||||||
|
|
||||||
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
|
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
|
||||||
|
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
#include <qtsupport/qtversionmanager.h>
|
||||||
|
#include <qtsupport/baseqtversion.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -143,6 +151,8 @@ public:
|
|||||||
float m_zoomFactor = -1.0;
|
float m_zoomFactor = -1.0;
|
||||||
QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr;
|
QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr;
|
||||||
QString m_locale;
|
QString m_locale;
|
||||||
|
bool elideWarning = false;
|
||||||
|
QPointer<QmlDebugTranslationWidget> m_qmlDebugTranslationWidget;
|
||||||
|
|
||||||
RunWorkerFactory localRunWorkerFactory{
|
RunWorkerFactory localRunWorkerFactory{
|
||||||
RunWorkerFactory::make<LocalQmlPreviewSupport>(),
|
RunWorkerFactory::make<LocalQmlPreviewSupport>(),
|
||||||
@@ -165,6 +175,8 @@ public:
|
|||||||
runner, &QmlPreviewRunner::zoom);
|
runner, &QmlPreviewRunner::zoom);
|
||||||
connect(q, &QmlPreviewPlugin::localeChanged,
|
connect(q, &QmlPreviewPlugin::localeChanged,
|
||||||
runner, &QmlPreviewRunner::language);
|
runner, &QmlPreviewRunner::language);
|
||||||
|
connect(q, &QmlPreviewPlugin::elideWarningChanged,
|
||||||
|
runner, &QmlPreviewRunner::changeElideWarning);
|
||||||
|
|
||||||
connect(runner, &RunWorker::started, this, [this, runControl] {
|
connect(runner, &RunWorker::started, this, [this, runControl] {
|
||||||
addPreview(runControl);
|
addPreview(runControl);
|
||||||
@@ -199,10 +211,54 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
|
|||||||
|
|
||||||
ProjectExplorerPlugin::runStartupProject(Constants::QML_PREVIEW_RUN_MODE);
|
ProjectExplorerPlugin::runStartupProject(Constants::QML_PREVIEW_RUN_MODE);
|
||||||
});
|
});
|
||||||
menu->addAction(Core::ActionManager::registerAction(action, "QmlPreview.Internal"),
|
menu->addAction(
|
||||||
|
Core::ActionManager::registerAction(action, "QmlPreview.RunPreview"),
|
||||||
Constants::G_BUILD_RUN);
|
Constants::G_BUILD_RUN);
|
||||||
|
|
||||||
Core::Context projectTreeContext(Constants::C_PROJECT_TREE);
|
action = new QAction(QmlPreviewPlugin::tr("Test translations"), this);
|
||||||
|
action->setToolTip(QLatin1String("Runs the preview with all available translations and collects all issues."));
|
||||||
|
action->setEnabled(SessionManager::startupProject() != nullptr);
|
||||||
|
connect(SessionManager::instance(), &SessionManager::startupProjectChanged, action,
|
||||||
|
&QAction::setEnabled);
|
||||||
|
connect(action, &QAction::triggered, this, [this]() {
|
||||||
|
if (SessionManager::startupProject()) {
|
||||||
|
// Deletion for this widget is taken care of in aboutToShutdown() and registerWindow()
|
||||||
|
m_qmlDebugTranslationWidget = new QmlDebugTranslationWidget();
|
||||||
|
Core::ICore::registerWindow(m_qmlDebugTranslationWidget, Core::Context("Core.DebugTranslation"));
|
||||||
|
m_qmlDebugTranslationWidget->show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu->addAction(
|
||||||
|
Core::ActionManager::registerAction(action, "QmlPreview.TestTranslations"),
|
||||||
|
Constants::G_BUILD_RUN);
|
||||||
|
auto updateTestTranslationAction = [action]() {
|
||||||
|
bool showTestTranslationAction = false;
|
||||||
|
bool enableTestTranslationAction = false;
|
||||||
|
QtSupport::BaseQtVersion *activeQt{};
|
||||||
|
if (auto project = SessionManager::startupProject()) {
|
||||||
|
if (auto target = project->activeTarget()) {
|
||||||
|
if (auto activeKit = target->kit())
|
||||||
|
activeQt = QtSupport::QtKitAspect::qtVersion(activeKit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto qtVersion : QtSupport::QtVersionManager::versions()) {
|
||||||
|
if (qtVersion->features().contains("QtStudio")) {
|
||||||
|
showTestTranslationAction = true;
|
||||||
|
if (qtVersion == activeQt)
|
||||||
|
enableTestTranslationAction = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action->setVisible(showTestTranslationAction);
|
||||||
|
action->setEnabled(enableTestTranslationAction);
|
||||||
|
};
|
||||||
|
connect(ProjectExplorer::SessionManager::instance(),
|
||||||
|
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||||
|
updateTestTranslationAction);
|
||||||
|
|
||||||
|
connect(QtSupport::QtVersionManager::instance(),
|
||||||
|
&QtSupport::QtVersionManager::qtVersionsChanged,
|
||||||
|
updateTestTranslationAction);
|
||||||
|
|
||||||
menu = Core::ActionManager::actionContainer(Constants::M_FILECONTEXT);
|
menu = Core::ActionManager::actionContainer(Constants::M_FILECONTEXT);
|
||||||
action = new QAction(QmlPreviewPlugin::tr("Preview File"), this);
|
action = new QAction(QmlPreviewPlugin::tr("Preview File"), this);
|
||||||
action->setEnabled(false);
|
action->setEnabled(false);
|
||||||
@@ -211,8 +267,8 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
|
|||||||
action->setEnabled(!previews.isEmpty());
|
action->setEnabled(!previews.isEmpty());
|
||||||
});
|
});
|
||||||
connect(action, &QAction::triggered, this, &QmlPreviewPluginPrivate::previewCurrentFile);
|
connect(action, &QAction::triggered, this, &QmlPreviewPluginPrivate::previewCurrentFile);
|
||||||
menu->addAction(Core::ActionManager::registerAction(action, "QmlPreview.Preview",
|
menu->addAction(
|
||||||
projectTreeContext),
|
Core::ActionManager::registerAction(action, "QmlPreview.PreviewFile", Core::Context(Constants::C_PROJECT_TREE)),
|
||||||
Constants::G_FILE_OTHER);
|
Constants::G_FILE_OTHER);
|
||||||
action->setVisible(false);
|
action->setVisible(false);
|
||||||
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, action, [action]() {
|
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, action, [action]() {
|
||||||
@@ -251,6 +307,7 @@ ExtensionSystem::IPlugin::ShutdownFlag QmlPreviewPlugin::aboutToShutdown()
|
|||||||
{
|
{
|
||||||
d->m_parseThread.quit();
|
d->m_parseThread.quit();
|
||||||
d->m_parseThread.wait();
|
d->m_parseThread.wait();
|
||||||
|
delete d->m_qmlDebugTranslationWidget;
|
||||||
return SynchronousShutdown;
|
return SynchronousShutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +403,16 @@ void QmlPreviewPlugin::setLocale(const QString &locale)
|
|||||||
emit localeChanged(d->m_locale);
|
emit localeChanged(d->m_locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmlPreviewPlugin::elideWarning() const
|
||||||
|
{
|
||||||
|
return d->elideWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlPreviewPlugin::changeElideWarning(bool elideWarning)
|
||||||
|
{
|
||||||
|
d->elideWarning = elideWarning;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader)
|
void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader)
|
||||||
{
|
{
|
||||||
if (d->m_fileLoader == fileLoader)
|
if (d->m_fileLoader == fileLoader)
|
||||||
|
@@ -59,6 +59,7 @@ class QmlPreviewPlugin : public ExtensionSystem::IPlugin
|
|||||||
WRITE setFpsHandler NOTIFY fpsHandlerChanged)
|
WRITE setFpsHandler NOTIFY fpsHandlerChanged)
|
||||||
Q_PROPERTY(float zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
|
Q_PROPERTY(float zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
|
||||||
Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged)
|
Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged)
|
||||||
|
Q_PROPERTY(bool elideWarning READ elideWarning WRITE changeElideWarning NOTIFY elideWarningChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~QmlPreviewPlugin() override;
|
~QmlPreviewPlugin() override;
|
||||||
@@ -86,6 +87,9 @@ public:
|
|||||||
QString locale() const;
|
QString locale() const;
|
||||||
void setLocale(const QString &locale);
|
void setLocale(const QString &locale);
|
||||||
|
|
||||||
|
bool elideWarning() const;
|
||||||
|
void changeElideWarning(bool elideWarning);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void checkDocument(const QString &name, const QByteArray &contents,
|
void checkDocument(const QString &name, const QByteArray &contents,
|
||||||
QmlJS::Dialect::Enum dialect);
|
QmlJS::Dialect::Enum dialect);
|
||||||
@@ -100,6 +104,7 @@ signals:
|
|||||||
|
|
||||||
void zoomFactorChanged(float zoomFactor);
|
void zoomFactorChanged(float zoomFactor);
|
||||||
void localeChanged(const QString &locale);
|
void localeChanged(const QString &locale);
|
||||||
|
void elideWarningChanged(bool elideWarning);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class QmlPreviewPluginPrivate *d = nullptr;
|
class QmlPreviewPluginPrivate *d = nullptr;
|
||||||
|
@@ -66,6 +66,9 @@ QmlPreviewRunner::QmlPreviewRunner(ProjectExplorer::RunControl *runControl,
|
|||||||
&m_connectionManager, &Internal::QmlPreviewConnectionManager::zoom);
|
&m_connectionManager, &Internal::QmlPreviewConnectionManager::zoom);
|
||||||
connect(this, &QmlPreviewRunner::language,
|
connect(this, &QmlPreviewRunner::language,
|
||||||
&m_connectionManager, &Internal::QmlPreviewConnectionManager::language);
|
&m_connectionManager, &Internal::QmlPreviewConnectionManager::language);
|
||||||
|
connect(this, &QmlPreviewRunner::changeElideWarning,
|
||||||
|
&m_connectionManager, &Internal::QmlPreviewConnectionManager::changeElideWarning);
|
||||||
|
|
||||||
connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::connectionOpened,
|
connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::connectionOpened,
|
||||||
this, [this, initialZoom]() {
|
this, [this, initialZoom]() {
|
||||||
if (initialZoom > 0)
|
if (initialZoom > 0)
|
||||||
|
@@ -51,7 +51,7 @@ signals:
|
|||||||
void zoom(float zoomFactor);
|
void zoom(float zoomFactor);
|
||||||
void rerun();
|
void rerun();
|
||||||
void ready();
|
void ready();
|
||||||
|
void changeElideWarning(bool elideWarning);
|
||||||
private:
|
private:
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
Reference in New Issue
Block a user