From b77bce63e30669b9319f8570927a8789abf96240 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 27 Aug 2019 20:10:36 +0200 Subject: [PATCH] QmlDesigner: add a generate resource menu entry The result can be used with the Webassembly qmlprojector. Change-Id: I69ed21561c05fcbb9552bf74217e3546c489d4a6 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/CMakeLists.txt | 1 + src/plugins/qmldesigner/generateresource.cpp | 156 ++++++++++++++++++ src/plugins/qmldesigner/generateresource.h | 33 ++++ src/plugins/qmldesigner/qmldesignerplugin.cpp | 6 +- src/plugins/qmldesigner/qmldesignerplugin.pri | 2 + src/plugins/qmldesigner/qmldesignerplugin.qbs | 2 + 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/plugins/qmldesigner/generateresource.cpp create mode 100644 src/plugins/qmldesigner/generateresource.h diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 26d00a63d34..9b136f89c0b 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -16,6 +16,7 @@ add_qtc_plugin(QmlDesigner designmodewidget.cpp designmodewidget.h documentmanager.cpp documentmanager.h documentwarningwidget.cpp documentwarningwidget.h + generateresource.cpp generateresource.h openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui qmldesignerconstants.h qmldesignericons.h diff --git a/src/plugins/qmldesigner/generateresource.cpp b/src/plugins/qmldesigner/generateresource.cpp new file mode 100644 index 00000000000..ca907836335 --- /dev/null +++ b/src/plugins/qmldesigner/generateresource.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** 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 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace QmlDesigner { +void GenerateResource::generateMenuEntry() +{ + Core::ActionContainer *buildMenu = + Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT); + + + const Core::Context projectContext(QmlProjectManager::Constants::QML_PROJECT_ID); + // ToDo: move this to QtCreator and add tr to the string then + auto action = new QAction(QT_TRANSLATE_NOOP("GenerateResource", "Generate Resource File")); + action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); + // todo make it more intelligent when it gets enabled + QObject::connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::startupProjectChanged, [action]() { + action->setEnabled(ProjectExplorer::SessionManager::startupProject()); + }); + + Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateResource"); + QObject::connect(action, &QAction::triggered, [] () { + auto currentProject = ProjectExplorer::SessionManager::startupProject(); + auto projectPath = currentProject->projectFilePath().parentDir().toString(); + + static QMap lastUsedPathes; + auto saveLastUsedPath = [currentProject] (const QString &lastUsedPath) { + lastUsedPathes.insert(currentProject->displayName(), lastUsedPath); + }; + saveLastUsedPath(lastUsedPathes.value(currentProject->displayName(), + currentProject->projectFilePath().parentDir().toString())); + + auto resourceFileName = Core:: DocumentManager::getSaveFileName( + QT_TRANSLATE_NOOP("GenerateResource", "Save Project As Resource"), + lastUsedPathes.value(currentProject->displayName()) + currentProject->displayName() + ".qmlrc", + QT_TRANSLATE_NOOP("GenerateResource", "QML Resource File (*.qmlrc")); + if (resourceFileName.isEmpty()) + return; + + Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", + QString("Generate a resource file out of project %1 to %2").arg( + currentProject->displayName(), QDir::toNativeSeparators(resourceFileName)))); + + QTemporaryFile temp(projectPath + "/XXXXXXX.create.resource.qrc"); + if (!temp.open()) + return; + temp.close(); + + auto rccBinary = QtSupport::QtKitAspect::qtVersion(currentProject->activeTarget()->kit())->binPath(); +#ifdef Q_OS_WIN + rccBinary = rccBinary.pathAppended("rcc.exe"); +#else + rccBinary = rccBinary.pathAppended("rcc"); +#endif + QProcess rccProcess; + rccProcess.setProgram(rccBinary.toString()); + rccProcess.setWorkingDirectory(projectPath); + + const QStringList arguments1 = {"--project", "--output", temp.fileName()}; + const QStringList arguments2 = {"--binary", "--output", resourceFileName, temp.fileName()}; + + for (auto arguments : {arguments1, arguments2}) { + rccProcess.start(rccBinary.toString(), arguments); + if (!rccProcess.waitForStarted()) { + Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString( + "Unable to generate resource file: %1").arg(resourceFileName))); + return; + } + QByteArray stdOut; + QByteArray stdErr; + if (!Utils::SynchronousProcess::readDataFromProcess(rccProcess, 30, &stdOut, &stdErr, true)) { + Utils::SynchronousProcess::stopProcess(rccProcess); + Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString( + "A timeout occurred running \"%1\"").arg(rccBinary.toString() + arguments.join(" ")))); + return ; + + } + if (!stdOut.trimmed().isEmpty()) { + Core::MessageManager::write(QString::fromLocal8Bit(stdOut)); + } + if (!stdErr.trimmed().isEmpty()) + Core::MessageManager::write(QString::fromLocal8Bit(stdErr)); + + if (rccProcess.exitStatus() != QProcess::NormalExit) { + Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString( + "\"%1\" crashed.").arg(rccBinary.toString() + arguments.join(" ")))); + return; + } + if (rccProcess.exitCode() != 0) { + Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString( + "\"%1\" failed (exit code %2).").arg(rccBinary.toString() + + " " + arguments.join(" ")).arg(rccProcess.exitCode()))); + return; + } + + } + + saveLastUsedPath(Utils::FilePath::fromString(resourceFileName).parentDir().toString()); + }); + buildMenu->addAction(cmd, ProjectExplorer::Constants::G_BUILD_RUN); +} + +} // namespace QmlDesigner + diff --git a/src/plugins/qmldesigner/generateresource.h b/src/plugins/qmldesigner/generateresource.h new file mode 100644 index 00000000000..4b4dadf9e84 --- /dev/null +++ b/src/plugins/qmldesigner/generateresource.h @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** 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 GenerateResource { + void generateMenuEntry(); +} +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 752151a88d9..1f14969dfca 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -30,6 +30,7 @@ #include "settingspage.h" #include "designmodecontext.h" #include "openuiqmlfiledialog.h" +#include "generateresource.h" #include #include @@ -202,11 +203,14 @@ QmlDesignerPlugin::~QmlDesignerPlugin() // INHERITED FROM ExtensionSystem::Plugin // //////////////////////////////////////////////////// -bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/) // =0; +bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/) { if (!Utils::HostOsInfo::canCreateOpenGLContext(errorMessage)) return false; d = new QmlDesignerPluginPrivate; + if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool()) + GenerateResource::generateMenuEntry(); + return true; } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri index 503b47a83b1..9eba4c9a811 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pri +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -4,6 +4,7 @@ HEADERS += $$PWD/qmldesignerconstants.h \ $$PWD/designmodewidget.h \ $$PWD/switchsplittabwidget.h \ $$PWD/designersettings.h \ + $$PWD/generateresource.h \ $$PWD/settingspage.h \ $$PWD/designmodecontext.h \ $$PWD/documentmanager.h \ @@ -16,6 +17,7 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/designmodewidget.cpp \ $$PWD/switchsplittabwidget.cpp \ $$PWD/designersettings.cpp \ + $$PWD/generateresource.cpp \ $$PWD/settingspage.cpp \ $$PWD/designmodecontext.cpp \ $$PWD/documentmanager.cpp \ diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index a06195f3fcf..1e82b1354db 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -770,6 +770,8 @@ Project { } files: [ + "generateresource.cpp", + "generateresource.h", "designersettings.cpp", "designersettings.h", "designmodecontext.cpp",