forked from qt-creator/qt-creator
AssetExporter: Add basic infrastructure for the plugin
Adds export action, basic UI and workflow classes Change-Id: If019a8fa48cacaf7e7665335c53b3adeeb257b07 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -0,0 +1,94 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetexportdialog.h"
|
||||||
|
#include "ui_assetexportdialog.h"
|
||||||
|
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
AssetExportDialog::AssetExportDialog(const Utils::FilePath &exportPath,
|
||||||
|
AssetExporter &assetExporter, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
m_assetExporter(assetExporter),
|
||||||
|
m_ui(new Ui::AssetExportDialog),
|
||||||
|
m_model(this)
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
||||||
|
|
||||||
|
m_ui->filesView->setModel(&m_model);
|
||||||
|
|
||||||
|
m_exportBtn = m_ui->buttonBox->addButton(tr("Export"), QDialogButtonBox::AcceptRole);
|
||||||
|
m_exportBtn->setEnabled(false);
|
||||||
|
connect(m_exportBtn, &QPushButton::clicked, this, &AssetExportDialog::onExport);
|
||||||
|
m_ui->exportPathEdit->setText(exportPath.toString());
|
||||||
|
|
||||||
|
connect(&m_assetExporter, &AssetExporter::qmlFileResult, this, [this] (const Utils::FilePath &path) {
|
||||||
|
m_qmlFiles.append(path);
|
||||||
|
QStringList files = m_model.stringList();
|
||||||
|
files.append(path.toString());
|
||||||
|
m_model.setStringList(files);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(&m_assetExporter, &AssetExporter::stateChanged,
|
||||||
|
this, &AssetExportDialog::onExportStateChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetExportDialog::~AssetExportDialog()
|
||||||
|
{
|
||||||
|
m_assetExporter.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExportDialog::onExport()
|
||||||
|
{
|
||||||
|
m_assetExporter.exportQml(m_qmlFiles,
|
||||||
|
Utils::FilePath::fromString(m_ui->exportPathEdit->text()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExportDialog::onExportStateChanged(AssetExporter::ParsingState newState)
|
||||||
|
{
|
||||||
|
switch (newState) {
|
||||||
|
case AssetExporter::ParsingState::PreProcessing:
|
||||||
|
m_model.setStringList({});
|
||||||
|
break;
|
||||||
|
case AssetExporter::ParsingState::ExportingDone:
|
||||||
|
QMessageBox::information(this, tr("QML Export"), tr("Done"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_exportBtn->setEnabled(newState == AssetExporter::ParsingState::PreProcessingFinished ||
|
||||||
|
newState == AssetExporter::ParsingState::ExportingDone);
|
||||||
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(m_assetExporter.isBusy());
|
||||||
|
}
|
||||||
|
}
|
@@ -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 "assetexporter.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QStringListModel>
|
||||||
|
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QPushButton;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AssetExportDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class AssetExportDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AssetExportDialog(const Utils::FilePath &exportPath, AssetExporter &assetExporter,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
~AssetExportDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onExport();
|
||||||
|
void onExportStateChanged(AssetExporter::ParsingState newState);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AssetExporter &m_assetExporter;
|
||||||
|
std::unique_ptr<Ui::AssetExportDialog> m_ui;
|
||||||
|
QPushButton *m_exportBtn = nullptr;
|
||||||
|
QStringListModel m_model;
|
||||||
|
Utils::FilePaths m_qmlFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AssetExportDialog</class>
|
||||||
|
<widget class="QDialog" name="AssetExportDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>768</width>
|
||||||
|
<height>480</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Export QML</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QListView" name="filesView"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLineEdit" name="exportPathEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
255
src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp
Normal file
255
src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetexporter.h"
|
||||||
|
#include "componentexporter.h"
|
||||||
|
|
||||||
|
#include "plaintexteditmodifier.h"
|
||||||
|
#include "rewriterview.h"
|
||||||
|
|
||||||
|
#include "projectexplorer/project.h"
|
||||||
|
#include "projectexplorer/projectnodes.h"
|
||||||
|
|
||||||
|
#include "utils/runextensions.h"
|
||||||
|
#include "utils/qtcassert.h"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.assetExporter", QtInfoMsg)
|
||||||
|
Q_LOGGING_CATEGORY(loggerWarn, "qtc.designer.assetExportPlugin.assetExporter", QtWarningMsg)
|
||||||
|
Q_LOGGING_CATEGORY(loggerError, "qtc.designer.assetExportPlugin.assetExporter", QtCriticalMsg)
|
||||||
|
|
||||||
|
void findQmlFiles(QFutureInterface<Utils::FilePath> &f, const Project *project)
|
||||||
|
{
|
||||||
|
if (!project && !f.isCanceled())
|
||||||
|
f.reportFinished({});
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
Utils::FilePaths qmlFiles = project->files([&f, &index](const Node* node) ->bool {
|
||||||
|
if (f.isCanceled())
|
||||||
|
return false;
|
||||||
|
Utils::FilePath path = node->filePath();
|
||||||
|
bool isComponent = !path.fileName().isEmpty() && path.fileName().front().isUpper();
|
||||||
|
if (isComponent && node->filePath().endsWith(".ui.qml"))
|
||||||
|
f.reportResult(path, index++);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
f.reportFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
//static QmlDesigner::Model* createModel(const Utils::FilePath &fileName)
|
||||||
|
//{
|
||||||
|
// QmlDesigner::Model *model = QmlDesigner::Model::create("Item", 2, 7);
|
||||||
|
|
||||||
|
// Utils::FileReader reader;
|
||||||
|
// QTC_ASSERT(reader.fetch(fileName.toString()), return nullptr);
|
||||||
|
|
||||||
|
// auto textEdit = new QPlainTextEdit;
|
||||||
|
// textEdit->setPlainText(QString::fromUtf8(reader.data()));
|
||||||
|
|
||||||
|
// auto modifier = new QmlDesigner::NotIndentingTextEditModifier(textEdit);
|
||||||
|
// modifier->setParent(model);
|
||||||
|
|
||||||
|
// auto rewriterView = new QmlDesigner::RewriterView(QmlDesigner::RewriterView::Validate, model);
|
||||||
|
// rewriterView->setCheckSemanticErrors(false);
|
||||||
|
// rewriterView->setTextModifier(modifier);
|
||||||
|
|
||||||
|
// model->attachView(rewriterView);
|
||||||
|
|
||||||
|
// QTC_ASSERT(rewriterView->rootModelNode().isValid(), return nullptr);
|
||||||
|
// return model;
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
AssetExporter::AssetExporter(AssetExporterView *view, ProjectExplorer::Project *project, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_currentState(*this),
|
||||||
|
m_project(project),
|
||||||
|
m_view(view)
|
||||||
|
{
|
||||||
|
connect(m_view, &AssetExporterView::loadingFinished, this, &AssetExporter::onQmlFileLoaded);
|
||||||
|
connect(m_view, &AssetExporterView::loadingError, this, &AssetExporter::notifyLoadError);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetExporter::~AssetExporter()
|
||||||
|
{
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetExporter::preProcessProject()
|
||||||
|
{
|
||||||
|
if (m_preprocessWatcher && !m_preprocessWatcher->isCanceled() &&
|
||||||
|
!m_preprocessWatcher->isFinished()) {
|
||||||
|
qCDebug(loggerInfo) << "Previous pre-processing not finished.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentState.change(ParsingState::PreProcessing);
|
||||||
|
m_preprocessWatcher.reset(new QFutureWatcher<Utils::FilePath>(this));
|
||||||
|
connect(m_preprocessWatcher.get(), &QFutureWatcher<Utils::FilePath>::resultReadyAt, this,
|
||||||
|
[this](int index) {
|
||||||
|
emit qmlFileResult(m_preprocessWatcher->resultAt(index));
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_preprocessWatcher.get(), &QFutureWatcher<Utils::FilePath>::finished, this,
|
||||||
|
[this] () { m_currentState.change(ParsingState::PreProcessingFinished); });
|
||||||
|
|
||||||
|
QFuture<Utils::FilePath> f = Utils::runAsync(&findQmlFiles, m_project);
|
||||||
|
m_preprocessWatcher->setFuture(f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::exportQml(const Utils::FilePaths &qmlFiles, const Utils::FilePath &exportPath,
|
||||||
|
bool exportAssets)
|
||||||
|
{
|
||||||
|
// TODO Asset export
|
||||||
|
Q_UNUSED(exportAssets);
|
||||||
|
m_exportFiles = qmlFiles;
|
||||||
|
m_components = QJsonArray();
|
||||||
|
m_exportPath = exportPath;
|
||||||
|
m_currentState.change(ParsingState::Parsing);
|
||||||
|
triggerLoadNextFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::cancel()
|
||||||
|
{
|
||||||
|
if (m_preprocessWatcher && !m_preprocessWatcher->isCanceled() &&
|
||||||
|
!m_preprocessWatcher->isFinished()) {
|
||||||
|
m_preprocessWatcher->cancel();
|
||||||
|
m_preprocessWatcher->waitForFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetExporter::isBusy() const
|
||||||
|
{
|
||||||
|
return m_currentState == AssetExporter::ParsingState::PreProcessing ||
|
||||||
|
m_currentState == AssetExporter::ParsingState::Parsing ||
|
||||||
|
m_currentState == AssetExporter::ParsingState::ExportingAssets ||
|
||||||
|
m_currentState == AssetExporter::ParsingState::WritingJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::exportComponent(const ModelNode &rootNode)
|
||||||
|
{
|
||||||
|
qCDebug(loggerInfo) << "Exporting component" << rootNode.id();
|
||||||
|
ComponentExporter exporter(rootNode);
|
||||||
|
QJsonObject json = exporter.exportComponent();
|
||||||
|
m_components.append(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::notifyLoadError(AssetExporterView::LoadState state)
|
||||||
|
{
|
||||||
|
QString errorStr = tr("Unknown error.");
|
||||||
|
switch (state) {
|
||||||
|
case AssetExporterView::LoadState::Exausted:
|
||||||
|
errorStr = tr("Loading file is taking too long.");
|
||||||
|
break;
|
||||||
|
case AssetExporterView::LoadState::QmlErrorState:
|
||||||
|
errorStr = tr("Cannot parse. QML file has errors.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO. Communicate errors to user
|
||||||
|
qCDebug(loggerError) << "QML load error:" << errorStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::onQmlFileLoaded()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_view && m_view->model(), qCDebug(loggerError) << "Null model"; return);
|
||||||
|
qCDebug(loggerInfo) << "Qml file load done" << m_view->model()->fileUrl();
|
||||||
|
exportComponent(m_view->rootModelNode());
|
||||||
|
triggerLoadNextFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::triggerLoadNextFile()
|
||||||
|
{
|
||||||
|
QTimer::singleShot(0, this, &AssetExporter::loadNextFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::loadNextFile()
|
||||||
|
{
|
||||||
|
if (m_exportFiles.isEmpty()) {
|
||||||
|
m_currentState.change(ParsingState::ParsingFinished);
|
||||||
|
writeMetadata();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the next pending file.
|
||||||
|
const Utils::FilePath file = m_exportFiles.takeFirst();
|
||||||
|
qCDebug(loggerInfo) << "Loading next file" << file;
|
||||||
|
m_view->loadQmlFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::writeMetadata() const
|
||||||
|
{
|
||||||
|
qCDebug(loggerInfo) << "Writing metadata";
|
||||||
|
m_currentState.change(ParsingState::WritingJson);
|
||||||
|
QJsonObject jsonRoot; // TODO: Write plugin info to root
|
||||||
|
jsonRoot.insert("artboards", m_components);
|
||||||
|
QJsonDocument doc(jsonRoot);
|
||||||
|
if (doc.isNull() || doc.isEmpty()) {
|
||||||
|
qCDebug(loggerWarn) << "Empty JSON document";
|
||||||
|
} else {
|
||||||
|
Utils::FileSaver saver(m_exportPath.toString(), QIODevice::Text);
|
||||||
|
saver.write(doc.toJson(QJsonDocument::Indented));
|
||||||
|
if (!saver.finalize()) {
|
||||||
|
qCDebug(loggerError) << "Cannot write Metadata file: " << saver.errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_currentState.change(ParsingState::ExportingDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetExporter::State::State(AssetExporter &exporter) :
|
||||||
|
m_assetExporter(exporter)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporter::State::change(const ParsingState &state)
|
||||||
|
{
|
||||||
|
qCDebug(loggerInfo()) << "Assetimporter State change: Old: " << m_state << "New: " << state;
|
||||||
|
if (m_state != state) {
|
||||||
|
m_state = state;
|
||||||
|
m_assetExporter.stateChanged(m_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug os, const AssetExporter::ParsingState &s)
|
||||||
|
{
|
||||||
|
os << static_cast<std::underlying_type<QmlDesigner::AssetExporter::ParsingState>::type>(s);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
src/plugins/qmldesigner/assetexporterplugin/assetexporter.h
Normal file
105
src/plugins/qmldesigner/assetexporterplugin/assetexporter.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetexporterview.h"
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QJsonArray;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class Project;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class AssetExporter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class ParsingState {
|
||||||
|
Idle = 0,
|
||||||
|
PreProcessing,
|
||||||
|
PreProcessingFinished,
|
||||||
|
Parsing,
|
||||||
|
ParsingFinished,
|
||||||
|
ExportingAssets,
|
||||||
|
ExportingAssetsFinished,
|
||||||
|
WritingJson,
|
||||||
|
ExportingDone
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetExporter(AssetExporterView *view, ProjectExplorer::Project *project,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
~AssetExporter();
|
||||||
|
|
||||||
|
bool preProcessProject();
|
||||||
|
void exportQml(const Utils::FilePaths &qmlFiles, const Utils::FilePath &exportPath, bool exportAssets = false);
|
||||||
|
|
||||||
|
void cancel();
|
||||||
|
bool isBusy() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void qmlFileResult(Utils::FilePath);
|
||||||
|
void stateChanged(ParsingState);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ParsingState currentState() const { return m_currentState.m_state; }
|
||||||
|
void exportComponent(const ModelNode &rootNode);
|
||||||
|
void writeMetadata() const;
|
||||||
|
void notifyLoadError(AssetExporterView::LoadState state);
|
||||||
|
void triggerLoadNextFile();
|
||||||
|
void loadNextFile();
|
||||||
|
|
||||||
|
void onQmlFileLoaded();
|
||||||
|
private:
|
||||||
|
mutable class State {
|
||||||
|
public:
|
||||||
|
State(AssetExporter&);
|
||||||
|
void change(const ParsingState &state);
|
||||||
|
operator ParsingState() const { return m_state; }
|
||||||
|
AssetExporter &m_assetExporter;
|
||||||
|
ParsingState m_state = ParsingState::Idle;
|
||||||
|
} m_currentState;
|
||||||
|
ProjectExplorer::Project *m_project = nullptr;
|
||||||
|
AssetExporterView *m_view = nullptr;
|
||||||
|
Utils::FilePaths m_exportFiles;
|
||||||
|
Utils::FilePath m_exportPath;
|
||||||
|
QJsonArray m_components;
|
||||||
|
std::unique_ptr<QFutureWatcher<Utils::FilePath>> m_preprocessWatcher;
|
||||||
|
};
|
||||||
|
QDebug operator<< (QDebug os, const QmlDesigner::AssetExporter::ParsingState& s);
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,124 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetexporterplugin.h"
|
||||||
|
|
||||||
|
#include "assetexportpluginconstants.h"
|
||||||
|
#include "assetexportdialog.h"
|
||||||
|
#include "assetexporter.h"
|
||||||
|
#include "assetexporterview.h"
|
||||||
|
#include "componentexporter.h"
|
||||||
|
|
||||||
|
#include "parsers/modelitemnodeparser.h"
|
||||||
|
|
||||||
|
#include "coreplugin/actionmanager/actionmanager.h"
|
||||||
|
#include "coreplugin/actionmanager/actioncontainer.h"
|
||||||
|
#include "coreplugin/documentmanager.h"
|
||||||
|
#include "qmldesigner/qmldesignerplugin.h"
|
||||||
|
#include "projectexplorer/projectexplorerconstants.h"
|
||||||
|
#include "projectexplorer/session.h"
|
||||||
|
#include "projectexplorer/project.h"
|
||||||
|
#include "projectexplorer/session.h"
|
||||||
|
|
||||||
|
#include "extensionsystem/pluginmanager.h"
|
||||||
|
#include "extensionsystem/pluginspec.h"
|
||||||
|
|
||||||
|
#include "utils/algorithm.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
AssetExporterPlugin::AssetExporterPlugin() :
|
||||||
|
m_view(new AssetExporterView)
|
||||||
|
{
|
||||||
|
auto *designerPlugin = QmlDesigner::QmlDesignerPlugin::instance();
|
||||||
|
auto &viewManager = designerPlugin->viewManager();
|
||||||
|
viewManager.registerViewTakingOwnership(m_view);
|
||||||
|
|
||||||
|
// Add parsers templates for factory instantiation.
|
||||||
|
ComponentExporter::addNodeParser<ItemNodeParser>();
|
||||||
|
|
||||||
|
// Instantiate actions created by the plugin.
|
||||||
|
addActions();
|
||||||
|
|
||||||
|
connect(ProjectExplorer::SessionManager::instance(),
|
||||||
|
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||||
|
this, &AssetExporterPlugin::updateActions);
|
||||||
|
|
||||||
|
updateActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AssetExporterPlugin::pluginName() const
|
||||||
|
{
|
||||||
|
return QLatin1String("AssetExporterPlugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterPlugin::onExport()
|
||||||
|
{
|
||||||
|
auto startupProject = ProjectExplorer::SessionManager::startupProject();
|
||||||
|
if (!startupProject)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto exportDir = startupProject->projectFilePath().parentDir();
|
||||||
|
if (!exportDir.toFileInfo().isRoot())
|
||||||
|
exportDir = exportDir.parentDir();
|
||||||
|
auto defaultMetadataPath = exportDir.pathAppended(startupProject->displayName() + ".metadata");
|
||||||
|
|
||||||
|
AssetExporter assetExporter(m_view, startupProject);
|
||||||
|
AssetExportDialog assetExporterDialog(defaultMetadataPath, assetExporter);
|
||||||
|
assetExporter.preProcessProject();
|
||||||
|
assetExporterDialog.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterPlugin::addActions()
|
||||||
|
{
|
||||||
|
auto exportAction = new QAction(tr("Export QML"));
|
||||||
|
exportAction->setToolTip(tr("Export QML code of the current project."));
|
||||||
|
connect(exportAction, &QAction::triggered, this, &AssetExporterPlugin::onExport);
|
||||||
|
Core::Command *cmd = Core::ActionManager::registerAction(exportAction, Constants::EXPORT_QML);
|
||||||
|
|
||||||
|
// Add action to build menu
|
||||||
|
Core::ActionContainer *buildMenu =
|
||||||
|
Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT);
|
||||||
|
buildMenu->addAction(cmd, ProjectExplorer::Constants::G_BUILD_RUN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterPlugin::updateActions()
|
||||||
|
{
|
||||||
|
auto project = ProjectExplorer::SessionManager::startupProject();
|
||||||
|
QAction* const exportAction = Core::ActionManager::command(Constants::EXPORT_QML)->action();
|
||||||
|
exportAction->setEnabled(project && !project->needsConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AssetExporterPlugin::metaInfo() const
|
||||||
|
{
|
||||||
|
return QLatin1String(":/assetexporterplugin/assetexporterplugin.metainfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
} //QmlDesigner
|
@@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <iwidgetplugin.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
class AssetExporter;
|
||||||
|
class AssetExporterView;
|
||||||
|
class AssetExporterPlugin : public QObject, QmlDesigner::IWidgetPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QmlDesignerPlugin" FILE "assetexporterplugin.json")
|
||||||
|
|
||||||
|
Q_DISABLE_COPY(AssetExporterPlugin)
|
||||||
|
Q_INTERFACES(QmlDesigner::IWidgetPlugin)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetExporterPlugin();
|
||||||
|
|
||||||
|
QString metaInfo() const;
|
||||||
|
QString pluginName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onExport();
|
||||||
|
void addActions();
|
||||||
|
void updateActions();
|
||||||
|
|
||||||
|
AssetExporterView *m_view = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,2 @@
|
|||||||
|
MetaInfo {
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
QT *= qml quick core widgets
|
||||||
|
|
||||||
|
VPATH += $$PWD
|
||||||
|
|
||||||
|
RESOURCES += assetexporterplugin.qrc
|
||||||
|
|
||||||
|
INCLUDEPATH += ./
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
assetexportdialog.h \
|
||||||
|
assetexporter.h \
|
||||||
|
assetexporterplugin.h \
|
||||||
|
assetexporterview.h \
|
||||||
|
assetexportpluginconstants.h \
|
||||||
|
componentexporter.h \
|
||||||
|
parsers/modelitemnodeparser.h \
|
||||||
|
parsers/modelnodeparser.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
assetexportdialog.cpp \
|
||||||
|
assetexporter.cpp \
|
||||||
|
assetexporterplugin.cpp \
|
||||||
|
assetexporterview.cpp \
|
||||||
|
componentexporter.cpp \
|
||||||
|
parsers/modelitemnodeparser.cpp \
|
||||||
|
parsers/modelnodeparser.cpp
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
assetexportdialog.ui
|
@@ -0,0 +1,17 @@
|
|||||||
|
include (../../../../qtcreator.pri)
|
||||||
|
include (../plugindestdir.pri)
|
||||||
|
include (../designercore/iwidgetplugin.pri)
|
||||||
|
include (../qmldesigner_dependencies.pri)
|
||||||
|
include (assetexporterplugin.pri)
|
||||||
|
|
||||||
|
LIBS += -L$$IDE_PLUGIN_PATH
|
||||||
|
LIBS += -l$$qtLibraryName(QmlDesigner)
|
||||||
|
LIBS += -l$$qtLibraryName(ExtensionSystem)
|
||||||
|
LIBS += -l$$qtLibraryName(Core)
|
||||||
|
LIBS += -l$$qtLibraryName(ProjectExplorer)
|
||||||
|
LIBS += -l$$qtLibraryName(Utils)
|
||||||
|
|
||||||
|
TARGET = assetexporterplugin
|
||||||
|
TEMPLATE = lib
|
||||||
|
CONFIG += plugin
|
||||||
|
|
@@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/assetexporterplugin">
|
||||||
|
<file>assetexporterplugin.metainfo</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@@ -0,0 +1,149 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "assetexporterview.h"
|
||||||
|
|
||||||
|
#include "qmlitemnode.h"
|
||||||
|
#include "rewriterview.h"
|
||||||
|
|
||||||
|
#include "coreplugin/editormanager/editormanager.h"
|
||||||
|
#include "coreplugin/editormanager/ieditor.h"
|
||||||
|
#include "coreplugin/modemanager.h"
|
||||||
|
#include "coreplugin/coreconstants.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.view", QtInfoMsg)
|
||||||
|
Q_LOGGING_CATEGORY(loggerWarn, "qtc.designer.assetExportPlugin.view", QtWarningMsg)
|
||||||
|
Q_LOGGING_CATEGORY(loggerError, "qtc.designer.assetExportPlugin.view", QtCriticalMsg)
|
||||||
|
|
||||||
|
static const int RetryIntervalMs = 500;
|
||||||
|
static const int MinRetry = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
AssetExporterView::AssetExporterView(QObject *parent) : AbstractView(parent),
|
||||||
|
m_timer(this)
|
||||||
|
{
|
||||||
|
m_timer.setInterval(RetryIntervalMs);
|
||||||
|
// We periodically check if file is loaded.
|
||||||
|
connect(&m_timer, &QTimer::timeout, this, &AssetExporterView::handleTimerTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AssetExporterView::loadQmlFile(const Utils::FilePath &path, uint timeoutSecs)
|
||||||
|
{
|
||||||
|
qCDebug(loggerInfo) << "Load file" << path;
|
||||||
|
if (loadingState() == LoadState::Busy)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setState(LoadState::Busy);
|
||||||
|
m_retryCount = std::max(MinRetry, static_cast<int>((timeoutSecs * 1000) / RetryIntervalMs));
|
||||||
|
Core::EditorManager::openEditor(path.toString(), Core::Id(),
|
||||||
|
Core::EditorManager::DoNotMakeVisible);
|
||||||
|
Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
|
||||||
|
Core::ModeManager::setFocusToCurrentMode();
|
||||||
|
m_timer.start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::modelAttached(Model *model)
|
||||||
|
{
|
||||||
|
if (model->rewriterView() && model->rewriterView()->inErrorState())
|
||||||
|
setState(LoadState::QmlErrorState);
|
||||||
|
|
||||||
|
AbstractView::modelAttached(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::
|
||||||
|
instanceInformationsChanged(const QMultiHash<ModelNode, InformationName> &informationChangeHash)
|
||||||
|
{
|
||||||
|
if (inErrorState() || loadingState() == LoadState::Loaded)
|
||||||
|
return; // Already reached error or connected state.
|
||||||
|
|
||||||
|
// We expect correct dimensions are available if the rootnode's
|
||||||
|
// information change message is received.
|
||||||
|
const auto nodes = informationChangeHash.keys();
|
||||||
|
bool hasRootNode = std::any_of(nodes.begin(), nodes.end(), [](const ModelNode &n) {
|
||||||
|
return n.isRootNode();
|
||||||
|
});
|
||||||
|
if (hasRootNode)
|
||||||
|
handleMaybeDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::instancesPreviewImageChanged(const QVector<ModelNode> &nodeList)
|
||||||
|
{
|
||||||
|
Q_UNUSED(nodeList);
|
||||||
|
emit previewChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetExporterView::inErrorState() const
|
||||||
|
{
|
||||||
|
return m_state == LoadState::Exausted || m_state == LoadState::QmlErrorState;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetExporterView::isLoaded() const
|
||||||
|
{
|
||||||
|
return isAttached() && QmlItemNode(rootModelNode()).isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::setState(AssetExporterView::LoadState state)
|
||||||
|
{
|
||||||
|
if (state != m_state) {
|
||||||
|
m_state = state;
|
||||||
|
qCDebug(loggerInfo) << "Loading state changed" << m_state;
|
||||||
|
if (inErrorState() || m_state == LoadState::Loaded) {
|
||||||
|
m_timer.stop();
|
||||||
|
if (m_state == LoadState::Loaded)
|
||||||
|
emit loadingFinished();
|
||||||
|
else
|
||||||
|
emit loadingError(m_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::handleMaybeDone()
|
||||||
|
{
|
||||||
|
if (isLoaded())
|
||||||
|
setState(LoadState::Loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetExporterView::handleTimerTimeout()
|
||||||
|
{
|
||||||
|
if (!inErrorState() && loadingState() != LoadState::Loaded)
|
||||||
|
handleMaybeDone();
|
||||||
|
|
||||||
|
if (--m_retryCount < 0)
|
||||||
|
setState(LoadState::Exausted);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug os, const QmlDesigner::AssetExporterView::LoadState &s)
|
||||||
|
{
|
||||||
|
os << static_cast<std::underlying_type<QmlDesigner::AssetExporterView::LoadState>::type>(s);
|
||||||
|
return os;
|
||||||
|
}
|
@@ -0,0 +1,85 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "abstractview.h"
|
||||||
|
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class IEditor;
|
||||||
|
}
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
|
||||||
|
class AssetExporterView : public AbstractView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum class LoadState {
|
||||||
|
Idle = 1,
|
||||||
|
Busy,
|
||||||
|
Exausted,
|
||||||
|
QmlErrorState,
|
||||||
|
Loaded
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetExporterView(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool loadQmlFile(const Utils::FilePath &path, uint timeoutSecs = 10);
|
||||||
|
|
||||||
|
void modelAttached(Model *model) override;
|
||||||
|
void instanceInformationsChanged(const QMultiHash<ModelNode, InformationName> &informationChangeHash) override;
|
||||||
|
void instancesPreviewImageChanged(const QVector<ModelNode> &nodeList) override;
|
||||||
|
|
||||||
|
LoadState loadingState() const { return m_state; }
|
||||||
|
bool inErrorState() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void loadingFinished();
|
||||||
|
void loadingError(LoadState);
|
||||||
|
void previewChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isLoaded() const;
|
||||||
|
void setState(LoadState state);
|
||||||
|
void handleMaybeDone();
|
||||||
|
void handleTimerTimeout();
|
||||||
|
|
||||||
|
Core::IEditor *m_currentEditor = nullptr;
|
||||||
|
QTimer m_timer;
|
||||||
|
int m_retryCount = 0;
|
||||||
|
LoadState m_state = LoadState::Idle;
|
||||||
|
bool m_waitForPuppet = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug os, const QmlDesigner::AssetExporterView::LoadState &s);
|
@@ -0,0 +1,33 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
namespace Constants {
|
||||||
|
|
||||||
|
const char EXPORT_QML[] = "Designer.ExportPlugin.ExportQml";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,107 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "componentexporter.h"
|
||||||
|
#include "parsers/modelnodeparser.h"
|
||||||
|
|
||||||
|
#include "model.h"
|
||||||
|
#include "nodeabstractproperty.h"
|
||||||
|
#include "rewriterview.h"
|
||||||
|
|
||||||
|
#include "utils/qtcassert.h"
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.modelExporter", QtInfoMsg)
|
||||||
|
|
||||||
|
static void populateLineage(const QmlDesigner::ModelNode &node, QByteArrayList &lineage)
|
||||||
|
{
|
||||||
|
if (!node.isValid() || node.type().isEmpty())
|
||||||
|
return;
|
||||||
|
lineage.append(node.type());
|
||||||
|
if (node.hasParentProperty())
|
||||||
|
populateLineage(node.parentProperty().parentModelNode(), lineage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Internal::NodeParserCreatorBase>> ComponentExporter::m_readers;
|
||||||
|
ComponentExporter::ComponentExporter(const ModelNode &rootNode):
|
||||||
|
m_rootNode(rootNode)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ComponentExporter::exportComponent() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_rootNode.isValid(), return {});
|
||||||
|
return nodeToJson(m_rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNodeParser *ComponentExporter::createNodeParser(const ModelNode &node) const
|
||||||
|
{
|
||||||
|
QByteArrayList lineage;
|
||||||
|
populateLineage(node, lineage);
|
||||||
|
std::unique_ptr<ModelNodeParser> reader;
|
||||||
|
for (auto &parserCreator: m_readers) {
|
||||||
|
std::unique_ptr<ModelNodeParser> r(parserCreator->instance(lineage, node));
|
||||||
|
if (r->isExportable()) {
|
||||||
|
if (reader) {
|
||||||
|
if (reader->priority() < r->priority())
|
||||||
|
reader = std::move(r);
|
||||||
|
} else {
|
||||||
|
reader = std::move(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!reader) {
|
||||||
|
qCDebug(loggerInfo()) << "No parser for node" << node;
|
||||||
|
}
|
||||||
|
return reader.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject ComponentExporter::nodeToJson(const ModelNode &node) const
|
||||||
|
{
|
||||||
|
QJsonObject jsonObject;
|
||||||
|
std::unique_ptr<ModelNodeParser> parser(createNodeParser(node));
|
||||||
|
if (parser)
|
||||||
|
jsonObject = parser->json();
|
||||||
|
|
||||||
|
QJsonArray children;
|
||||||
|
for (const ModelNode &childnode : node.directSubModelNodes())
|
||||||
|
children.append(nodeToJson(childnode));
|
||||||
|
|
||||||
|
if (!children.isEmpty())
|
||||||
|
jsonObject.insert("children", children);
|
||||||
|
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,90 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QJsonValue>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QByteArrayList>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "utils/qtcassert.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QJsonArray;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
class Model;
|
||||||
|
class ModelNode;
|
||||||
|
class ComponentExporter;
|
||||||
|
class ModelNodeParser;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
class NodeParserCreatorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~NodeParserCreatorBase() {}
|
||||||
|
protected:
|
||||||
|
virtual ModelNodeParser *instance(const QByteArrayList &, const ModelNode &) const = 0;
|
||||||
|
friend class QmlDesigner::ComponentExporter;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class NodeParserCreator : public NodeParserCreatorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeParserCreator() = default;
|
||||||
|
~NodeParserCreator() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ModelNodeParser *instance(const QByteArrayList &lineage, const ModelNode &node) const {
|
||||||
|
return new T(lineage, node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} //Internal
|
||||||
|
|
||||||
|
class ComponentExporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComponentExporter(const ModelNode &rootNode);
|
||||||
|
|
||||||
|
QJsonObject exportComponent() const;
|
||||||
|
|
||||||
|
template<typename T> static void addNodeParser()
|
||||||
|
{
|
||||||
|
QTC_ASSERT((std::is_base_of<ModelNodeParser, T>::value), return);
|
||||||
|
m_readers.push_back(std::make_unique<Internal::NodeParserCreator<T>>());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ModelNodeParser* createNodeParser(const ModelNode &node) const;
|
||||||
|
QJsonObject nodeToJson(const ModelNode &node) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ModelNode &m_rootNode;
|
||||||
|
static std::vector<std::unique_ptr<Internal::NodeParserCreatorBase>> m_readers;
|
||||||
|
};
|
||||||
|
}
|
@@ -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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "modelitemnodeparser.h"
|
||||||
|
#include "assetexportpluginconstants.h"
|
||||||
|
|
||||||
|
#include "modelnode.h"
|
||||||
|
#include "qmlitemnode.h"
|
||||||
|
#include "variantproperty.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
ItemNodeParser::ItemNodeParser(const QByteArrayList &lineage, const ModelNode &node) :
|
||||||
|
ModelNodeParser(lineage, node)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlDesigner::ItemNodeParser::isExportable() const
|
||||||
|
{
|
||||||
|
return m_lineage.contains("QtQuick.Item");
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject QmlDesigner::ItemNodeParser::json() const
|
||||||
|
{
|
||||||
|
// TODO parse other relevant properties i.e. dimensions etc
|
||||||
|
QJsonObject jsonObject;
|
||||||
|
jsonObject.insert("qmlid", m_node.id());
|
||||||
|
QmlItemNode itemNode(m_node);
|
||||||
|
|
||||||
|
// Position relative to parent
|
||||||
|
QPointF pos = itemNode.instancePosition();
|
||||||
|
jsonObject.insert("x", pos.x());
|
||||||
|
jsonObject.insert("y", pos.y());
|
||||||
|
|
||||||
|
// size
|
||||||
|
QSizeF size = itemNode.instanceSize();
|
||||||
|
jsonObject.insert("width", size.width());
|
||||||
|
jsonObject.insert("height", size.height());
|
||||||
|
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "modelnodeparser.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
class ModelNode;
|
||||||
|
|
||||||
|
class ItemNodeParser : public ModelNodeParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ItemNodeParser(const QByteArrayList &lineage, const ModelNode &node);
|
||||||
|
|
||||||
|
~ItemNodeParser() override = default;
|
||||||
|
|
||||||
|
int priority() const override { return 100; }
|
||||||
|
bool isExportable() const override;
|
||||||
|
QJsonObject json() const override;
|
||||||
|
};
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "modelnodeparser.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
ModelNodeParser::ModelNodeParser(const QByteArrayList &lineage, const ModelNode &node) :
|
||||||
|
m_node(node),
|
||||||
|
m_lineage(lineage)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <QJsonObject>
|
||||||
|
#include <QByteArrayList>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
class ModelNode;
|
||||||
|
|
||||||
|
class ModelNodeParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ModelNodeParser(const QByteArrayList &lineage, const ModelNode &node);
|
||||||
|
|
||||||
|
virtual ~ModelNodeParser() = default;
|
||||||
|
|
||||||
|
virtual int priority() const = 0;
|
||||||
|
virtual bool isExportable() const = 0;
|
||||||
|
virtual QJsonObject json() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const ModelNode &m_node;
|
||||||
|
const QByteArrayList m_lineage;
|
||||||
|
};
|
||||||
|
}
|
@@ -1,4 +1,9 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
CONFIG += ordered
|
CONFIG += ordered
|
||||||
|
|
||||||
SUBDIRS = qmldesignerplugin.pro qtquickplugin componentsplugin qmlpreviewplugin
|
SUBDIRS = \
|
||||||
|
qmldesignerplugin.pro \
|
||||||
|
qtquickplugin \
|
||||||
|
componentsplugin \
|
||||||
|
qmlpreviewplugin \
|
||||||
|
assetexporterplugin
|
||||||
|
Reference in New Issue
Block a user