forked from qt-creator/qt-creator
QML Designer: Load relevant fonts in MCU projects
For MCU projects, QDS will use fonts that are closer to those that are used in QUL. This mostly applies to the cases of implicitly assumed fonts (i.e. there's no user-specified font properties). In this case text items will use the font set in `MCU.Config.defaultFontFamily` property, and, if this property is not set, DejaVu Sans, which corresponds to the behavior of Qt for MCUs. Also only the relevant fonts will be suggested in the font picker combobox. These come from the MCU installation and replace the standard set of fonts (Arial, Courier, Times New Roman, etc.) in MCU projects. From a technical perspective: * added a new model - `FontResourceModel` - as font handling logic is now too complex for a more generic `FileResourceModel`. * naturally, some wiring to be able to access MCU font throughout various parts of the project. Fixes: QDS-10597 Fixes: QDS-15079 Fixes: QDS-15156 Change-Id: I25aa4b0f89cca864f8fd41e0812f448fe307b104 Reviewed-by: Knud Dollereder <knud.dollereder@qt.io>
This commit is contained in:
@@ -20,10 +20,9 @@ StudioControls.ComboBox {
|
||||
|
||||
onTextColorChanged: root.setColor()
|
||||
|
||||
FileResourcesModel {
|
||||
FontResourcesModel {
|
||||
id: fileModel
|
||||
modelNodeBackendProperty: modelNodeBackend
|
||||
filter: root.fontFilter
|
||||
}
|
||||
|
||||
DropArea {
|
||||
@@ -59,19 +58,7 @@ StudioControls.ComboBox {
|
||||
}
|
||||
|
||||
function setupModel() {
|
||||
// default fonts
|
||||
var familyNames = ["Arial", "Times New Roman", "Courier", "Verdana", "Tahoma"]
|
||||
|
||||
for (var i = 0; i < fileModel.model.length; ++i) { // add custom fonts
|
||||
var fontLoader = root.createFontLoader(fileModel.docPath + "/"
|
||||
+ fileModel.model[i].relativeFilePath)
|
||||
familyNames.push(fontLoader.name)
|
||||
}
|
||||
|
||||
// Remove duplicate family names
|
||||
familyNames = [...new Set(familyNames)]
|
||||
familyNames.sort()
|
||||
root.model = familyNames
|
||||
root.model = fileModel.model
|
||||
root.currentIndex = root.find(root.backendValue.value)
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "mcubuildstep.h"
|
||||
#include "mcukitmanager.h"
|
||||
#include "mculegacyconstants.h"
|
||||
#include "mcuqmlprojectnode.h"
|
||||
#include "mcusupportconstants.h"
|
||||
#include "mcusupportdevice.h"
|
||||
@@ -16,6 +17,8 @@
|
||||
#include "test/unittest.h"
|
||||
#endif
|
||||
|
||||
#include <cmakeprojectmanager/cmakekitaspect.h>
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
@@ -38,6 +41,7 @@
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#include <qmljstools/qmljstoolsconstants.h>
|
||||
|
||||
#include <utils/expected.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/infobar.h>
|
||||
|
||||
@@ -49,6 +53,8 @@
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
const char setupMcuSupportKits[] = "SetupMcuSupportKits";
|
||||
@@ -192,6 +198,7 @@ public:
|
||||
void extensionsInitialized() final;
|
||||
|
||||
Q_INVOKABLE static void updateDeployStep(ProjectExplorer::Target *target, bool enabled);
|
||||
Q_INVOKABLE static expected_str<Utils::FilePath> installationRoot();
|
||||
};
|
||||
|
||||
void McuSupportPlugin::initialize()
|
||||
@@ -286,6 +293,26 @@ void McuSupportPlugin::updateDeployStep(ProjectExplorer::Target *target, bool en
|
||||
MCUBuildStepFactory::updateDeployStep(target, enabled);
|
||||
}
|
||||
|
||||
expected_str<Utils::FilePath> McuSupportPlugin::installationRoot()
|
||||
{
|
||||
const ProjectExplorer::Kit *kit = MCUBuildStepFactory::findMostRecentQulKit();
|
||||
if (kit == nullptr) {
|
||||
return make_unexpected("No QUL kits installed"_L1);
|
||||
}
|
||||
|
||||
const auto config
|
||||
= CMakeProjectManager::CMakeConfigurationKitAspect::configuration(kit).toList();
|
||||
const auto key = QString{Internal::Legacy::Constants::QUL_CMAKE_VAR}.toUtf8();
|
||||
for (const CMakeProjectManager::CMakeConfigItem &configItem : config) {
|
||||
if (configItem.key == key) {
|
||||
return Utils::FilePath::fromUserInput(QString::fromUtf8(configItem.value));
|
||||
}
|
||||
}
|
||||
return make_unexpected("No QUL installation root ('%1') key in kit '%2' configuration"_L1
|
||||
.arg(Internal::Legacy::Constants::QUL_CMAKE_VAR)
|
||||
.arg(kit->displayName()));
|
||||
}
|
||||
|
||||
} // namespace McuSupport::Internal
|
||||
|
||||
#include "mcusupportplugin.moc"
|
||||
|
@@ -409,6 +409,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
compatibleproperties.cpp compatibleproperties.h
|
||||
designerpropertymap.cpp designerpropertymap.h
|
||||
fileresourcesmodel.cpp fileresourcesmodel.h
|
||||
fontresourcesmodel.cpp fontresourcesmodel.h
|
||||
itemfiltermodel.cpp itemfiltermodel.h
|
||||
listvalidator.cpp listvalidator.h
|
||||
gradientmodel.cpp gradientmodel.h
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <viewmanager.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmlobjectnode.h>
|
||||
#include <qmlprojectmanager/qmlprojectconstants.h>
|
||||
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/project.h>
|
||||
@@ -423,6 +424,16 @@ bool DesignDocument::isQtForMCUsProject() const
|
||||
return false;
|
||||
}
|
||||
|
||||
QString DesignDocument::defaultFontFamilyMCU() const
|
||||
{
|
||||
if (m_currentTarget == nullptr) {
|
||||
return QmlProjectManager::Constants::FALLBACK_MCU_FONT_FAMILY;
|
||||
}
|
||||
|
||||
return m_currentTarget->additionalData(QmlProjectManager::Constants::customDefaultFontFamilyMCU)
|
||||
.toString();
|
||||
}
|
||||
|
||||
Utils::FilePath DesignDocument::projectFolder() const
|
||||
{
|
||||
ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectManager::projectForFile(fileName());
|
||||
|
@@ -87,6 +87,7 @@ public:
|
||||
void changeToDocumentModel();
|
||||
|
||||
bool isQtForMCUsProject() const;
|
||||
[[nodiscard]] QString defaultFontFamilyMCU() const;
|
||||
|
||||
Utils::FilePath projectFolder() const;
|
||||
bool hasProject() const;
|
||||
|
@@ -0,0 +1,156 @@
|
||||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "fontresourcesmodel.h"
|
||||
#include "fileresourcesmodel.h"
|
||||
|
||||
#include <cmakeprojectmanager/cmakekitaspect.h>
|
||||
#include <designermcumanager.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <qmlprojectmanager/qmlproject.h>
|
||||
#include <qmlprojectmanager/qmlprojectconstants.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/expected.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QLatin1String>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
namespace {
|
||||
|
||||
QStringList makeFontFilesFilterList()
|
||||
{
|
||||
QStringList filterList;
|
||||
filterList.reserve(std::size(QmlProjectManager::Constants::QDS_FONT_FILES_FILTERS));
|
||||
std::ranges::transform(QmlProjectManager::Constants::QDS_FONT_FILES_FILTERS,
|
||||
std::back_inserter(filterList),
|
||||
[](const char *filter) { return QString::fromLatin1(filter); });
|
||||
|
||||
return filterList;
|
||||
}
|
||||
|
||||
const QStringList &fontFilesFilterList()
|
||||
{
|
||||
static const QStringList list = makeFontFilesFilterList();
|
||||
return list;
|
||||
}
|
||||
|
||||
QString fontFamily(const QString &fontPath)
|
||||
{
|
||||
const int fontId = QFontDatabase::addApplicationFont(fontPath);
|
||||
QString fontFamily = QFontDatabase::applicationFontFamilies(fontId).front();
|
||||
QFontDatabase::removeApplicationFont(fontId);
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
Utils::expected_str<QSet<QString>> mcuFonts()
|
||||
{
|
||||
Utils::expected_str<Utils::FilePath> mcuFontsDir = QmlProjectManager::mcuFontsDir();
|
||||
if (!mcuFontsDir) {
|
||||
return Utils::make_unexpected(mcuFontsDir.error());
|
||||
}
|
||||
|
||||
QSet<QString> fonts;
|
||||
const Utils::FilePaths fontFiles = mcuFontsDir->dirEntries({fontFilesFilterList(), QDir::Files});
|
||||
for (const auto &file : fontFiles) {
|
||||
fonts.insert(fontFamily(file.absoluteFilePath().toFSPathString()));
|
||||
}
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
QSet<QString> systemFonts()
|
||||
{
|
||||
QSet<QString> defaultFonts{
|
||||
"Arial",
|
||||
"Courier",
|
||||
"Tahoma",
|
||||
"Times New Roman",
|
||||
"Verdana",
|
||||
};
|
||||
|
||||
if (QmlDesigner::DesignerMcuManager::instance().isMCUProject()) {
|
||||
const auto fonts = mcuFonts();
|
||||
if (!fonts) {
|
||||
qWarning() << "Failed to load MCU fonts." << fonts.error();
|
||||
return defaultFonts;
|
||||
}
|
||||
|
||||
return *fonts;
|
||||
}
|
||||
|
||||
return defaultFonts;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void FontResourcesModel::registerDeclarativeType()
|
||||
{
|
||||
qmlRegisterType<FontResourcesModel>("HelperWidgets", 2, 0, "FontResourcesModel");
|
||||
}
|
||||
|
||||
QVariant FontResourcesModel::modelNodeBackend()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
FontResourcesModel::FontResourcesModel(QObject *parent)
|
||||
: QObject{parent}
|
||||
, m_resourceModel{new FileResourcesModel{this}}
|
||||
{
|
||||
m_resourceModel->setFilter(fontFilesFilterList().join(' '));
|
||||
}
|
||||
|
||||
void FontResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||
{
|
||||
m_resourceModel->setModelNodeBackend(modelNodeBackend);
|
||||
}
|
||||
|
||||
QStringList FontResourcesModel::model() const
|
||||
{
|
||||
QSet<QString> fonts;
|
||||
for (const auto &item : m_resourceModel->model()) {
|
||||
fonts.insert(fontFamily(item.absoluteFilePath()));
|
||||
}
|
||||
|
||||
fonts.unite(systemFonts());
|
||||
|
||||
auto ret = QStringList{fonts.cbegin(), fonts.cend()};
|
||||
ret.sort();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FontResourcesModel::refreshModel()
|
||||
{
|
||||
m_resourceModel->refreshModel();
|
||||
}
|
||||
|
||||
void FontResourcesModel::openFileDialog(const QString &customPath)
|
||||
{
|
||||
m_resourceModel->openFileDialog(customPath);
|
||||
}
|
||||
|
||||
QString FontResourcesModel::resolve(const QString &relative) const
|
||||
{
|
||||
return m_resourceModel->resolve(relative);
|
||||
}
|
||||
|
||||
bool FontResourcesModel::isLocal(const QString &path) const
|
||||
{
|
||||
return m_resourceModel->isLocal(path);
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fileresourcesmodel.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
class FontResourcesModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend
|
||||
NOTIFY modelNodeBackendChanged)
|
||||
Q_PROPERTY(QStringList model READ model NOTIFY modelChanged)
|
||||
|
||||
public:
|
||||
static void registerDeclarativeType();
|
||||
[[nodiscard]] static QVariant modelNodeBackend();
|
||||
|
||||
explicit FontResourcesModel(QObject *parent = nullptr);
|
||||
|
||||
void setModelNodeBackend(const QVariant &modelNodeBackend);
|
||||
[[nodiscard]] QStringList model() const;
|
||||
|
||||
void refreshModel();
|
||||
|
||||
Q_INVOKABLE void openFileDialog(const QString &customPath = {});
|
||||
Q_INVOKABLE [[nodiscard]] QString resolve(const QString &relative) const;
|
||||
Q_INVOKABLE [[nodiscard]] bool isLocal(const QString &path) const;
|
||||
|
||||
signals:
|
||||
void fileNameChanged(const QUrl &fileName);
|
||||
void filterChanged(const QString &filter);
|
||||
void modelNodeBackendChanged();
|
||||
void pathChanged(const QUrl &path);
|
||||
void modelChanged();
|
||||
|
||||
private:
|
||||
FileResourcesModel *m_resourceModel;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(FontResourcesModel)
|
@@ -13,6 +13,7 @@
|
||||
#include "bindingeditor/bindingeditor.h"
|
||||
#include "colorpalettebackend.h"
|
||||
#include "fileresourcesmodel.h"
|
||||
#include "fontresourcesmodel.h"
|
||||
#include "gradientmodel.h"
|
||||
#include "gradientpresetcustomlistmodel.h"
|
||||
#include "gradientpresetdefaultlistmodel.h"
|
||||
@@ -60,6 +61,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
|
||||
declarativeTypesRegistered = true;
|
||||
PropertyEditorValue::registerDeclarativeTypes();
|
||||
FileResourcesModel::registerDeclarativeType();
|
||||
FontResourcesModel::registerDeclarativeType();
|
||||
GradientModel::registerDeclarativeType();
|
||||
GradientPresetDefaultListModel::registerDeclarativeType();
|
||||
GradientPresetCustomListModel::registerDeclarativeType();
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "designdocument.h"
|
||||
|
||||
#include <qmljs/qmljssimplereader.h>
|
||||
#include <qmlprojectmanager/qmlprojectconstants.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -45,6 +46,22 @@ QString DesignerMcuManager::mcuResourcesPath()
|
||||
return Core::ICore::resourcePath("qmldesigner/qt4mcu").toUrlishString();
|
||||
}
|
||||
|
||||
QString DesignerMcuManager::defaultFontFamilyMCU()
|
||||
{
|
||||
const QmlDesignerPlugin *designerPlugin = QmlDesigner::QmlDesignerPlugin::instance();
|
||||
if (designerPlugin == nullptr) {
|
||||
return QmlProjectManager::Constants::FALLBACK_MCU_FONT_FAMILY;
|
||||
}
|
||||
|
||||
const QmlDesigner::DesignDocument *designDocument = designerPlugin->documentManager()
|
||||
.currentDesignDocument();
|
||||
if (designDocument == nullptr) {
|
||||
return QmlProjectManager::Constants::FALLBACK_MCU_FONT_FAMILY;
|
||||
}
|
||||
|
||||
return designDocument->defaultFontFamilyMCU();
|
||||
}
|
||||
|
||||
bool DesignerMcuManager::isMCUProject() const
|
||||
{
|
||||
QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance()
|
||||
|
@@ -31,6 +31,7 @@ public:
|
||||
static DesignerMcuManager& instance();
|
||||
|
||||
static QString mcuResourcesPath();
|
||||
static QString defaultFontFamilyMCU();
|
||||
|
||||
bool isMCUProject() const;
|
||||
|
||||
|
@@ -7,14 +7,18 @@
|
||||
|
||||
#include <model.h>
|
||||
|
||||
#include <designermcumanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.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/qtkitaspect.h>
|
||||
#include <qtsupport/qtversions.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/expected.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QLibraryInfo>
|
||||
|
||||
@@ -51,6 +55,7 @@ QProcessEnvironment PuppetEnvironmentBuilder::processEnvironment() const
|
||||
addCustomFileSelectors();
|
||||
addDisableDeferredProperties();
|
||||
addResolveUrlsOnAssignment();
|
||||
addMcuFonts();
|
||||
|
||||
qCInfo(puppetEnvirmentBuild) << "Puppet environment:" << m_environment.toStringList();
|
||||
|
||||
@@ -249,6 +254,24 @@ void PuppetEnvironmentBuilder::addResolveUrlsOnAssignment() const
|
||||
m_environment.set("QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT", "true");
|
||||
}
|
||||
|
||||
void PuppetEnvironmentBuilder::addMcuFonts() const
|
||||
{
|
||||
const Utils::expected_str<Utils::FilePath> mcuFontsDir = QmlProjectManager::mcuFontsDir();
|
||||
if (!mcuFontsDir) {
|
||||
qCWarning(puppetEnvirmentBuild)
|
||||
<< "Failed to locate MCU installation." << mcuFontsDir.error();
|
||||
return;
|
||||
}
|
||||
|
||||
m_environment.set(QmlProjectManager::Constants::QMLPUPPET_ENV_MCU_FONTS_DIR,
|
||||
mcuFontsDir->toUserOutput());
|
||||
if (QmlDesigner::DesignerMcuManager::instance().isMCUProject()) {
|
||||
const QString defaultFontFamily = DesignerMcuManager::defaultFontFamilyMCU();
|
||||
m_environment.set(QmlProjectManager::Constants::QMLPUPPET_ENV_DEFAULT_FONT_FAMILY,
|
||||
defaultFontFamily);
|
||||
}
|
||||
}
|
||||
|
||||
PuppetType PuppetEnvironmentBuilder::determinePuppetType() const
|
||||
{
|
||||
if (m_target && m_target->kit() && m_target->kit()->isValid()) {
|
||||
|
@@ -51,6 +51,7 @@ private:
|
||||
void addCustomFileSelectors() const;
|
||||
void addDisableDeferredProperties() const;
|
||||
void addResolveUrlsOnAssignment() const;
|
||||
void addMcuFonts() const;
|
||||
|
||||
private:
|
||||
ProjectExplorer::Target *m_target = nullptr;
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "converters.h"
|
||||
#include "utils/algorithm.h"
|
||||
#include "../../qmlprojectexporter/filetypes.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
@@ -11,27 +12,6 @@ namespace QmlProjectManager::Converters {
|
||||
|
||||
const static QStringList qmlFilesFilter{QStringLiteral("*.qml")};
|
||||
const static QStringList javaScriptFilesFilter{QStringLiteral("*.js"), QStringLiteral("*.ts")};
|
||||
const static QStringList fontFilesFilter{
|
||||
QStringLiteral("*.afm"),
|
||||
QStringLiteral("*.bdf"),
|
||||
QStringLiteral("*.ccc"),
|
||||
QStringLiteral("*.cff"),
|
||||
QStringLiteral("*.fmp"),
|
||||
QStringLiteral("*.fnt"),
|
||||
QStringLiteral("*.otc"),
|
||||
QStringLiteral("*.otf"),
|
||||
QStringLiteral("*.pcf"),
|
||||
QStringLiteral("*.pfa"),
|
||||
QStringLiteral("*.pfb"),
|
||||
QStringLiteral("*.pfm"),
|
||||
QStringLiteral("*.pfr"),
|
||||
QStringLiteral("*.ttc"),
|
||||
QStringLiteral("*.ttcf"),
|
||||
QStringLiteral("*.tte"),
|
||||
QStringLiteral("*.ttf"),
|
||||
QStringLiteral("*.woff"),
|
||||
QStringLiteral("*.woff2"),
|
||||
};
|
||||
|
||||
const QStringList imageFilesFilter() {
|
||||
return imageFiles([](const QString& suffix) { return "*." + suffix; });
|
||||
@@ -486,12 +466,12 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile)
|
||||
// and all files are prefixed such as "directory/<filename>".
|
||||
// if directory is empty, then the files are prefixed with the project directory
|
||||
if (childNodeFiles.empty()) {
|
||||
auto inserter = [&childNodeFilters](const QStringList &filterSource) {
|
||||
auto inserter = [&childNodeFilters](auto &filterSource) {
|
||||
if (!childNodeFilters.empty())
|
||||
return;
|
||||
|
||||
std::for_each(filterSource.begin(),
|
||||
filterSource.end(),
|
||||
std::for_each(std::cbegin(filterSource),
|
||||
std::cend(filterSource),
|
||||
[&childNodeFilters](const auto &value) {
|
||||
if (!childNodeFilters.contains(value)) {
|
||||
childNodeFilters << value;
|
||||
@@ -510,7 +490,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile)
|
||||
} else if (childNodeName == "imagefiles") {
|
||||
inserter(imageFilesFilter());
|
||||
} else if (childNodeName == "fontfiles") {
|
||||
inserter(fontFilesFilter);
|
||||
inserter(QmlProjectManager::Constants::QDS_FONT_FILES_FILTERS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,10 +22,6 @@
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/session.h>
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
|
||||
#include <projectexplorer/deploymentdata.h>
|
||||
#include <projectexplorer/devicesupport/devicekitaspects.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
@@ -51,17 +47,6 @@ namespace {
|
||||
Q_LOGGING_CATEGORY(infoLogger, "QmlProjectManager.QmlBuildSystem", QtInfoMsg)
|
||||
}
|
||||
|
||||
ExtensionSystem::IPlugin *findMcuSupportPlugin()
|
||||
{
|
||||
const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(
|
||||
ExtensionSystem::PluginManager::plugins(),
|
||||
Utils::equal(&ExtensionSystem::PluginSpec::id, QString("mcusupport")));
|
||||
|
||||
if (pluginSpec)
|
||||
return pluginSpec->plugin();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void updateMcuBuildStep(Target *target, bool mcuEnabled)
|
||||
{
|
||||
if (auto plugin = findMcuSupportPlugin()) {
|
||||
@@ -123,6 +108,18 @@ void QmlBuildSystem::updateDeploymentData()
|
||||
setDeploymentData(deploymentData);
|
||||
}
|
||||
|
||||
QString QmlBuildSystem::defaultFontFamilyMCU() const
|
||||
{
|
||||
const QJsonObject project = m_projectItem->project();
|
||||
QString defaultFontFamily = project["mcu"].toObject()["config"].toObject()["defaultFontFamily"].toString();
|
||||
|
||||
if (!defaultFontFamily.isEmpty()) {
|
||||
return defaultFontFamily;
|
||||
}
|
||||
|
||||
return QmlProjectManager::Constants::FALLBACK_MCU_FONT_FAMILY;
|
||||
}
|
||||
|
||||
//probably this method needs to be moved into QmlProjectPlugin::initialize to be called only once
|
||||
void QmlBuildSystem::registerMenuButtons()
|
||||
{
|
||||
@@ -607,6 +604,8 @@ QVariant QmlBuildSystem::additionalData(Utils::Id id) const
|
||||
return mainFilePath().toUrlishString();
|
||||
if (id == Constants::canonicalProjectDir)
|
||||
return canonicalProjectDir().toUrlishString();
|
||||
if (id == Constants::customDefaultFontFamilyMCU)
|
||||
return defaultFontFamilyMCU();
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -701,7 +700,20 @@ bool QmlBuildSystem::qt6Project() const
|
||||
|
||||
Utils::EnvironmentItems QmlBuildSystem::environment() const
|
||||
{
|
||||
return m_projectItem->environment();
|
||||
Utils::EnvironmentItems env = m_projectItem->environment();
|
||||
|
||||
Utils::expected_str<Utils::FilePath> fontsDir = mcuFontsDir();
|
||||
if (!fontsDir) {
|
||||
qWarning() << "Failed to locate MCU installation." << fontsDir.error();
|
||||
return env;
|
||||
}
|
||||
|
||||
env.append({Constants::QMLPUPPET_ENV_MCU_FONTS_DIR, fontsDir->toUserOutput()});
|
||||
if (qtForMCUs()) {
|
||||
env.append({Constants::QMLPUPPET_ENV_DEFAULT_FONT_FAMILY, defaultFontFamilyMCU()});
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::fileSelectors() const
|
||||
|
@@ -144,6 +144,9 @@ private:
|
||||
|
||||
void registerMenuButtons();
|
||||
void updateDeploymentData();
|
||||
|
||||
[[nodiscard]] QString defaultFontFamilyMCU() const;
|
||||
|
||||
friend class FilesUpdateBlocker;
|
||||
|
||||
QmlProjectExporter::Exporter* m_fileGen;
|
||||
|
@@ -10,6 +10,10 @@
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
|
||||
#include <projectexplorer/devicesupport/devicekitaspects.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
@@ -26,10 +30,12 @@
|
||||
#include <texteditor/textdocument.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/expected.h>
|
||||
#include <utils/infobar.h>
|
||||
#include <utils/mimeconstants.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/predicates.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLoggingCategory>
|
||||
@@ -40,9 +46,52 @@
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
namespace {
|
||||
expected_str<FilePath> mcuInstallationRoot()
|
||||
{
|
||||
ExtensionSystem::IPlugin *mcuSupportPlugin = QmlProjectManager::findMcuSupportPlugin();
|
||||
if (mcuSupportPlugin == nullptr) {
|
||||
return make_unexpected("Failed to find MCU Support plugin"_L1);
|
||||
}
|
||||
|
||||
expected_str<FilePath> root;
|
||||
QMetaObject::invokeMethod(mcuSupportPlugin,
|
||||
"installationRoot",
|
||||
Qt::DirectConnection,
|
||||
Q_RETURN_ARG(expected_str<FilePath>, root));
|
||||
|
||||
return root;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
ExtensionSystem::IPlugin *findMcuSupportPlugin()
|
||||
{
|
||||
const QString pluginId = "mcusupport";
|
||||
const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(
|
||||
ExtensionSystem::PluginManager::plugins(),
|
||||
Utils::equal(&ExtensionSystem::PluginSpec::id, pluginId));
|
||||
|
||||
if (pluginSpec == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pluginSpec->plugin();
|
||||
}
|
||||
|
||||
expected_str<FilePath> mcuFontsDir()
|
||||
{
|
||||
expected_str<FilePath> mcuRoot = mcuInstallationRoot();
|
||||
if (!mcuRoot) {
|
||||
return mcuRoot;
|
||||
}
|
||||
|
||||
return *mcuRoot / "src" / "3rdparty" / "fonts";
|
||||
}
|
||||
|
||||
QmlProject::QmlProject(const Utils::FilePath &fileName)
|
||||
: Project(Utils::Constants::QMLPROJECT_MIMETYPE, fileName)
|
||||
{
|
||||
|
@@ -5,7 +5,11 @@
|
||||
|
||||
#include "buildsystem/qmlbuildsystem.h" // IWYU pragma: keep
|
||||
#include "qmlprojectmanager_global.h"
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <utils/expected.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
@@ -13,6 +17,9 @@ namespace QmlProjectManager {
|
||||
|
||||
class QmlProject;
|
||||
|
||||
ExtensionSystem::IPlugin *findMcuSupportPlugin();
|
||||
QMLPROJECTMANAGER_EXPORT Utils::expected_str<Utils::FilePath> mcuFontsDir();
|
||||
|
||||
class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@@ -11,6 +11,7 @@ const char primaryLanguageData[] = "PrimaryLanguageData";
|
||||
const char customForceFreeTypeData[] = "CustomForceFreeType";
|
||||
const char customQtForMCUs[] = "CustomQtForMCUs";
|
||||
const char customQt6Project[] = "CustomQt6Project";
|
||||
const char customDefaultFontFamilyMCU[] = "CustomDefaultFontFamilyMCU";
|
||||
|
||||
const char mainFilePath[] = "MainFilePath";
|
||||
const char canonicalProjectDir[] ="CanonicalProjectDir";
|
||||
@@ -37,4 +38,13 @@ const char G_EXPORT_CONVERT[] = "QmlDesigner.Group.ConvertProject";
|
||||
|
||||
const char fakeProjectName[] = "fake85673.qmlproject";
|
||||
|
||||
inline constexpr const char *QDS_FONT_FILES_FILTERS[] = {
|
||||
"*.afm", "*.bdf", "*.ccc", "*.cff", "*.fmp", "*.fnt", "*.otc", "*.otf", "*.pcf", "*.pfa",
|
||||
"*.pfb", "*.pfm", "*.pfr", "*.ttc", "*.ttcf", "*.tte", "*.ttf", "*.woff", "*.woff2",
|
||||
};
|
||||
constexpr char FALLBACK_MCU_FONT_FAMILY[] = "DejaVu Sans";
|
||||
// These constants should be kept in sync with their counterparts in qmlbase.h
|
||||
constexpr char QMLPUPPET_ENV_MCU_FONTS_DIR[] = "QMLPUPPET_MCU_FONTS_DIR";
|
||||
constexpr char QMLPUPPET_ENV_DEFAULT_FONT_FAMILY[] = "QMLPUPPET_DEFAULT_FONT_FAMILY";
|
||||
|
||||
} // QmlProjectManager::Constants
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "childrenchangeeventfilter.h"
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
#include "qmlpuppet/qmlbase.h"
|
||||
|
||||
#include <propertyabstractcontainer.h>
|
||||
#include <propertybindingcontainer.h>
|
||||
@@ -312,6 +313,10 @@ void NodeInstanceServer::stopRenderTimer()
|
||||
void NodeInstanceServer::createScene(const CreateSceneCommand &command)
|
||||
{
|
||||
initializeView();
|
||||
if (const QString mcuFontsFolder = qEnvironmentVariable(QmlBase::QMLPUPPET_ENV_MCU_FONTS_DIR);
|
||||
!mcuFontsFolder.isEmpty()) {
|
||||
registerFonts(QUrl::fromLocalFile(mcuFontsFolder));
|
||||
}
|
||||
registerFonts(command.resourceUrl);
|
||||
setTranslationLanguage(command.language);
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QFont>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
#include <iostream>
|
||||
@@ -13,6 +14,10 @@ class QmlBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// These constants should be kept in sync with their counterparts in qmlprojectconstants.h
|
||||
static constexpr char QMLPUPPET_ENV_MCU_FONTS_DIR[] = "QMLPUPPET_MCU_FONTS_DIR";
|
||||
static constexpr char QMLPUPPET_ENV_DEFAULT_FONT_FAMILY[] = "QMLPUPPET_DEFAULT_FONT_FAMILY";
|
||||
|
||||
struct AppArgs
|
||||
{
|
||||
public:
|
||||
@@ -65,6 +70,13 @@ protected:
|
||||
void createCoreApp()
|
||||
{
|
||||
m_coreApp.reset(new T(m_args.argc, m_args.argv));
|
||||
if (const QString defaultFontFamily = qEnvironmentVariable(
|
||||
QMLPUPPET_ENV_DEFAULT_FONT_FAMILY);
|
||||
!defaultFontFamily.isEmpty()) {
|
||||
if (qobject_cast<QGuiApplication *>(QCoreApplication::instance()) != nullptr) {
|
||||
QGuiApplication::setFont(QFont{defaultFontFamily});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<QCoreApplication> m_coreApp;
|
||||
|
@@ -162,6 +162,12 @@ void QmlRuntime::initCoreApp()
|
||||
void QmlRuntime::initQmlRunner()
|
||||
{
|
||||
registerFonts(findProjectFolder(QDir::current()));
|
||||
|
||||
if (const QString mcuFontsFolder = qEnvironmentVariable(QmlBase::QMLPUPPET_ENV_MCU_FONTS_DIR);
|
||||
!mcuFontsFolder.isEmpty()) {
|
||||
registerFonts(mcuFontsFolder);
|
||||
}
|
||||
|
||||
m_qmlEngine.reset(new QQmlApplicationEngine());
|
||||
|
||||
QStringList files;
|
||||
|
Reference in New Issue
Block a user