Files
qt-creator/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp

251 lines
8.2 KiB
C++
Raw Normal View History

// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "puppetenvironmentbuilder.h"
#include "designersettings.h"
#include "qmldesignerplugin.h"
#include <model.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/target.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
#include <qmlprojectmanager/qmlproject.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversions.h>
#include <QLibraryInfo>
namespace QmlDesigner {
namespace {
Q_LOGGING_CATEGORY(puppetEnvirmentBuild, "qtc.puppet.environmentBuild", QtWarningMsg)
void filterOutQtBaseImportPath(QStringList *stringList)
{
Utils::erase(*stringList, [](const QString &string) {
QDir dir(string);
return dir.dirName() == "qml"
&& !dir.entryInfoList(QStringList("QtTest"), QDir::Dirs).isEmpty();
});
}
Utils::FilePath pathForBinPuppet(ProjectExplorer::Target *target)
{
if (!target || !target->kit())
return {};
QtSupport::QtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
if (currentQtVersion)
return currentQtVersion->binPath().pathAppended("qml2puppet").withExecutableSuffix();
return {};
}
} // namespace
QProcessEnvironment PuppetEnvironmentBuilder::processEnvironment() const
{
qCInfo(puppetEnvirmentBuild) << Q_FUNC_INFO;
m_availablePuppetType = determinePuppetType();
m_environment = Utils::Environment::systemEnvironment();
addKit();
addRendering();
addControls();
addPixelRatio();
addVirtualKeyboard();
addQuick3D();
addForceQApplication();
addMultiLanguageDatatbase();
addImportPaths();
addCustomFileSelectors();
qCInfo(puppetEnvirmentBuild) << "Puppet environment:" << m_environment.toStringList();
return m_environment.toProcessEnvironment();
}
QProcessEnvironment PuppetEnvironmentBuilder::createEnvironment(
ProjectExplorer::Target *target, const DesignerSettings &designerSettings, const Model &model)
{
PuppetEnvironmentBuilder builder{target, designerSettings, model};
return builder.processEnvironment();
}
bool PuppetEnvironmentBuilder::usesVirtualKeyboard() const
{
if (m_target) {
auto *qmlbuild = qobject_cast<QmlProjectManager::QmlBuildSystem *>(m_target->buildSystem());
const Utils::EnvironmentItem virtualKeyboard("QT_IM_MODULE", "qtvirtualkeyboard");
return qmlbuild && qmlbuild->environment().indexOf(virtualKeyboard);
}
return false;
}
QString PuppetEnvironmentBuilder::getStyleConfigFileName() const
{
if (m_target) {
for (const Utils::FilePath &fileName :
m_target->project()->files(ProjectExplorer::Project::SourceFiles)) {
if (fileName.fileName() == "qtquickcontrols2.conf")
return fileName.toString();
}
}
return {};
}
void PuppetEnvironmentBuilder::addKit() const
{
if (m_target) {
if (m_availablePuppetType == PuppetType::Kit) {
m_target->kit()->addToBuildEnvironment(m_environment);
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (qt) { // Kits without a Qt version should not have a puppet!
// Update PATH to include QT_HOST_BINS
m_environment.prependOrSetPath(qt->hostBinPath());
}
}
}
}
void PuppetEnvironmentBuilder::addRendering() const
{
m_environment.set("QML_BAD_GUI_RENDER_LOOP", "true");
m_environment.set("QML_PUPPET_MODE", "true");
m_environment.set("QML_DISABLE_DISK_CACHE", "true");
m_environment.set("QMLPUPPET_RENDER_EFFECTS", "true");
if (!m_environment.hasKey("QT_SCREEN_SCALE_FACTORS") && !m_environment.hasKey("QT_SCALE_FACTOR"))
m_environment.set("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
const bool smoothRendering = m_designerSettings.value(DesignerSettingsKey::SMOOTH_RENDERING).toBool();
if (smoothRendering)
m_environment.set("QMLPUPPET_SMOOTH_RENDERING", "true");
}
void PuppetEnvironmentBuilder::addControls() const
{
const QString controlsStyle = m_designerSettings.value(DesignerSettingsKey::CONTROLS_STYLE).toString();
if (!controlsStyle.isEmpty()) {
m_environment.set("QT_QUICK_CONTROLS_STYLE", controlsStyle);
m_environment.set("QT_LABS_CONTROLS_STYLE", controlsStyle);
}
const QString styleConfigFileName = getStyleConfigFileName();
if (!styleConfigFileName.isEmpty())
m_environment.appendOrSet("QT_QUICK_CONTROLS_CONF", styleConfigFileName);
}
void PuppetEnvironmentBuilder::addPixelRatio() const
{
m_environment.set("FORMEDITOR_DEVICE_PIXEL_RATIO",
QString::number(QmlDesignerPlugin::formEditorDevicePixelRatio()));
}
void PuppetEnvironmentBuilder::addVirtualKeyboard() const
{
if (usesVirtualKeyboard()) {
m_environment.set("QT_IM_MODULE", "qtvirtualkeyboard");
m_environment.set("QT_VIRTUALKEYBOARD_DESKTOP_DISABLE", "1");
}
}
void PuppetEnvironmentBuilder::addQuick3D() const
{
// set env var if QtQuick3D import exists
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0");
if (m_model.hasImport(import, true, true))
m_environment.set("QMLDESIGNER_QUICK3D_MODE", "true");
import = QmlDesigner::Import::createLibraryImport("QtQuick3D.Particles3D", "1.0");
if (m_model.hasImport(import, true, true))
m_environment.set("QMLDESIGNER_QUICK3D_PARTICLES3D_MODE", "true");
bool particlemode = m_designerSettings.value("particleMode").toBool();
if (!particlemode)
m_environment.set("QT_QUICK3D_DISABLE_PARTICLE_SYSTEMS", "1");
else
m_environment.set("QT_QUICK3D_EDITOR_PARTICLE_SYSTEMS", "1");
}
void PuppetEnvironmentBuilder::addForceQApplication() const
{
auto import = QmlDesigner::Import::createLibraryImport("QtCharts", "2.0");
if (m_model.hasImport(import, true, true)) {
m_environment.set("QMLDESIGNER_FORCE_QAPPLICATION", "true");
} else if (m_target) {
auto bs = qobject_cast<QmlProjectManager::QmlBuildSystem *>(m_target->buildSystem());
if (bs && bs->widgetApp())
m_environment.set("QMLDESIGNER_FORCE_QAPPLICATION", "true");
}
}
void PuppetEnvironmentBuilder::addMultiLanguageDatatbase() const
{
if (m_target) {
if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(m_target)) {
if (!multiLanguageAspect->databaseFilePath().isEmpty())
m_environment.set("QT_MULTILANGUAGE_DATABASE",
multiLanguageAspect->databaseFilePath().toString());
}
}
}
void PuppetEnvironmentBuilder::addImportPaths() const
{
QStringList importPaths = m_model.importPaths();
if (m_availablePuppetType == PuppetType::Fallback)
filterOutQtBaseImportPath(&importPaths);
if (m_target) {
QStringList designerImports = m_target->additionalData("QmlDesignerImportPath").toStringList();
importPaths.append(designerImports);
}
if (m_availablePuppetType == PuppetType::Fallback)
importPaths.prepend(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath));
constexpr auto pathSep = Utils::HostOsInfo::pathListSeparator();
m_environment.appendOrSet("QML2_IMPORT_PATH", importPaths.join(pathSep), pathSep);
qCInfo(puppetEnvirmentBuild) << "Puppet import paths:" << importPaths;
}
void PuppetEnvironmentBuilder::addCustomFileSelectors() const
{
QStringList customFileSelectors;
if (m_target)
customFileSelectors = m_target->additionalData("CustomFileSelectorsData").toStringList();
customFileSelectors.append("DesignMode");
constexpr auto pathSep = Utils::HostOsInfo::pathListSeparator();
if (!customFileSelectors.isEmpty())
m_environment.appendOrSet("QML_FILE_SELECTORS", customFileSelectors.join(","), pathSep);
qCInfo(puppetEnvirmentBuild) << "Puppet selectors:" << customFileSelectors;
}
PuppetType PuppetEnvironmentBuilder::determinePuppetType() const
{
if (m_target && m_target->kit() && m_target->kit()->isValid()) {
if (pathForBinPuppet(m_target).isExecutableFile())
return PuppetType::Kit;
}
return PuppetType::Fallback;
}
} // namespace QmlDesigner