Merge remote-tracking branch 'origin/7.0'

Conflicts:
	src/plugins/mcusupport/mcupackage.cpp
	src/plugins/mcusupport/mcusupportoptions.cpp
	src/plugins/mcusupport/mcusupportoptions.h
	src/plugins/mcusupport/mcusupportoptionspage.cpp
	src/plugins/mcusupport/mcusupportplugin.cpp
	src/plugins/mcusupport/mcusupportsdk.cpp

Change-Id: Ib423e9f23877176f01b188104b0a179ed32c4770
This commit is contained in:
Eike Ziller
2022-02-22 14:06:18 +01:00
158 changed files with 3567 additions and 1825 deletions

View File

@@ -25,8 +25,8 @@ jobs:
matrix: matrix:
config: config:
- { - {
name: "Windows Latest MSVC", artifact: "Windows-MSVC", name: "Windows MSVC 2019", artifact: "Windows-MSVC",
os: windows-latest, os: windows-2019,
cc: "cl", cxx: "cl", cc: "cl", cxx: "cl",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat",
is_msvc: true is_msvc: true

View File

@@ -66,6 +66,9 @@ if (Qt5_VERSION VERSION_LESS 6.0.0)
if (MSVC AND MSVC_VERSION GREATER_EQUAL 1910) if (MSVC AND MSVC_VERSION GREATER_EQUAL 1910)
add_compile_options(/permissive- /Zc:__cplusplus) add_compile_options(/permissive- /Zc:__cplusplus)
endif() endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
add_compile_options(-Wno-missing-field-initializers)
endif()
else() else()
# Common intermediate directory for QML modules which are defined via qt_add_qml_module() # Common intermediate directory for QML modules which are defined via qt_add_qml_module()
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml_modules") set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml_modules")

View File

@@ -39,6 +39,17 @@
\image qtcreator-cmake-build-settings-initial.png "CMake build settings" \image qtcreator-cmake-build-settings-initial.png "CMake build settings"
\uicontrol {Initial Configuration} lists the variables that are used to
configure the CMake project for the first time. The default values that
are inherited from the kit's CMake configuration are displayed in italic.
The initial configuration list of variables is saved in the project's source
directory as the \e CMakeLists.txt.user file.
\uicontrol {Current Configuration} lists the CMake variables in the
\c cmake-file-api JSON export in the \c {.cmake/api/v1/reply} directory.
The variables that are inherited from the initial configuration are
displayed in italic. Mismatched values are displayed in red.
You can view and edit the actual values of the variables that are passed You can view and edit the actual values of the variables that are passed
to CMake. Variable names are listed in the \uicontrol Key column and their to CMake. Variable names are listed in the \uicontrol Key column and their
current values in the \uicontrol Value column. For more information about current values in the \uicontrol Value column. For more information about

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -291,7 +291,7 @@
\row \row
\li M106 \li M106
\li Warning \li Warning
\li \c Name is already a var \li \c Name already is a var
\li \li
\row \row
@@ -416,6 +416,12 @@
\li A state cannot have the specified child item \li A state cannot have the specified child item
\li \li
\row
\li M129
\li Error
\li Type cannot be instantiated recursively
\li
\row \row
\li M201 \li M201
\li Hint \li Hint
@@ -430,6 +436,7 @@
\li Use only one statement per line \li Use only one statement per line
\li \li
\if defined(qtdesignstudio)
\row \row
\li M203 \li M203
\li Warning \li Warning
@@ -463,60 +470,70 @@
\row \row
\li M208 \li M208
\li Error \li Error
\li This id might be ambiguous and is not supported in \QDS. \li This id might be ambiguous and is not supported in \QDS
\li \li
\row \row
\li M209 \li M209
\li Error \li Error
\li This type (type name) is not supported as a root element in \li This type (type name) is not supported as a root element in
\QDS. \QDS
\li \li
\endif
\row \row
\li M220 \li M220
\li Error \li Error
\li This type (type name) is not supported as a root element of a \li This type (type name) is not supported as a root element of a
UI file (.ui.qml). UI file (.ui.qml)
\li \li For more information about supported QML types, see \l{UI Files}.
\row \row
\li M221 \li M221
\li Error \li Error
\li This type (type name) is not supported in a UI file (.ui.qml). \li This type (type name) is not supported in a UI file (.ui.qml)
\li \li For more information about supported QML types, see \l{UI Files}.
\row \row
\li M222 \li M222
\li Error \li Error
\li Functions are not supported in a UI file (.ui.qml). \li Functions are not supported in a UI file (.ui.qml)
\li For a list of supported JavaScript functions, see \li For a list of supported JavaScript functions, see
\l{Supported Methods}. \l{Supported Methods}.
\row \row
\li M223 \li M223
\li Error \li Error
\li Java Script blocks are not supported in a UI file (.ui.qml). \li JavaScript blocks are not supported in a UI file (.ui.qml)
\li \li For more information about supported features, see \l{UI Files}.
\row \row
\li M224 \li M224
\li Error \li Error
\li Behavior type is not supported in a UI file (.ui.qml). \li Behavior type is not supported in a UI file (.ui.qml)
\li \li For more information about supported QML types, see \l{UI Files}.
\row \row
\li M225 \li M225
\li Error \li Error
\li States are only supported in the root item in a UI file (.ui.qml). \li States are only supported in the root item in a UI file (.ui.qml)
\li \li For more information about supported features, see \l{UI Files}.
\row \row
\li M226 \li M226
\li Error \li Error
\li Referencing the parent of the root item is not supported in a \li Referencing the parent of the root item is not supported in a
UI file (.ui.qml). UI file (.ui.qml)
\li \li For more information about supported features, see \l{UI Files}.
\row
\li M227
\li Error
\li Do not mix translation functions in a UI file (.ui.qml)
\li Even though several different translation functions, such as
\c qsTr and \c qsTrId are supported, you should pick one and
use it consistently within a UI file. For more information,
see \l{Qt QML Methods}.
\row \row
\li M300 \li M300
@@ -674,11 +691,30 @@
and most likely invalid and most likely invalid
\li \li
\row
\li M325
\li Warning
\li Logical value does not depend on actual values
\li
\row
\li M326
\li Error
\li Components are only allowed to have a single child element
\li For more information, see \l [QML] {Component}.
\row
\li M327
\li Warning
\li Components require a child element
\li For more information, see \l [QML] {Component}.
\row \row
\li M400 \li M400
\li Warning \li Warning
\li Duplicate import \li Duplicate import
\li \li An import statement has been added twice. For more information,
see \l{Import Statements}.
\endtable \endtable

View File

@@ -83,7 +83,7 @@
By default, logging categories and messages coming directly from Qt are By default, logging categories and messages coming directly from Qt are
disabled. To display them, select \inlineimage icons/qtlogo-16.png disabled. To display them, select \inlineimage icons/qtlogo-16.png
(\uicontrol {Toggle logging of Qt internal loggings.}) (\uicontrol {Toggle Qt Internal Logging}).
New messages automatically scroll the message display to the bottom. New messages automatically scroll the message display to the bottom.
To stop automatic scrolling, toggle \inlineimage icons/arrowdown.png To stop automatic scrolling, toggle \inlineimage icons/arrowdown.png

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2021 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -52,6 +52,7 @@
be edited in \QDS only. be edited in \QDS only.
\endif \endif
The following features are not supported in .ui.qml files: The following features are not supported in .ui.qml files:
\list \list
@@ -61,6 +62,7 @@
\li States in other components than the root component \li States in other components than the root component
\li Root components that are not derived from \l QQuickItem or \li Root components that are not derived from \l QQuickItem or
\l [QML]{Item} \l [QML]{Item}
\li Referencing the parent of the root component
\endlist \endlist
The following components are not supported: The following components are not supported:
@@ -69,11 +71,9 @@
\li Behavior \li Behavior
\li Binding \li Binding
\li Canvas \li Canvas
\li Component
\li Shader Effect \li Shader Effect
\li Timer \li Timer
\li Transform \li Transform
\li Transition
\endlist \endlist
\section1 Supported Methods \section1 Supported Methods
@@ -165,6 +165,8 @@
\li \l{Qt::}{qsTrNoOp()} \li \l{Qt::}{qsTrNoOp()}
\endlist \endlist
\note Do not mix translation methods in a UI file.
For more information about using the methods, see For more information about using the methods, see
\l{https://doc.qt.io/qt/qml-qtqml-qt.html}{Qt QML Methods}. \l{https://doc.qt.io/qt/qml-qtqml-qt.html}{Qt QML Methods}.

View File

@@ -74,12 +74,8 @@
In \uicontrol Navigator, select \e particleSystem and in In \uicontrol Navigator, select \e particleSystem and in
\uicontrol Properties, set \uicontrol Translation > \uicontrol Y to 193. \uicontrol Properties, set \uicontrol Translation > \uicontrol Y to 193.
\li Set the \e rain-drop-white-square.png as texture for the particles. \li Set the \e rain-drop-white-square.png as texture for the particles.
From \uicontrol Library > \uicontrol Components, drag a \uicontrol Texture From \uicontrol Library > \uicontrol Assets, drag
to \e spriteParticle. \e {rain-drop-white-square.png} to \e spriteParticle.
\li In \uicontrol Navigator, select \uicontrol texture1 and in \uicontrol
Properties, set \uicontrol Source to \e rain-drop-white-square.png.
\li In \uicontrol Navigator, select \uicontrol spriteParticle and in the
\uicontrol Properties, set \uicontrol Sprite to texture.
\li Adjust the apperance and behavior of the sprite further. In \uicontrol \li Adjust the apperance and behavior of the sprite further. In \uicontrol
Properties, set: Properties, set:
\list \list

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -38,7 +38,7 @@
\QDS is available in binary packages for the following operating systems: \QDS is available in binary packages for the following operating systems:
\list \list
\li \macOS 10.15 \li \macOS 11.0
\li Linux: \li Linux:
\list \list
\li CentOS 8.1 \li CentOS 8.1

View File

@@ -92,22 +92,9 @@
\li Drag-and-drop an instance of the \uicontrol {Particle System} \li Drag-and-drop an instance of the \uicontrol {Particle System}
component from \uicontrol Library to a scene component instance component from \uicontrol Library to a scene component instance
in \l Navigator. in \l Navigator.
\li Drag-and-drop an instance of the \uicontrol Texture component
from \uicontrol Library > \uicontrol Components >
\uicontrol {Qt Quick 3D} to the sprite particle instance
in \uicontrol Navigator.
\li Drag-and-drop the sprite image from \uicontrol Library > \li Drag-and-drop the sprite image from \uicontrol Library >
\uicontrol Assets to the texture instance in \uicontrol Navigator. \uicontrol Assets to the sprite particle instance
\li Select the sprite particle instance in \uicontrol Navigator to in \uicontrol Navigator.
display its properties in \l Properties.
\li In \uicontrol Sprite, select the texture instance.
\li Select the emitter instance in \uicontrol Navigator to
display its properties in \uicontrol Properties.
\li In \uicontrol Particle, select the particle instance to emit.
\li Select the vector 3D instance in \uicontrol Navigator to
display its properties in \uicontrol Properties.
\li In \uicontrol Direction, set the emitted particle velocity
towards the target vector.
\endlist \endlist
Add instances of other components according to your use case. The following Add instances of other components according to your use case. The following
@@ -122,6 +109,9 @@
their property values, such as particle source images and their color, life their property values, such as particle source images and their color, life
span, and fading effects, to simulate fire. span, and fading effects, to simulate fire.
You can download the completed project from
\l {https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/FireParticles}{here}.
We will need the following \l{Assets}{assets}: We will need the following \l{Assets}{assets}:
\list \list
@@ -199,12 +189,16 @@
\uicontrol {Particle end scale} to \e 5.00 for the flame \uicontrol {Particle end scale} to \e 5.00 for the flame
particles and to \e 6.00 for the smoke particles. particles and to \e 6.00 for the smoke particles.
We can now modify the appearance of the particles by setting their color in We can now modify the appearance of the particles by selecting the
\e spriteParticle in \uicontrol Navigator and then setting their color in
\uicontrol Properties > \uicontrol Particle. We select transparent yellow, \uicontrol Properties > \uicontrol Particle. We select transparent yellow,
orange, and transparent gray in \uicontrol Color and set values for orange, and transparent gray in \uicontrol Color and set values for
\uicontrol {Color variation} to use slightly different colors for the \uicontrol {Color variation} to use slightly different colors for the
individual particles. individual particles.
We can also try changing the \uicontrol{Blend Mode} for the particle to get
a more realistic fire effect.
\image studio-3d-particles-fire-properties-particle.png "Particle properties" \image studio-3d-particles-fire-properties-particle.png "Particle properties"
We set \uicontrol {Fade in effect} and \uicontrol {Fade out effect} values We set \uicontrol {Fade in effect} and \uicontrol {Fade out effect} values
@@ -220,6 +214,11 @@
\image studio-3d-particles-fire-properties-sprite-particle.png "Sprite Particle properties" \image studio-3d-particles-fire-properties-sprite-particle.png "Sprite Particle properties"
In \uicontrol{Particle Rotation}, we also need to set \uicontrol Rotation
and \uicontrol{Velocity Variation} for all emitters to 0.
\image studio-3d-particles-fire-properties-rotation.png "Emitter rotation properties"
Finally, we will specify the direction in which the particles move by Finally, we will specify the direction in which the particles move by
modifying the property values of the \uicontrol {Vector Direction} component modifying the property values of the \uicontrol {Vector Direction} component
instances in \uicontrol Properties > \uicontrol {Particle Vector Direction}. instances in \uicontrol Properties > \uicontrol {Particle Vector Direction}.

View File

@@ -50,7 +50,7 @@ Product {
flags.push("-Wno-deprecated-copy", "-Wno-constant-logical-operand"); flags.push("-Wno-deprecated-copy", "-Wno-constant-logical-operand");
} }
if (!qbs.toolchain.contains("clang")) { if (!qbs.toolchain.contains("clang")) {
flags.push("-Wno-noexcept-type"); flags.push("-Wno-missing-field-initializers", "-Wno-noexcept-type");
if (Utilities.versionCompare(cpp.compilerVersion, "9") >= 0) if (Utilities.versionCompare(cpp.compilerVersion, "9") >= 0)
flags.push("-Wno-deprecated-copy", "-Wno-init-list-lifetime"); flags.push("-Wno-deprecated-copy", "-Wno-init-list-lifetime");
} }

View File

@@ -0,0 +1,65 @@
import qbs
import qbs.File
import qbs.FileInfo
Module {
property bool preferExternalLibs: true
Depends { name: "pkgconfig"; condition: preferExternalLibs; required: false }
Depends { name: "gtest"; condition: preferExternalLibs; required: false }
Depends { name: "gmock"; condition: preferExternalLibs; required: false }
Depends { name: "cpp" }
Probe {
id: gtestProbe
property string repoDir
property string gtestDir
property string gmockDir
property bool hasRepo
configure: {
repoDir = FileInfo.cleanPath(path + "/../../../tests/unit/unittest/3rdparty/googletest");
gtestDir = FileInfo.joinPaths(repoDir, "googletest");
gmockDir = FileInfo.joinPaths(repoDir, "googlemock");
hasRepo = File.exists(gtestDir);
found = hasRepo;
}
}
property bool hasRepo: gtestProbe.hasRepo
property bool externalLibsPresent: preferExternalLibs && gtest.present && gmock.present
property bool useRepo: !externalLibsPresent && hasRepo
property string gtestDir: gtestProbe.gtestDir
property string gmockDir: gtestProbe.gmockDir
Group {
name: "Files from repository"
condition: qtc_gtest_gmock.useRepo
cpp.includePaths: [
qtc_gtest_gmock.gtestDir,
qtc_gtest_gmock.gmockDir,
FileInfo.joinPaths(qtc_gtest_gmock.gtestDir, "include"),
FileInfo.joinPaths(qtc_gtest_gmock.gmockDir, "include"),
]
files: [
FileInfo.joinPaths(qtc_gtest_gmock.gtestDir, "src", "gtest-all.cc"),
FileInfo.joinPaths(qtc_gtest_gmock.gmockDir, "src", "gmock-all.cc"),
]
}
Properties {
condition: qtc_gtest_gmock.useRepo
cpp.includePaths: [
FileInfo.joinPaths(qtc_gtest_gmock.gtestDir, "include"),
FileInfo.joinPaths(qtc_gtest_gmock.gmockDir, "include"),
]
}
validate: {
if (!qtc_gtest_gmock.externalLibsPresent && !gtestProbe.found) {
console.warn("No GTest found.");
throw new Error();
}
}
}

View File

@@ -19,6 +19,7 @@
"qbs.FileInfo", "qbs.FileInfo",
"qbs.ModUtils", "qbs.ModUtils",
"qbs.PathTools", "qbs.PathTools",
"qbs.PkgConfig",
"qbs.Probes", "qbs.Probes",
"qbs.Process", "qbs.Process",
"qbs.PropertyList", "qbs.PropertyList",

View File

@@ -133,6 +133,7 @@ Module {
Property { name: "multiplexedType"; type: "string"; isList: true } Property { name: "multiplexedType"; type: "string"; isList: true }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "profiles"; type: "string"; isList: true } Property { name: "profiles"; type: "string"; isList: true }
Property { name: "qbsModuleProviders"; type: "string"; isList: true }
Property { name: "qbsSearchPaths"; type: "string"; isList: true } Property { name: "qbsSearchPaths"; type: "string"; isList: true }
Property { name: "targetName"; type: "string" } Property { name: "targetName"; type: "string" }
Property { name: "type"; type: "string"; isList: true } Property { name: "type"; type: "string"; isList: true }
@@ -155,6 +156,7 @@ Module {
Property { name: "minimumQbsVersion"; type: "string" } Property { name: "minimumQbsVersion"; type: "string" }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "profile"; type: "string" } Property { name: "profile"; type: "string" }
Property { name: "qbsModuleProviders"; type: "string"; isList: true }
Property { name: "qbsSearchPaths"; type: "string"; isList: true } Property { name: "qbsSearchPaths"; type: "string"; isList: true }
Property { name: "references"; type: "string"; isList: true } Property { name: "references"; type: "string"; isList: true }
Property { name: "sourceDirectory"; type: "string" } Property { name: "sourceDirectory"; type: "string" }

View File

@@ -398,6 +398,8 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item); QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
const bool rootIs3dNode = rootNodeInstance().isSubclassOf("QQuick3DNode");
const bool renderEffects = qEnvironmentVariableIsSet("QMLPUPPET_RENDER_EFFECTS"); const bool renderEffects = qEnvironmentVariableIsSet("QMLPUPPET_RENDER_EFFECTS");
if (renderEffects) { if (renderEffects) {
@@ -426,6 +428,9 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
QRectF renderBoundingRect; QRectF renderBoundingRect;
if (instance.isValid()) if (instance.isValid())
renderBoundingRect = instance.boundingRect(); renderBoundingRect = instance.boundingRect();
else if (rootIs3dNode)
renderBoundingRect = item->boundingRect();
else else
renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item); renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item);

View File

@@ -133,6 +133,14 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
nodeInstanceClient()->synchronizeWithClientProcess(); nodeInstanceClient()->synchronizeWithClientProcess();
} }
if (rootNodeInstance().isSubclassOf("QQuick3DNode") && rootNodeInstance().contentItem()
&& DesignerSupport::isDirty(rootNodeInstance().contentItem(),
DesignerSupport::ContentUpdateMask)
&& nodeInstanceClient()->bytesToWrite() < 10000) {
Internal::QuickItemNodeInstance::updateDirtyNode(rootNodeInstance().contentItem());
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
}
inFunction = false; inFunction = false;
} }
} }

View File

@@ -55,6 +55,8 @@
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
const QRectF preview3dBoundingRect(0, 0, 640, 480);
Quick3DNodeInstance::Quick3DNodeInstance(QObject *node) Quick3DNodeInstance::Quick3DNodeInstance(QObject *node)
: ObjectNodeInstance(node) : ObjectNodeInstance(node)
{ {
@@ -97,7 +99,7 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// In case this is the scene root, we need to create a dummy View3D for the scene // In case this is the scene root, we need to create a dummy View3D for the scene
// in preview puppets // in preview puppets
if (instanceId() == 0 && nodeInstanceServer()->isPreviewServer()) { if (instanceId() == 0 && (!nodeInstanceServer()->isInformationServer())) {
auto helper = new QmlDesigner::Internal::GeneralHelper(); auto helper = new QmlDesigner::Internal::GeneralHelper();
engine()->rootContext()->setContextProperty("_generalHelper", helper); engine()->rootContext()->setContextProperty("_generalHelper", helper);
@@ -111,8 +113,8 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
nodeInstanceServer()->setRootItem(m_dummyRootView); nodeInstanceServer()->setRootItem(m_dummyRootView);
} }
#endif #endif // QT_VERSION
#endif #endif // QUICK3D_MODULE
ObjectNodeInstance::initialize(objectNodeInstance, flags); ObjectNodeInstance::initialize(objectNodeInstance, flags);
} }
@@ -122,7 +124,7 @@ QImage Quick3DNodeInstance::renderImage() const
if (!isRootNodeInstance() || !m_dummyRootView) if (!isRootNodeInstance() || !m_dummyRootView)
return {}; return {};
QSize size(640, 480); QSize size = preview3dBoundingRect.size().toSize();
nodeInstanceServer()->quickWindow()->resize(size); nodeInstanceServer()->quickWindow()->resize(size);
m_dummyRootView->setSize(size); m_dummyRootView->setSize(size);
@@ -190,13 +192,37 @@ bool Quick3DNodeInstance::isRenderable() const
return m_dummyRootView; return m_dummyRootView;
} }
bool Quick3DNodeInstance::hasContent() const
{
return true;
}
QRectF Quick3DNodeInstance::boundingRect() const QRectF Quick3DNodeInstance::boundingRect() const
{ {
//The information server has no m_dummyRootView therefore we use the hardcoded value
if (nodeInstanceServer()->isInformationServer())
return preview3dBoundingRect;
if (m_dummyRootView) if (m_dummyRootView)
return m_dummyRootView->boundingRect(); return m_dummyRootView->boundingRect();
return ObjectNodeInstance::boundingRect(); return ObjectNodeInstance::boundingRect();
} }
QRectF Quick3DNodeInstance::contentItemBoundingBox() const
{
return boundingRect();
}
QPointF Quick3DNodeInstance::position() const
{
return QPointF(0, 0);
}
QSizeF Quick3DNodeInstance::size() const
{
return boundingRect().size();
}
QList<ServerNodeInstance> Quick3DNodeInstance::stateInstances() const QList<ServerNodeInstance> Quick3DNodeInstance::stateInstances() const
{ {
QList<ServerNodeInstance> instanceList; QList<ServerNodeInstance> instanceList;
@@ -212,6 +238,11 @@ QList<ServerNodeInstance> Quick3DNodeInstance::stateInstances() const
return instanceList; return instanceList;
} }
QQuickItem *Quick3DNodeInstance::contentItem() const
{
return m_dummyRootView;
}
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
{ {
return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer()); return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer());

View File

@@ -51,10 +51,16 @@ public:
QImage renderPreviewImage(const QSize &previewImageSize) const override; QImage renderPreviewImage(const QSize &previewImageSize) const override;
bool isRenderable() const override; bool isRenderable() const override;
bool hasContent() const override;
QRectF boundingRect() const override; QRectF boundingRect() const override;
QRectF contentItemBoundingBox() const override;
QPointF position() const override;
QSizeF size() const override;
QList<ServerNodeInstance> stateInstances() const override; QList<ServerNodeInstance> stateInstances() const override;
QQuickItem *contentItem() const override;
protected: protected:
explicit Quick3DNodeInstance(QObject *node); explicit Quick3DNodeInstance(QObject *node);

View File

@@ -162,6 +162,11 @@ bool ServerNodeInstance::isComponentWrap() const
return m_nodeInstance->isComponentWrap(); return m_nodeInstance->isComponentWrap();
} }
QQuickItem *ServerNodeInstance::contentItem() const
{
return m_nodeInstance->contentItem();
}
void ServerNodeInstance::updateDirtyNodeRecursive() void ServerNodeInstance::updateDirtyNodeRecursive()
{ {
m_nodeInstance->updateAllDirtyNodesRecursive(); m_nodeInstance->updateAllDirtyNodesRecursive();

View File

@@ -188,6 +188,8 @@ public:
bool isComponentWrap() const; bool isComponentWrap() const;
QQuickItem *contentItem() const;
private: // functions private: // functions
ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance); ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);

View File

@@ -98,6 +98,8 @@ Item {
StudioControls.Menu { StudioControls.Menu {
id: contextMenu id: contextMenu
closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Expand All") text: qsTr("Expand All")
enabled: allExpandedState !== 1 enabled: allExpandedState !== 1
@@ -167,7 +169,7 @@ Item {
Dialog { Dialog {
id: renameFolderDialog id: renameFolderDialog
title: qsTr("Rename folder") title: qsTr("Rename Folder")
anchors.centerIn: parent anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
implicitWidth: 280 implicitWidth: 280
@@ -192,15 +194,15 @@ Item {
} }
Text { Text {
text: qsTr("Folder Name cannot be empty.") text: qsTr("Folder name cannot be empty.")
color: "#ff0000" color: "#ff0000"
visible: folderRename.text === "" && !renameFolderDialog.renameError visible: folderRename.text === "" && !renameFolderDialog.renameError
} }
Text { Text {
text: qsTr("Could not rename directory. Make sure no folder with the same name exists.") text: qsTr("Could not rename folder. Make sure no folder with the same name exists.")
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
width: renameFolderDialog.width width: renameFolderDialog.width - 12
color: "#ff0000" color: "#ff0000"
visible: renameFolderDialog.renameError visible: renameFolderDialog.renameError
} }
@@ -259,7 +261,7 @@ Item {
Dialog { Dialog {
id: newFolderDialog id: newFolderDialog
title: qsTr("Create new folder") title: qsTr("Create New Folder")
anchors.centerIn: parent anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
modal: true modal: true
@@ -269,7 +271,7 @@ Item {
Row { Row {
Text { Text {
text: qsTr("Folder Name: ") text: qsTr("Folder name: ")
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: StudioTheme.Values.themeTextColor color: StudioTheme.Values.themeTextColor
} }
@@ -287,7 +289,7 @@ Item {
} }
Text { Text {
text: qsTr("Folder Name cannot be empty.") text: qsTr("Folder name cannot be empty.")
color: "#ff0000" color: "#ff0000"
anchors.right: parent.right anchors.right: parent.right
visible: folderName.text === "" visible: folderName.text === ""
@@ -329,7 +331,7 @@ Item {
Dialog { Dialog {
id: confirmDeleteFolderDialog id: confirmDeleteFolderDialog
title: qsTr("Folder not empty") title: qsTr("Folder Not Empty")
anchors.centerIn: parent anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
implicitWidth: 300 implicitWidth: 300
@@ -342,7 +344,7 @@ Item {
Text { Text {
id: folderNotEmpty id: folderNotEmpty
text: qsTr("Folder '%1' is not empty. Are you sure you want to delete it?") text: qsTr("Folder \"%1\" is not empty. Delete it anyway?")
.arg(contextDir ? contextDir.dirName : "") .arg(contextDir ? contextDir.dirName : "")
color: StudioTheme.Values.themeTextColor color: StudioTheme.Values.themeTextColor
wrapMode: Text.WordWrap wrapMode: Text.WordWrap

View File

@@ -59,8 +59,8 @@ Section {
PropertyLabel { PropertyLabel {
visible: root.showAudioOutput visible: root.showAudioOutput
text: qsTr("Audio Output") text: qsTr("Audio output")
tooltip: qsTr("Holds the target audio output.") tooltip: qsTr("Target audio output.")
} }
SecondColumnLayout { SecondColumnLayout {
@@ -80,8 +80,8 @@ Section {
PropertyLabel { PropertyLabel {
visible: root.showVideoOutput visible: root.showVideoOutput
text: qsTr("Video Output") text: qsTr("Video output")
tooltip: qsTr("Holds the target video output.") tooltip: qsTr("Target video output.")
} }
SecondColumnLayout { SecondColumnLayout {

View File

@@ -41,7 +41,7 @@ import QtQuickDesignerTheme 1.0
import StudioTheme 1.0 as StudioTheme import StudioTheme 1.0 as StudioTheme
Section { Section {
caption: qsTr("Button content") caption: qsTr("Button Content")
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@@ -49,7 +49,7 @@ Section {
SectionLayout { SectionLayout {
PropertyLabel { PropertyLabel {
text: qsTr("Text") text: qsTr("Text")
tooltip: qsTr("The text displayed on the button.") tooltip: qsTr("Text displayed on the button.")
} }
SecondColumnLayout { SecondColumnLayout {

View File

@@ -41,7 +41,7 @@ Column {
SectionLayout { SectionLayout {
PropertyLabel { PropertyLabel {
text: qsTr("Active") text: qsTr("Active")
tooltip: qsTr("This property is true if the Loader is currently active.") tooltip: qsTr("Whether the loader is currently active.")
} }
SecondColumnLayout { SecondColumnLayout {
@@ -57,7 +57,7 @@ Column {
PropertyLabel { PropertyLabel {
text: qsTr("Source") text: qsTr("Source")
tooltip: qsTr("This property holds the URL of the QML component to instantiate.") tooltip: qsTr("URL of the component to instantiate.")
} }
SecondColumnLayout { SecondColumnLayout {
@@ -70,8 +70,8 @@ Column {
} }
PropertyLabel { PropertyLabel {
text: qsTr("Source Component") text: qsTr("Source component")
tooltip: qsTr("This property holds the component to instantiate.") tooltip: qsTr("Component to instantiate.")
} }
SecondColumnLayout { SecondColumnLayout {
@@ -88,7 +88,7 @@ Column {
PropertyLabel { PropertyLabel {
text: qsTr("Asynchronous") text: qsTr("Asynchronous")
tooltip: qsTr("This property holds whether the component will be instantiated asynchronously.") tooltip: qsTr("Whether the component will be instantiated asynchronously.")
} }
SecondColumnLayout { SecondColumnLayout {

View File

@@ -386,6 +386,7 @@ SecondColumnLayout {
property ListModel items: ListModel {} property ListModel items: ListModel {}
enabled: isBaseState
implicitWidth: StudioTheme.Values.colorEditorPopupCmoboBoxWidth implicitWidth: StudioTheme.Values.colorEditorPopupCmoboBoxWidth
width: implicitWidth width: implicitWidth
actionIndicatorVisible: false actionIndicatorVisible: false
@@ -442,6 +443,13 @@ SecondColumnLayout {
} }
colorEditor.updateThumbnail() colorEditor.updateThumbnail()
} }
ToolTipArea {
enabled: !isBaseState
anchors.fill: parent
tooltip: qsTr("Fill type can only be changed in base state.")
z: 10
}
} }
ExpandingSpacer {} ExpandingSpacer {}

View File

@@ -218,7 +218,7 @@ Section {
AbstractButton { AbstractButton {
id: editAnnotationButton id: editAnnotationButton
buttonIcon: StudioTheme.Constants.edit buttonIcon: StudioTheme.Constants.edit
tooltip: qsTr("Edit annotation") tooltip: qsTr("Edit Annotation")
onClicked: annotationEditor.showWidget() onClicked: annotationEditor.showWidget()
onHoveredChanged: annotationEditor.checkAux() onHoveredChanged: annotationEditor.checkAux()
} }
@@ -226,7 +226,7 @@ Section {
AbstractButton { AbstractButton {
id: removeAnnotationButton id: removeAnnotationButton
buttonIcon: StudioTheme.Constants.closeCross buttonIcon: StudioTheme.Constants.closeCross
tooltip: qsTr("Remove annotation") tooltip: qsTr("Remove Annotation")
onClicked: annotationEditor.removeFullAnnotation() onClicked: annotationEditor.removeFullAnnotation()
onHoveredChanged: annotationEditor.checkAux() onHoveredChanged: annotationEditor.checkAux()
} }

View File

@@ -35,13 +35,14 @@ import QtQuick.VirtualKeyboard %{QtQuickVersion}
@endif @endif
Window { Window {
width: Constants.width width: mainScreen.width
height: Constants.height height: mainScreen.height
visible: true visible: true
title: "%{ProjectName}" title: "%{ProjectName}"
%{UIClassName} { %{UIClassName} {
id: mainScreen
} }
@if %{UseVirtualKeyboard} @if %{UseVirtualKeyboard}

View File

@@ -62,6 +62,10 @@ Project {
Environment { Environment {
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
QT_AUTO_SCREEN_SCALE_FACTOR: "1" QT_AUTO_SCREEN_SCALE_FACTOR: "1"
@if %{IsQt6Project}
@else
QMLSCENE_CORE_PROFILE: "true" // Required for macOS, but can create issues on embedded Linux
@endif
@if %{UseVirtualKeyboard} @if %{UseVirtualKeyboard}
QT_IM_MODULE: "qtvirtualkeyboard" QT_IM_MODULE: "qtvirtualkeyboard"
QT_VIRTUALKEYBOARD_DESKTOP_DISABLE: 1 QT_VIRTUALKEYBOARD_DESKTOP_DISABLE: 1

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="OpenDocuments"><widget name="FileSystem" closed="true"/><widget name="OpenDocuments" closed="true"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>346 0 365</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="true"/></area><sizes>712 0</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="true"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="true"/></area><sizes>0 0</sizes></splitter><sizes>914 0</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="1" current=""><widget name="StatesEditor" closed="true"/></area><area tabs="1" current=""><widget name="TransitionEditor" closed="true"/></area><sizes>0 0</sizes></splitter><sizes>712 0</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="true"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="true"/></area><sizes>712 0 0</sizes></splitter><sizes>310 914 406</sizes></splitter><area tabs="2" current="Timelines"><widget name="Timelines" closed="false"/><widget name="CurveEditorId" closed="false"/></area><sizes>712 255</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="FileSystem"><widget name="FileSystem" closed="true"/><widget name="OpenDocuments" closed="true"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>541 0 426</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="false"/></area><sizes>353 353</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="true"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="true"/></area><sizes>0 0</sizes></splitter><sizes>919 0</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="3" current="Timelines"><widget name="Timelines" closed="false"/><widget name="CurveEditorId" closed="false"/><widget name="StatesEditor" closed="true"/></area><area tabs="1" current=""><widget name="TransitionEditor" closed="true"/></area><sizes>919 0</sizes></splitter><sizes>707 260</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="true"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="true"/></area><sizes>968 0 0</sizes></splitter><sizes>312 919 408</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="FileSystem"><widget name="FileSystem" closed="true"/><widget name="OpenDocuments" closed="true"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>481 0 486</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="true"/></area><sizes>968 0</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="true"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="true"/></area><sizes>968 0</sizes></splitter><sizes>919 0</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="2" current="Timelines"><widget name="StatesEditor" closed="true"/><widget name="Timelines" closed="true"/></area><area tabs="2" current="TransitionEditor"><widget name="CurveEditorId" closed="true"/><widget name="TransitionEditor" closed="true"/></area><sizes>0 919</sizes></splitter><sizes>968 0</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="true"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="true"/></area><sizes>968 0 0</sizes></splitter><sizes>312 919 408</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="OpenDocuments"><widget name="FileSystem" closed="true"/><widget name="OpenDocuments" closed="true"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>541 0 426</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="true"/></area><sizes>707 0</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="false"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="false"/></area><sizes>488 218</sizes></splitter><sizes>601 448</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="2" current="StatesEditor"><widget name="StatesEditor" closed="false"/><widget name="Timelines" closed="true"/></area><area tabs="2" current="TransitionEditor"><widget name="CurveEditorId" closed="true"/><widget name="TransitionEditor" closed="true"/></area><sizes>1050 0</sizes></splitter><sizes>707 260</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="true"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="false"/></area><sizes>541 0 426</sizes></splitter><sizes>274 1050 315</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="OpenDocuments"><widget name="FileSystem" closed="true"/><widget name="OpenDocuments" closed="true"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>487 0 480</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="true"/></area><sizes>707 0</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="true"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="true"/></area><sizes>707 0</sizes></splitter><sizes>914 0</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="2" current="StatesEditor"><widget name="StatesEditor" closed="false"/><widget name="Timelines" closed="true"/></area><area tabs="2" current="TransitionEditor"><widget name="CurveEditorId" closed="true"/><widget name="TransitionEditor" closed="true"/></area><sizes>914 0</sizes></splitter><sizes>707 260</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="true"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="false"/></area><sizes>707 0 260</sizes></splitter><sizes>310 914 406</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><QtAdvancedDockingSystem version="1" userVersion="0" containers="1"><container floating="false"><splitter orientation="Horizontal" count="3"><splitter orientation="Vertical" count="3"><area tabs="2" current="Navigator"><widget name="Navigator" closed="false"/><widget name="Projects" closed="false"/></area><area tabs="2" current="FileSystem"><widget name="FileSystem" closed="false"/><widget name="OpenDocuments" closed="false"/></area><area tabs="2" current="Components"><widget name="Components" closed="false"/><widget name="Assets" closed="false"/></area><sizes>343 353 270</sizes></splitter><splitter orientation="Vertical" count="2"><splitter orientation="Horizontal" count="2"><splitter orientation="Vertical" count="2"><area tabs="1" current="FormEditor"><widget name="FormEditor" closed="false"/></area><area tabs="1" current="Editor3D"><widget name="Editor3D" closed="false"/></area><sizes>353 353</sizes></splitter><splitter orientation="Vertical" count="2"><area tabs="1" current="TextEditor"><widget name="TextEditor" closed="false"/></area><area tabs="1" current="OutputPane"><widget name="OutputPane" closed="false"/></area><sizes>353 353</sizes></splitter><sizes>448 465</sizes></splitter><splitter orientation="Horizontal" count="2"><area tabs="2" current="StatesEditor"><widget name="StatesEditor" closed="false"/><widget name="Timelines" closed="false"/></area><area tabs="2" current="CurveEditorId"><widget name="CurveEditorId" closed="false"/><widget name="TransitionEditor" closed="false"/></area><sizes>457 456</sizes></splitter><sizes>707 260</sizes></splitter><splitter orientation="Vertical" count="3"><area tabs="1" current="Properties"><widget name="Properties" closed="false"/></area><area tabs="1" current="TranslationsView"><widget name="TranslationsView" closed="false"/></area><area tabs="1" current="ConnectionView"><widget name="ConnectionView" closed="false"/></area><sizes>343 353 270</sizes></splitter><sizes>310 914 406</sizes></splitter></container></QtAdvancedDockingSystem>

View File

@@ -1,4 +0,0 @@
import QtQuick 2.4
%{FormClass} {
}

View File

@@ -1,6 +0,0 @@
import QtQuick 2.4
Item {
width: 400
height: 400
}

View File

@@ -1,91 +0,0 @@
{
"version": 1,
"supportedProjectTypes": [ ],
"id": "R.QtQuickUi",
"category": "R.Qt",
"trDescription": "Creates a Qt Quick Designer UI form along with a matching QML file for implementation purposes. You can add the form and file to an existing Qt Quick Project.",
"trDisplayName": "QtQuick UI File",
"trDisplayCategory": "Qt",
"iconText": "ui.qml",
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.UiFiles" ],
"enabled": "%{JS: value('Plugins').indexOf('QmlJSEditor') >= 0}",
"options" : [
{ "key": "QmlFile", "value": "%{Class}.%{JS: Util.preferredSuffix('text/x-qml')}" },
{ "key": "UiFile", "value": "%{FormClass}.%{JS: Util.preferredSuffix('application/x-qt.ui+qml')}" }
],
"pages" :
[
{
"trDisplayName": "Define Class",
"trShortTitle": "Details",
"typeId": "Fields",
"data" :
[
{
"name": "Class",
"trDisplayName": "Component name:",
"mandatory": true,
"type": "LineEdit",
"data": {
"validator": "(?:[A-Z_][a-zA-Z_0-9]*|)",
"fixup": "%{JS: '%{INPUT}'.charAt(0).toUpperCase() + '%{INPUT}'.slice(1) }"
}
},
{
"name": "Sp1",
"type": "Spacer",
"data": { "factor": 2 }
},
{
"name": "FormClass",
"trDisplayName": "Component form name:",
"mandatory": true,
"type": "LineEdit",
"data": {
"validator": "(?:[A-Z_][a-zA-Z_0-9]*|)",
"fixup": "%{JS: '%{INPUT}'.charAt(0).toUpperCase() + '%{INPUT}'.slice(1) }",
"trText": "%{Class}Form"
}
},
{
"name": "TargetPath",
"type": "PathChooser",
"trDisplayName": "Path:",
"mandatory": true,
"data":
{
"kind": "directory",
"basePath": "%{InitialPath}",
"path": "%{InitialPath}"
}
}
]
},
{
"trDisplayName": "Project Management",
"trShortTitle": "Summary",
"typeId": "Summary"
}
],
"generators" :
[
{
"typeId": "File",
"data": [
{
"source": "file.qml.tpl",
"target": "%{TargetPath}/%{QmlFile}",
"openInEditor": true
},
{
"source": "fileForm.ui.qml.tpl",
"target": "%{TargetPath}/%{UiFile}",
"openInEditor": true
}
]
}
]
}

View File

@@ -1758,12 +1758,12 @@ Cancelling pending operations...
<context> <context>
<name>Android::Internal::AndroidServiceWidget::AndroidServiceModel</name> <name>Android::Internal::AndroidServiceWidget::AndroidServiceModel</name>
<message> <message>
<source>The name of the class implementing the service</source> <source>The name of the class implementing the service.</source>
<translation>Имя класса, реализующего сервис</translation> <translation>Имя класса, реализующего сервис.</translation>
</message> </message>
<message> <message>
<source>Checked if the service is run in an external process</source> <source>Checked if the service is run in an external process.</source>
<translation>Отмечено, если сервис работает во внешнем процессе</translation> <translation>Отмечено, если сервис работает во внешнем процессе.</translation>
</message> </message>
<message> <message>
<source>The name of the external process. <source>The name of the external process.
@@ -1772,52 +1772,52 @@ Prefix with : if the process is private, use a lowercase name if the process is
Если имя начинается с двоеточия, то процесс приватный, если написано в нижнем регистре, то процесс глобальный.</translation> Если имя начинается с двоеточия, то процесс приватный, если написано в нижнем регистре, то процесс глобальный.</translation>
</message> </message>
<message> <message>
<source>Checked if the service is in a separate dynamic library</source> <source>Checked if the service is in a separate dynamic library.</source>
<translation>Отмечено, если сервис в отдельной динамической библиотеке</translation> <translation>Отмечено, если сервис в отдельной динамической библиотеке.</translation>
</message> </message>
<message> <message>
<source>The name of the separate dynamic library</source> <source>The name of the separate dynamic library.</source>
<translation>Имя отдельной динамической библиотеки</translation> <translation>Имя отдельной динамической библиотеки.</translation>
</message> </message>
<message> <message>
<source>The arguments for telling the app to run the service instead of the main activity</source> <source>The arguments for telling the app to run the service instead of the main activity.</source>
<translation>Параметры запуска сервиса вместо основной функциональности приложения</translation> <translation>Параметры запуска сервиса вместо основной функциональности приложения.</translation>
</message> </message>
<message> <message>
<source>Service class name</source> <source>Service class name.</source>
<translation>Имя класса сервиса</translation> <translation>Имя класса сервиса.</translation>
</message> </message>
<message> <message>
<source>Run in external process</source> <source>Run in external process.</source>
<translation>Работа во внешнем процессе</translation> <translation>Работа во внешнем процессе.</translation>
</message> </message>
<message> <message>
<source>Process name</source> <source>Process name.</source>
<translation>Имя процесса</translation> <translation>Имя процесса.</translation>
</message> </message>
<message> <message>
<source>Run in external library</source> <source>Run in external library.</source>
<translation>Работа во внешней библиотеке</translation> <translation>Работа во внешней библиотеке.</translation>
</message> </message>
<message> <message>
<source>Library name</source> <source>Library name.</source>
<translation>Имя библиотеки</translation> <translation>Имя библиотеки.</translation>
</message> </message>
<message> <message>
<source>Service arguments</source> <source>Service arguments.</source>
<translation>Параметры сервиса</translation> <translation>Параметры сервиса.</translation>
</message> </message>
<message> <message>
<source>The class name must be set</source> <source>The class name must be set.</source>
<translation>Должно быть задано имя класса</translation> <translation>Должно быть задано имя класса.</translation>
</message> </message>
<message> <message>
<source>The process name must be set for a service run in an external process</source> <source>The process name must be set for a service run in an external process.</source>
<translation>Имя процесса должно быть задано для сервиса, работающего во внешнем процессе</translation> <translation>Имя процесса должно быть задано для сервиса, работающего во внешнем процессе.</translation>
</message> </message>
<message> <message>
<source>The library name must be set for a service run in an external library</source> <source>The library name must be set for a service run in an external library.</source>
<translation>Имя библиотеки должно быть задано для сервиса, работающего во внешней библиотеке</translation> <translation>Имя библиотеки должно быть задано для сервиса, работающего во внешней библиотеке.</translation>
</message> </message>
<message> <message>
<source>The service arguments must be set for a service not run in an external library</source> <source>The service arguments must be set for a service not run in an external library</source>

View File

@@ -26,6 +26,7 @@ add_qtc_executable(qtcreator
extend_qtc_executable(qtcreator extend_qtc_executable(qtcreator
CONDITION APPLE CONDITION APPLE
DEPENDS ${FWFoundation}
SOURCES SOURCES
main_mac.mm main_mac.mm
) )

View File

@@ -43,6 +43,8 @@ QtcProduct {
project.sharedSourcesDir + "/qtlockedfile", project.sharedSourcesDir + "/qtlockedfile",
] ]
cpp.frameworks: base.concat(qbs.targetOS.contains("macos") ? ["Foundation"] : [])
Depends { name: "app_version_header" } Depends { name: "app_version_header" }
Depends { name: "Qt"; submodules: ["widgets", "network"] } Depends { name: "Qt"; submodules: ["widgets", "network"] }
Depends { name: "Utils" } Depends { name: "Utils" }
@@ -97,4 +99,12 @@ QtcProduct {
"../shared/qtlockedfile/qtlockedfile_win.cpp" "../shared/qtlockedfile/qtlockedfile_win.cpp"
] ]
} }
Group {
name: "main_macos"
condition: qbs.targetOS.contains("macos")
files: [
"main_mac.mm"
]
}
} }

View File

@@ -60,7 +60,7 @@ QT_END_NAMESPACE
namespace ADS { namespace ADS {
namespace Constants { namespace Constants {
const char DEFAULT_WORKSPACE[] = "Essentials"; // This needs to align with a name of the shipped presets const char DEFAULT_WORKSPACE[] = "Basic"; // This needs to align with a name of the shipped presets
const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace"; const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace";
const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace"; const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
} // namespace Constants } // namespace Constants

View File

@@ -60,7 +60,7 @@ struct ConvertArgValueToString {
std::string Arg::value() const std::string Arg::value() const
{ {
return std::visit(ConvertArgValueToString(), m_value); return Utils::visit(ConvertArgValueToString(), m_value);
} }

View File

@@ -33,9 +33,9 @@
# define NANOTRACESHARED_EXPORT Q_DECL_IMPORT # define NANOTRACESHARED_EXPORT Q_DECL_IMPORT
#endif #endif
#include <utils/variant.h> // revert when macos minimum target is >= 10.14
#include <string> #include <string>
#include <variant>
#include <vector> #include <vector>
@@ -80,7 +80,7 @@ using TimePoint = std::chrono::time_point< Clock >;
class NANOTRACESHARED_EXPORT Arg class NANOTRACESHARED_EXPORT Arg
{ {
public: public:
using SupportedType = std::variant<int, int64_t, double, std::string>; using SupportedType = Utils::variant<int, int64_t, double, std::string>;
Arg(const std::string &name, const SupportedType &val); Arg(const std::string &name, const SupportedType &val);
std::string name() const; std::string name() const;

View File

@@ -185,7 +185,7 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
void Bind::throwRecursionDepthError() void Bind::throwRecursionDepthError()
{ {
_diagnosticMessages->append(DiagnosticMessage(Severity::Error, SourceLocation(), tr("Hit maximal recursion depth in AST visit"))); _diagnosticMessages->append(DiagnosticMessage(Severity::Error, SourceLocation(), tr("Hit maximal recursion depth in AST visit.")));
} }
void Bind::accept(Node *node) void Bind::accept(Node *node)

View File

@@ -71,7 +71,7 @@ static inline QString msgInvalidConstructor(const char *what)
StaticAnalysisMessages::StaticAnalysisMessages() StaticAnalysisMessages::StaticAnalysisMessages()
{ {
// When changing a message or severity, update the documentation, currently // When changing a message or severity, update the documentation, currently
// in creator-editors.qdoc, accordingly. // in creator-code-syntax.qdoc, accordingly.
newMsg(ErrInvalidEnumValue, Error, newMsg(ErrInvalidEnumValue, Error,
tr("Invalid value for enum.")); tr("Invalid value for enum."));
newMsg(ErrEnumValueMustBeStringOrNumber, Error, newMsg(ErrEnumValueMustBeStringOrNumber, Error,
@@ -211,36 +211,36 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(ErrInvalidArrayValueLength, Error, newMsg(ErrInvalidArrayValueLength, Error,
tr("%1 elements expected in array value."), 1); tr("%1 elements expected in array value."), 1);
newMsg(WarnImperativeCodeNotEditableInVisualDesigner, Warning, newMsg(WarnImperativeCodeNotEditableInVisualDesigner, Warning,
tr("Imperative code is not supported in the Qt Quick Designer.")); tr("Imperative code is not supported in Qt Design Studio."));
newMsg(WarnUnsupportedTypeInVisualDesigner, Warning, newMsg(WarnUnsupportedTypeInVisualDesigner, Warning,
tr("This type (%1) is not supported in the Qt Quick Designer."), 1); tr("This type (%1) is not supported in Qt Design Studio."), 1);
newMsg(WarnReferenceToParentItemNotSupportedByVisualDesigner, Warning, newMsg(WarnReferenceToParentItemNotSupportedByVisualDesigner, Warning,
tr("Reference to parent item cannot be resolved correctly by the Qt Quick Designer.")); tr("Reference to parent item cannot be resolved correctly by Qt Design Studio."));
newMsg(WarnUndefinedValueForVisualDesigner, Warning, newMsg(WarnUndefinedValueForVisualDesigner, Warning,
tr("This visual property binding cannot be evaluated in the local context " tr("This visual property binding cannot be evaluated in the local context "
"and might not show up in Qt Quick Designer as expected.")); "and might not show up in Qt Design Studio as expected."));
newMsg(WarnStatesOnlyInRootItemForVisualDesigner, Warning, newMsg(WarnStatesOnlyInRootItemForVisualDesigner, Warning,
tr("Qt Quick Designer only supports states in the root item.")); tr("Qt Design Studio only supports states in the root item."));
newMsg(ErrInvalidIdeInVisualDesigner, Error, newMsg(ErrInvalidIdeInVisualDesigner, Error,
tr("This id might be ambiguous and is not supported in the Qt Quick Designer.")); tr("This id might be ambiguous and is not supported in Qt Design Studio."));
newMsg(ErrUnsupportedRootTypeInVisualDesigner, Error, newMsg(ErrUnsupportedRootTypeInVisualDesigner, Error,
tr("This type (%1) is not supported as a root element by Qt Quick Designer."), 1); tr("This type (%1) is not supported as a root element by Qt Design Studio."), 1);
newMsg(ErrUnsupportedRootTypeInQmlUi, Error, newMsg(ErrUnsupportedRootTypeInQmlUi, Error,
tr("This type (%1) is not supported as a root element of a Qt Quick UI form."), 1); tr("This type (%1) is not supported as a root element of a UI file (.ui.qml)."), 1);
newMsg(ErrUnsupportedTypeInQmlUi, Error, newMsg(ErrUnsupportedTypeInQmlUi, Error,
tr("This type (%1) is not supported in a Qt Quick UI form."), 1); tr("This type (%1) is not supported in a UI file (.ui.qml)."), 1);
newMsg(ErrFunctionsNotSupportedInQmlUi, Error, newMsg(ErrFunctionsNotSupportedInQmlUi, Error,
tr("Functions are not supported in a Qt Quick UI form.")); tr("Functions are not supported in a UI file (.ui.qml)."));
newMsg(ErrBlocksNotSupportedInQmlUi, Error, newMsg(ErrBlocksNotSupportedInQmlUi, Error,
tr("JavaScript blocks are not supported in a Qt Quick UI form.")); tr("JavaScript blocks are not supported in a UI file (.ui.qml)."));
newMsg(ErrBehavioursNotSupportedInQmlUi, Error, newMsg(ErrBehavioursNotSupportedInQmlUi, Error,
tr("Behavior type is not supported in a Qt Quick UI form.")); tr("Behavior type is not supported in a UI file (.ui.qml)."));
newMsg(ErrStatesOnlyInRootItemInQmlUi, Error, newMsg(ErrStatesOnlyInRootItemInQmlUi, Error,
tr("States are only supported in the root item in a Qt Quick UI form.")); tr("States are only supported in the root item in a UI file (.ui.qml)."));
newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error, newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error,
tr("Referencing the parent of the root item is not supported in a Qt Quick UI form.")); tr("Referencing the parent of the root item is not supported in a UI file (.ui.qml)."));
newMsg(ErrDoNotMixTranslationFunctionsInQmlUi, Error, newMsg(ErrDoNotMixTranslationFunctionsInQmlUi, Error,
tr("Do not mix translation functions in a Qt Quick UI form.")); tr("Do not mix translation functions in a UI file (.ui.qml)."));
newMsg(StateCannotHaveChildItem, Error, newMsg(StateCannotHaveChildItem, Error,
tr("A State cannot have a child item (%1)."), 1); tr("A State cannot have a child item (%1)."), 1);
newMsg(WarnDuplicateImport, Warning, newMsg(WarnDuplicateImport, Warning,
@@ -250,7 +250,7 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(ErrTypeIsInstantiatedRecursively, Error, newMsg(ErrTypeIsInstantiatedRecursively, Error,
tr("Type cannot be instantiated recursively (%1)."), 1); tr("Type cannot be instantiated recursively (%1)."), 1);
newMsg(WarnLogicalValueDoesNotDependOnValues, Warning, newMsg(WarnLogicalValueDoesNotDependOnValues, Warning,
tr("Logical value does not depend on actual values")); tr("Logical value does not depend on actual values."));
newMsg(ErrToManyComponentChildren, Error, newMsg(ErrToManyComponentChildren, Error,
tr("Components are only allowed to have a single child element.")); tr("Components are only allowed to have a single child element."));
newMsg(WarnComponentRequiresChildren, Warning, newMsg(WarnComponentRequiresChildren, Warning,

View File

@@ -34,6 +34,7 @@ add_qtc_library(Utils
differ.cpp differ.h differ.cpp differ.h
displayname.cpp displayname.h displayname.cpp displayname.h
dropsupport.cpp dropsupport.h dropsupport.cpp dropsupport.h
dynamiclicensecheck.h
elfreader.cpp elfreader.h elfreader.cpp elfreader.h
elidinglabel.cpp elidinglabel.h elidinglabel.cpp elidinglabel.h
environment.cpp environment.h environment.cpp environment.h

View File

@@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2022 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 <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
#include <extensionsystem/iplugin.h>
#include <utils/predicates.h>
#include <utils/algorithm.h>
#include <QMetaObject>
namespace Utils {
enum FoundLicense {
community,
professional,
enterprise
};
FoundLicense checkLicense() {
const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(
ExtensionSystem::PluginManager::plugins(),
Utils::equal(&ExtensionSystem::PluginSpec::name, QString("LicenseChecker")));
if (!pluginSpec)
return community;
ExtensionSystem::IPlugin *plugin = pluginSpec->plugin();
if (!plugin)
return community;
bool retVal = false;
bool success = QMetaObject::invokeMethod(plugin,
"qdsEnterpriseLicense",
Qt::DirectConnection,
Q_RETURN_ARG(bool, retVal));
if (success && retVal)
return enterprise;
return professional;
}
} // namespace Utils

View File

@@ -889,7 +889,7 @@ void LauncherSocket::handleSocketDisconnected()
{ {
QTC_ASSERT(isCalledFromLaunchersThread(), return); QTC_ASSERT(isCalledFromLaunchersThread(), return);
handleError(QCoreApplication::translate("Utils::LauncherSocket", handleError(QCoreApplication::translate("Utils::LauncherSocket",
"Launcher socket closed unexpectedly")); "Launcher socket closed unexpectedly."));
} }
void LauncherSocket::handleError(const QString &error) void LauncherSocket::handleError(const QString &error)

View File

@@ -106,29 +106,36 @@ LayoutBuilder::LayoutItem::LayoutItem(const QString &text)
: text(text) : text(text)
{} {}
static QLayout *createLayoutFromType(LayoutBuilder::LayoutType layoutType) QLayout *LayoutBuilder::createLayout() const
{ {
switch (layoutType) { QLayout *layout = nullptr;
switch (m_layoutType) {
case LayoutBuilder::FormLayout: { case LayoutBuilder::FormLayout: {
auto formLayout = new QFormLayout; auto formLayout = new QFormLayout;
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
return formLayout; layout = formLayout;
break;
} }
case LayoutBuilder::GridLayout: { case LayoutBuilder::GridLayout: {
auto gridLayout = new QGridLayout; auto gridLayout = new QGridLayout;
return gridLayout; layout = gridLayout;
break;
} }
case LayoutBuilder::HBoxLayout: { case LayoutBuilder::HBoxLayout: {
auto hboxLayout = new QHBoxLayout; auto hboxLayout = new QHBoxLayout;
return hboxLayout; layout = hboxLayout;
break;
} }
case LayoutBuilder::VBoxLayout: { case LayoutBuilder::VBoxLayout: {
auto vboxLayout = new QVBoxLayout; auto vboxLayout = new QVBoxLayout;
return vboxLayout; layout = vboxLayout;
break;
} }
} }
QTC_CHECK(false); QTC_ASSERT(layout, return nullptr);
return nullptr; if (m_spacing)
layout->setSpacing(*m_spacing);
return layout;
} }
static void setMargins(bool on, QLayout *layout) static void setMargins(bool on, QLayout *layout)
@@ -246,7 +253,7 @@ static void doLayoutHelper(QLayout *layout,
*/ */
LayoutBuilder::LayoutItem::LayoutItem(const LayoutBuilder &builder) LayoutBuilder::LayoutItem::LayoutItem(const LayoutBuilder &builder)
{ {
layout = createLayoutFromType(builder.m_layoutType); layout = builder.createLayout();
doLayoutHelper(layout, builder.m_items); doLayoutHelper(layout, builder.m_items);
setMargins(builder.m_withMargins, layout); setMargins(builder.m_withMargins, layout);
} }
@@ -287,6 +294,12 @@ LayoutBuilder::LayoutBuilder(LayoutType layoutType, const LayoutItems &items)
addItem(item); addItem(item);
} }
LayoutBuilder &LayoutBuilder::setSpacing(int spacing)
{
m_spacing = spacing;
return *this;
}
LayoutBuilder::LayoutBuilder() = default; LayoutBuilder::LayoutBuilder() = default;
/*! /*!
@@ -343,7 +356,7 @@ LayoutBuilder &LayoutBuilder::addItem(const LayoutItem &item)
void LayoutBuilder::doLayout(QWidget *parent) void LayoutBuilder::doLayout(QWidget *parent)
{ {
QLayout *layout = createLayoutFromType(m_layoutType); QLayout *layout = createLayout();
parent->setLayout(layout); parent->setLayout(layout);
doLayoutHelper(layout, m_items); doLayoutHelper(layout, m_items);

View File

@@ -27,6 +27,8 @@
#include "utils_global.h" #include "utils_global.h"
#include "optional.h"
#include <QList> #include <QList>
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
@@ -97,6 +99,8 @@ public:
~LayoutBuilder(); ~LayoutBuilder();
LayoutBuilder &setSpacing(int spacing);
LayoutBuilder &addItem(const LayoutItem &item); LayoutBuilder &addItem(const LayoutItem &item);
LayoutBuilder &addItems(const LayoutItems &items); LayoutBuilder &addItems(const LayoutItems &items);
@@ -148,10 +152,12 @@ public:
protected: protected:
explicit LayoutBuilder(); // Adds to existing layout. explicit LayoutBuilder(); // Adds to existing layout.
QLayout *createLayout() const;
void doLayout(QWidget *parent); void doLayout(QWidget *parent);
LayoutItems m_items; LayoutItems m_items;
LayoutType m_layoutType; LayoutType m_layoutType;
Utils::optional<int> m_spacing;
bool m_withMargins = false; bool m_withMargins = false;
}; };

View File

@@ -980,12 +980,12 @@ static bool askToKill(const QString &command)
#ifdef QT_GUI_LIB #ifdef QT_GUI_LIB
if (QThread::currentThread() != QCoreApplication::instance()->thread()) if (QThread::currentThread() != QCoreApplication::instance()->thread())
return true; return true;
const QString title = QtcProcess::tr("Process not Responding"); const QString title = QtcProcess::tr("Process Not Responding");
QString msg = command.isEmpty() ? QString msg = command.isEmpty() ?
QtcProcess::tr("The process is not responding.") : QtcProcess::tr("The process is not responding.") :
QtcProcess::tr("The process \"%1\" is not responding.").arg(command); QtcProcess::tr("The process \"%1\" is not responding.").arg(command);
msg += ' '; msg += ' ';
msg += QtcProcess::tr("Would you like to terminate it?"); msg += QtcProcess::tr("Terminate the process?");
// Restore the cursor that is set to wait while running. // Restore the cursor that is set to wait while running.
const bool hasOverrideCursor = QApplication::overrideCursor() != nullptr; const bool hasOverrideCursor = QApplication::overrideCursor() != nullptr;
if (hasOverrideCursor) if (hasOverrideCursor)

View File

@@ -13,6 +13,8 @@ Project {
var libs = []; var libs = [];
if (qbs.targetOS.contains("windows")) { if (qbs.targetOS.contains("windows")) {
libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32"); libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32");
if (qbs.toolchainType === "mingw")
libs.push("uuid");
} else if (qbs.targetOS.contains("unix")) { } else if (qbs.targetOS.contains("unix")) {
if (!qbs.targetOS.contains("macos")) if (!qbs.targetOS.contains("macos"))
libs.push("X11"); libs.push("X11");

View File

@@ -164,14 +164,15 @@ bool AndroidDeployQtStep::init()
if (selectedAbis.isEmpty()) if (selectedAbis.isEmpty())
selectedAbis.append(bs->extraData(buildKey, Constants::AndroidAbi).toString()); selectedAbis.append(bs->extraData(buildKey, Constants::AndroidAbi).toString());
// TODO: use AndroidDevice directly instead of AndroidDeviceInfo.
if (!info.isValid()) { if (!info.isValid()) {
const IDevice *dev = DeviceKitAspect::device(kit()).data(); const auto dev =
static_cast<const AndroidDevice *>(DeviceKitAspect::device(kit()).data());
if (!dev) { if (!dev) {
reportWarningOrError(tr("No valid deployment device is set."), Task::Error); reportWarningOrError(tr("No valid deployment device is set."), Task::Error);
return false; return false;
} }
// TODO: use AndroidDevice directly instead of AndroidDeviceInfo.
info = AndroidDevice::androidDeviceInfoFromIDevice(dev); info = AndroidDevice::androidDeviceInfoFromIDevice(dev);
m_deviceInfo = info; // Keep around for later steps m_deviceInfo = info; // Keep around for later steps
@@ -181,18 +182,17 @@ bool AndroidDeployQtStep::init()
return false; return false;
} }
const AndroidDevice *androidDev = static_cast<const AndroidDevice *>(dev); if (!dev->canSupportAbis(selectedAbis)) {
if (androidDev && !androidDev->canSupportAbis(selectedAbis)) {
const QString error = tr("The deployment device \"%1\" does not support the " const QString error = tr("The deployment device \"%1\" does not support the "
"architectures used by the kit.\n" "architectures used by the kit.\n"
"The kit supports \"%2\", but the device uses \"%3\".") "The kit supports \"%2\", but the device uses \"%3\".")
.arg(dev->displayName()).arg(selectedAbis.join(", ")) .arg(dev->displayName()).arg(selectedAbis.join(", "))
.arg(androidDev->supportedAbis().join(", ")); .arg(dev->supportedAbis().join(", "));
reportWarningOrError(error, Task::Error); reportWarningOrError(error, Task::Error);
return false; return false;
} }
if (androidDev && !androidDev->canHandleDeployments()) { if (!dev->canHandleDeployments()) {
reportWarningOrError(tr("The deployment device \"%1\" is disconnected.") reportWarningOrError(tr("The deployment device \"%1\" is disconnected.")
.arg(dev->displayName()), Task::Error); .arg(dev->displayName()), Task::Error);
return false; return false;

View File

@@ -204,31 +204,31 @@ QVariant AndroidServiceWidget::AndroidServiceModel::headerData(int section, Qt::
{ {
if (role == Qt::ToolTipRole && orientation == Qt::Horizontal) { if (role == Qt::ToolTipRole && orientation == Qt::Horizontal) {
if (section == 0) if (section == 0)
return tr("The name of the class implementing the service"); return tr("The name of the class implementing the service.");
else if (section == 1) else if (section == 1)
return tr("Checked if the service is run in an external process"); return tr("Checked if the service is run in an external process.");
else if (section == 2) else if (section == 2)
return tr("The name of the external process.\n" return tr("The name of the external process.\n"
"Prefix with : if the process is private, use a lowercase name if the process is global."); "Prefix with : if the process is private, use a lowercase name if the process is global.");
else if (section == 3) else if (section == 3)
return tr("Checked if the service is in a separate dynamic library"); return tr("Checked if the service is in a separate dynamic library.");
else if (section == 4) else if (section == 4)
return tr("The name of the separate dynamic library"); return tr("The name of the separate dynamic library.");
else if (section == 5) else if (section == 5)
return tr("The arguments for telling the app to run the service instead of the main activity"); return tr("The arguments for telling the app to run the service instead of the main activity.");
} else if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { } else if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
if (section == 0) if (section == 0)
return tr("Service class name"); return tr("Service class name.");
else if (section == 1) else if (section == 1)
return tr("Run in external process"); return tr("Run in external process.");
else if (section == 2) else if (section == 2)
return tr("Process name"); return tr("Process name.");
else if (section == 3) else if (section == 3)
return tr("Run in external library"); return tr("Run in external library.");
else if (section == 4) else if (section == 4)
return tr("Library name"); return tr("Library name.");
else if (section == 5) else if (section == 5)
return tr("Service arguments"); return tr("Service arguments.");
} }
return {}; return {};
} }
@@ -247,22 +247,22 @@ QVariant AndroidServiceWidget::AndroidServiceModel::data(const QModelIndex &inde
if (index.column() == 0) if (index.column() == 0)
return m_services[index.row()].className(); return m_services[index.row()].className();
else if (index.column() == 1) else if (index.column() == 1)
return tr("Run in external process"); return tr("Run in external process.");
else if (index.column() == 2) else if (index.column() == 2)
return m_services[index.row()].externalProcessName(); return m_services[index.row()].externalProcessName();
else if (index.column() == 3) else if (index.column() == 3)
return tr("Run in external library"); return tr("Run in external library.");
else if (index.column() == 4) else if (index.column() == 4)
return m_services[index.row()].externalLibraryName(); return m_services[index.row()].externalLibraryName();
else if (index.column() == 5) else if (index.column() == 5)
return m_services[index.row()].serviceArguments(); return m_services[index.row()].serviceArguments();
} else if (role == Qt::ToolTipRole) { } else if (role == Qt::ToolTipRole) {
if (index.column() == 0 && m_services[index.row()].className().isEmpty()) if (index.column() == 0 && m_services[index.row()].className().isEmpty())
return tr("The class name must be set"); return tr("The class name must be set.");
else if (index.column() == 2 && m_services[index.row()].isRunInExternalProcess()) else if (index.column() == 2 && m_services[index.row()].isRunInExternalProcess())
return tr("The process name must be set for a service run in an external process"); return tr("The process name must be set for a service run in an external process.");
else if (index.column() == 4 && m_services[index.row()].isRunInExternalLibrary()) else if (index.column() == 4 && m_services[index.row()].isRunInExternalLibrary())
return tr("The library name must be set for a service run in an external library"); return tr("The library name must be set for a service run in an external library.");
} else if (role == Qt::EditRole) { } else if (role == Qt::EditRole) {
if (index.column() == 0) if (index.column() == 0)
return m_services[index.row()].className(); return m_services[index.row()].className();

View File

@@ -65,7 +65,7 @@
<item> <item>
<widget class="QPushButton" name="makeDefaultNdkButton"> <widget class="QPushButton" name="makeDefaultNdkButton">
<property name="toolTip"> <property name="toolTip">
<string>Force a specific NDK installation to be used by all Android kits.&lt;br/&gt;Note that the forced NDK might not be compatible with all Qt registered versions.</string> <string>Force a specific NDK installation to be used by all Android kits.&lt;br/&gt;Note that the forced NDK might not be compatible with all registered Qt versions.</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@@ -1402,7 +1402,10 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
setClientCapabilities(caps); setClientCapabilities(caps);
setLocatorsEnabled(false); setLocatorsEnabled(false);
setAutoRequestCodeActions(false); // clangd sends code actions inside diagnostics setAutoRequestCodeActions(false); // clangd sends code actions inside diagnostics
setProgressTitleForToken(indexingToken(), tr("Parsing C/C++ Files (clangd)")); if (project) {
setProgressTitleForToken(indexingToken(),
tr("Indexing %1 with clangd").arg(project->displayName()));
}
setCurrentProject(project); setCurrentProject(project);
setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold); setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold);
@@ -2958,9 +2961,10 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
int version, bool force) int version, bool force)
{ {
SubtaskTimer t(highlightingTimer); SubtaskTimer t(highlightingTimer);
qCDebug(clangdLog) << "handling LSP tokens" << doc->filePath() << tokens.size(); qCInfo(clangdLogHighlight) << "handling LSP tokens" << doc->filePath()
<< version << tokens.size();
if (version != q->documentVersion(doc->filePath())) { if (version != q->documentVersion(doc->filePath())) {
qCDebug(clangdLogHighlight) << "LSP tokens outdated; aborting highlighting procedure" qCInfo(clangdLogHighlight) << "LSP tokens outdated; aborting highlighting procedure"
<< version << q->documentVersion(doc->filePath()); << version << q->documentVersion(doc->filePath());
return; return;
} }
@@ -2968,7 +2972,7 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
const auto previous = previousTokens.find(doc); const auto previous = previousTokens.find(doc);
if (previous != previousTokens.end()) { if (previous != previousTokens.end()) {
if (!force && previous->first == tokens && previous->second == version) { if (!force && previous->first == tokens && previous->second == version) {
qCDebug(clangdLogHighlight) << "tokens and version same as last time; nothing to do"; qCInfo(clangdLogHighlight) << "tokens and version same as last time; nothing to do";
return; return;
} }
previous->first = tokens; previous->first = tokens;
@@ -2985,7 +2989,7 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
if (!q->documentOpen(doc)) if (!q->documentOpen(doc))
return; return;
if (version != q->documentVersion(doc->filePath())) { if (version != q->documentVersion(doc->filePath())) {
qCDebug(clangdLogHighlight) << "AST not up to date; aborting highlighting procedure" qCInfo(clangdLogHighlight) << "AST not up to date; aborting highlighting procedure"
<< version << q->documentVersion(doc->filePath()); << version << q->documentVersion(doc->filePath());
return; return;
} }

View File

@@ -44,6 +44,7 @@
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <cppeditor/cppcodemodelsettings.h> #include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cppfollowsymbolundercursor.h> #include <cppeditor/cppfollowsymbolundercursor.h>
#include <cppeditor/cppmodelmanager.h> #include <cppeditor/cppmodelmanager.h>
#include <cppeditor/cppprojectfile.h> #include <cppeditor/cppprojectfile.h>
@@ -58,6 +59,7 @@
#include <projectexplorer/buildsystem.h> #include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h> #include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -85,21 +87,20 @@ static CppEditor::CppModelManager *cppModelManager()
return CppEditor::CppModelManager::instance(); return CppEditor::CppModelManager::instance();
} }
static const QList<TextEditor::BaseTextEditor *> allCppEditors() static ProjectExplorer::Project *fallbackProject()
{ {
QList<TextEditor::BaseTextEditor *> cppEditors; if (ProjectExplorer::Project * const p = ProjectExplorer::ProjectTree::currentProject())
for (const Core::DocumentModel::Entry * const entry : Core::DocumentModel::entries()) { return p;
const auto textDocument = qobject_cast<TextEditor::TextDocument *>(entry->document); return ProjectExplorer::SessionManager::startupProject();
if (!textDocument)
continue;
if (const auto cppEditor = qobject_cast<TextEditor::BaseTextEditor *>(Utils::findOrDefault(
Core::DocumentModel::editorsForDocument(textDocument), [](Core::IEditor *editor) {
return CppEditor::CppModelManager::isCppEditor(editor);
}))) {
cppEditors << cppEditor;
} }
}
return cppEditors; static const QList<TextEditor::TextDocument *> allCppDocuments()
{
const auto isCppDocument = Utils::equal(&Core::IDocument::id,
Utils::Id(CppEditor::Constants::CPPEDITOR_ID));
const QList<Core::IDocument *> documents
= Utils::filtered(Core::DocumentModel::openedDocuments(), isCppDocument);
return Utils::qobject_container_cast<TextEditor::TextDocument *>(documents);
} }
ClangModelManagerSupport::ClangModelManagerSupport() ClangModelManagerSupport::ClangModelManagerSupport()
@@ -149,10 +150,7 @@ ClangModelManagerSupport::ClangModelManagerSupport()
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject, connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
this, &ClangModelManagerSupport::onAboutToRemoveProject); this, &ClangModelManagerSupport::onAboutToRemoveProject);
connect(sessionManager, &ProjectExplorer::SessionManager::projectRemoved, connect(sessionManager, &ProjectExplorer::SessionManager::projectRemoved,
this, [this] { this, [this] { claimNonProjectSources(clientForProject(fallbackProject())); });
if (ClangdClient * const fallbackClient = clientForProject(nullptr))
claimNonProjectSources(fallbackClient);
});
CppEditor::ClangdSettings::setDefaultClangdPath(Core::ICore::clangdExecutable(CLANG_BINDIR)); CppEditor::ClangdSettings::setDefaultClangdPath(Core::ICore::clangdExecutable(CLANG_BINDIR));
connect(&CppEditor::ClangdSettings::instance(), &CppEditor::ClangdSettings::changed, connect(&CppEditor::ClangdSettings::instance(), &CppEditor::ClangdSettings::changed,
@@ -369,14 +367,16 @@ void ClangModelManagerSupport::updateLanguageClient(
// Acquaint the client with all open C++ documents for this project. // Acquaint the client with all open C++ documents for this project.
bool hasDocuments = false; bool hasDocuments = false;
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) { for (TextEditor::TextDocument * const doc : allCppDocuments()) {
const Utils::FilePath filePath = editor->textDocument()->filePath(); const Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (!project->isKnownFile(filePath)) if (!currentClient || !currentClient->project()
continue; || currentClient->state() != Client::Initialized
LanguageClientManager::openDocumentWithClient(editor->textDocument(), client); || project->isKnownFile(doc->filePath())) {
ClangEditorDocumentProcessor::clearTextMarks(filePath); LanguageClientManager::openDocumentWithClient(doc, client);
ClangEditorDocumentProcessor::clearTextMarks(doc->filePath());
hasDocuments = true; hasDocuments = true;
} }
}
if (client->state() == Client::Initialized) if (client->state() == Client::Initialized)
updateParserConfig(); updateParserConfig();
@@ -444,7 +444,7 @@ ClangdClient *ClangModelManagerSupport::clientForProject(
ClangdClient *ClangModelManagerSupport::clientForFile(const Utils::FilePath &file) const ClangdClient *ClangModelManagerSupport::clientForFile(const Utils::FilePath &file) const
{ {
return clientForProject(ProjectExplorer::SessionManager::projectForFile(file)); return qobject_cast<ClangdClient *>(LanguageClientManager::clientForFilePath(file));
} }
ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *project, ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *project,
@@ -455,15 +455,18 @@ ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *p
return client; return client;
} }
void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *fallbackClient) void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
{ {
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) { if (!client)
if (ProjectExplorer::SessionManager::projectForFile(editor->textDocument()->filePath())) return;
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
if (Client * const currentClient = LanguageClientManager::clientForDocument(doc);
currentClient && currentClient->state() == Client::Initialized
&& (currentClient == client || currentClient->project())) {
continue; continue;
if (!fallbackClient->documentOpen(editor->textDocument())) {
ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath());
fallbackClient->openDocument(editor->textDocument());
} }
ClangEditorDocumentProcessor::clearTextMarks(doc->filePath());
client->openDocument(doc);
} }
} }
@@ -563,8 +566,10 @@ void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
// TODO: Ensure that not fully loaded documents are updated? // TODO: Ensure that not fully loaded documents are updated?
ProjectExplorer::Project * const project ProjectExplorer::Project * project
= ProjectExplorer::SessionManager::projectForFile(document->filePath()); = ProjectExplorer::SessionManager::projectForFile(document->filePath());
if (!project)
project = fallbackProject();
if (ClangdClient * const client = clientForProject(project)) if (ClangdClient * const client = clientForProject(project))
LanguageClientManager::openDocumentWithClient(textDocument, client); LanguageClientManager::openDocumentWithClient(textDocument, client);
} }

View File

@@ -134,7 +134,7 @@ private:
void updateLanguageClient(ProjectExplorer::Project *project, void updateLanguageClient(ProjectExplorer::Project *project,
const CppEditor::ProjectInfo::ConstPtr &projectInfo); const CppEditor::ProjectInfo::ConstPtr &projectInfo);
ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir); ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir);
void claimNonProjectSources(ClangdClient *fallbackClient); void claimNonProjectSources(ClangdClient *client);
void watchForExternalChanges(); void watchForExternalChanges();
void watchForInternalChanges(); void watchForInternalChanges();

View File

@@ -35,10 +35,12 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cpptoolsreuse.h> #include <cppeditor/cpptoolsreuse.h>
#include <cppeditor/cpptoolstestcase.h> #include <cppeditor/cpptoolstestcase.h>
#include <cppeditor/modelmanagertesthelper.h> #include <cppeditor/modelmanagertesthelper.h>
#include <cppeditor/projectinfo.h> #include <cppeditor/projectinfo.h>
#include <languageclient/languageclientmanager.h>
#include <texteditor/codeassist/assistproposalitem.h> #include <texteditor/codeassist/assistproposalitem.h>
#include <texteditor/codeassist/genericproposalmodel.h> #include <texteditor/codeassist/genericproposalmodel.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
@@ -514,6 +516,13 @@ namespace ClangCodeModel {
namespace Internal { namespace Internal {
namespace Tests { namespace Tests {
void ClangCodeCompletionTest::initTestCase()
{
CppEditor::ClangdSettings::setUseClangd(false);
for (LanguageClient::Client * const c : LanguageClient::LanguageClientManager::clients())
LanguageClient::LanguageClientManager::shutdownClient(c);
}
void ClangCodeCompletionTest::testCompleteDoxygenKeywords() void ClangCodeCompletionTest::testCompleteDoxygenKeywords()
{ {
ProjectLessCompletionTest t("doxygenKeywordsCompletion.cpp"); ProjectLessCompletionTest t("doxygenKeywordsCompletion.cpp");

View File

@@ -38,6 +38,8 @@ class ClangCodeCompletionTest : public QObject
Q_OBJECT Q_OBJECT
private slots: private slots:
void initTestCase();
void testCompleteDoxygenKeywords(); void testCompleteDoxygenKeywords();
void testCompletePreprocessorKeywords(); void testCompletePreprocessorKeywords();
void testCompleteIncludeDirective(); void testCompleteIncludeDirective();

View File

@@ -2036,7 +2036,7 @@ void ClangdTestExternalChanges::test()
QVERIFY(waitForSignalOrTimeout(ClangModelManagerSupport::instance(), QVERIFY(waitForSignalOrTimeout(ClangModelManagerSupport::instance(),
&ClangModelManagerSupport::createdClient, timeOutInMs())); &ClangModelManagerSupport::createdClient, timeOutInMs()));
ClangdClient * const newClient = ClangModelManagerSupport::instance() ClangdClient * const newClient = ClangModelManagerSupport::instance()
->clientForFile(filePath("main.cpp")); ->clientForProject(project());
QVERIFY(newClient); QVERIFY(newClient);
QVERIFY(newClient != oldClient); QVERIFY(newClient != oldClient);
newClient->enableTesting(); newClient->enableTesting();

View File

@@ -303,7 +303,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_resetButton->setEnabled(false); m_resetButton->setEnabled(false);
m_batchEditButton = new QPushButton(tr("Batch Edit...")); m_batchEditButton = new QPushButton(tr("Batch Edit..."));
m_batchEditButton->setToolTip(tr("Set or reset multiple values in the CMake Configuration.")); m_batchEditButton->setToolTip(tr("Set or reset multiple values in the CMake configuration."));
m_showAdvancedCheckBox = new QCheckBox(tr("Advanced")); m_showAdvancedCheckBox = new QCheckBox(tr("Advanced"));
@@ -339,8 +339,9 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
qmlDebugAspect qmlDebugAspect
}, },
m_warningMessageLabel, m_warningMessageLabel,
Space(10), m_kitConfiguration,
Row{m_kitConfiguration, m_configurationStates}, Column {
m_configurationStates,
Group { Group {
cmakeConfiguration, cmakeConfiguration,
Row { Row {
@@ -349,6 +350,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
}, },
m_reconfigureButton, m_reconfigureButton,
} }
}.setSpacing(0)
}.attachTo(details, false); }.attachTo(details, false);
updateAdvancedCheckBox(); updateAdvancedCheckBox();

View File

@@ -326,7 +326,7 @@ QSet<Id> CMakeKitAspect::availableFeatures(const Kit *k) const
QString CMakeKitAspect::msgUnsupportedVersion(const QByteArray &versionString) QString CMakeKitAspect::msgUnsupportedVersion(const QByteArray &versionString)
{ {
return tr("CMake version %1 is unsupported. Please update to " return tr("CMake version %1 is unsupported. Update to "
"version 3.14 (with file-api) or later.") "version 3.14 (with file-api) or later.")
.arg(QString::fromUtf8(versionString)); .arg(QString::fromUtf8(versionString));
} }

View File

@@ -283,7 +283,7 @@ QObject *CorePlugin::remoteCommand(const QStringList & /* options */,
}); });
return nullptr; return nullptr;
} }
const FilePaths filePaths = Utils::transform(args, FilePath::fromString); const FilePaths filePaths = Utils::transform(args, FilePath::fromUserInput);
IDocument *res = MainWindow::openFiles( IDocument *res = MainWindow::openFiles(
filePaths, filePaths,
ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineAndColumnNumbers | ICore::SwitchSplitIfAlreadyVisible), ICore::OpenFilesFlags(ICore::SwitchMode | ICore::CanContainLineAndColumnNumbers | ICore::SwitchSplitIfAlreadyVisible),

View File

@@ -83,13 +83,16 @@ protected:
void setSettings(Utils::AspectContainer *settings); void setSettings(Utils::AspectContainer *settings);
void setLayouter(const std::function<void(QWidget *w)> &layouter); void setLayouter(const std::function<void(QWidget *w)> &layouter);
// Used in FontSettingsPage. FIXME?
QPointer<QWidget> m_widget; // Used in conjunction with m_widgetCreator
private:
Utils::Id m_id; Utils::Id m_id;
Utils::Id m_category; Utils::Id m_category;
QString m_displayName; QString m_displayName;
QString m_displayCategory; QString m_displayCategory;
Utils::Icon m_categoryIcon; Utils::Icon m_categoryIcon;
WidgetCreator m_widgetCreator; WidgetCreator m_widgetCreator;
QPointer<QWidget> m_widget; // Used in conjunction with m_widgetCreator
mutable bool m_keywordsInitialized = false; mutable bool m_keywordsInitialized = false;
mutable QStringList m_keywords; mutable QStringList m_keywords;

View File

@@ -199,6 +199,7 @@ public:
IDocument *m_blockedIDocument = nullptr; IDocument *m_blockedIDocument = nullptr;
QAction *m_saveAllAction; QAction *m_saveAllAction;
QString fileDialogFilterOverride;
}; };
static DocumentManager *m_instance; static DocumentManager *m_instance;
@@ -770,6 +771,16 @@ bool DocumentManager::saveDocument(IDocument *document,
return ret; return ret;
} }
QString DocumentManager::fileDialogFilter(QString *selectedFilter)
{
if (!d->fileDialogFilterOverride.isEmpty()) {
if (selectedFilter)
*selectedFilter = d->fileDialogFilterOverride.split(";;").first();
return d->fileDialogFilterOverride;
}
return allDocumentFactoryFiltersString(selectedFilter);
}
QString DocumentManager::allDocumentFactoryFiltersString(QString *allFilesFilter = nullptr) QString DocumentManager::allDocumentFactoryFiltersString(QString *allFilesFilter = nullptr)
{ {
QSet<QString> uniqueFilters; QSet<QString> uniqueFilters;
@@ -1531,6 +1542,11 @@ void DocumentManager::notifyFilesChangedInternally(const FilePaths &filePaths)
emit m_instance->filesChangedInternally(filePaths); emit m_instance->filesChangedInternally(filePaths);
} }
void DocumentManager::setFileDialogFilter(const QString &filter)
{
d->fileDialogFilterOverride = filter;
}
void DocumentManager::registerSaveAllAction() void DocumentManager::registerSaveAllAction()
{ {
d->registerSaveAllAction(); d->registerSaveAllAction();

View File

@@ -142,6 +142,10 @@ public:
lead to any editors to reload or any other editor manager actions. */ lead to any editors to reload or any other editor manager actions. */
static void notifyFilesChangedInternally(const Utils::FilePaths &filePaths); static void notifyFilesChangedInternally(const Utils::FilePaths &filePaths);
static void setFileDialogFilter(const QString &filter);
static QString fileDialogFilter(QString *selectedFilter = nullptr);
signals: signals:
/* Used to notify e.g. the code model to update the given files. Does *not* /* Used to notify e.g. the code model to update the given files. Does *not*
lead to any editors to reload or any other editor manager actions. */ lead to any editors to reload or any other editor manager actions. */

View File

@@ -3231,7 +3231,7 @@ void EditorManager::addCloseEditorListener(const std::function<bool (IEditor *)>
FilePaths EditorManager::getOpenFilePaths() FilePaths EditorManager::getOpenFilePaths()
{ {
QString selectedFilter; QString selectedFilter;
const QString &fileFilters = DocumentManager::allDocumentFactoryFiltersString(&selectedFilter); const QString &fileFilters = DocumentManager::fileDialogFilter(&selectedFilter);
return DocumentManager::getOpenFileNames(fileFilters, {}, &selectedFilter); return DocumentManager::getOpenFileNames(fileFilters, {}, &selectedFilter);
} }

View File

@@ -425,7 +425,7 @@ LoggingViewManagerWidget::LoggingViewManagerWidget(QWidget *parent)
buttonsLayout->addWidget(stop); buttonsLayout->addWidget(stop);
auto qtInternal = new QToolButton; auto qtInternal = new QToolButton;
qtInternal->setIcon(Core::Icons::QTLOGO.icon()); qtInternal->setIcon(Core::Icons::QTLOGO.icon());
qtInternal->setToolTip(tr("Toggle logging of Qt internal loggings")); qtInternal->setToolTip(tr("Toggle Qt Internal Logging"));
qtInternal->setCheckable(true); qtInternal->setCheckable(true);
qtInternal->setChecked(false); qtInternal->setChecked(false);
buttonsLayout->addWidget(qtInternal); buttonsLayout->addWidget(qtInternal);
@@ -616,7 +616,7 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
if (enabled) if (enabled)
m_manager->setEnabled(false); m_manager->setEnabled(false);
const Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(), const Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(),
tr("Save logs as")); tr("Save Logs As"));
if (fp.isEmpty()) if (fp.isEmpty())
return; return;
const bool useTS = m_timestamps->isChecked(); const bool useTS = m_timestamps->isChecked();
@@ -628,7 +628,7 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
if (res == -1) { if (res == -1) {
QMessageBox::critical( QMessageBox::critical(
ICore::dialogParent(), tr("Error"), ICore::dialogParent(), tr("Error"),
tr("Failed to write logs to '%1'.").arg(fp.toUserOutput())); tr("Failed to write logs to \"%1\".").arg(fp.toUserOutput()));
break; break;
} }
} }
@@ -636,14 +636,14 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
} else { } else {
QMessageBox::critical( QMessageBox::critical(
ICore::dialogParent(), tr("Error"), ICore::dialogParent(), tr("Error"),
tr("Failed to open file '%1' for writing logs.").arg(fp.toUserOutput())); tr("Failed to open file \"%1\" for writing logs.").arg(fp.toUserOutput()));
} }
} }
void LoggingViewManagerWidget::saveEnabledCategoryPreset() const void LoggingViewManagerWidget::saveEnabledCategoryPreset() const
{ {
Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(), Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(),
tr("Save enabled categories as")); tr("Save Enabled Categories As"));
if (fp.isEmpty()) if (fp.isEmpty())
return; return;
const QList<LoggingCategoryItem> enabled = m_categoryModel->enabledCategories(); const QList<LoggingCategoryItem> enabled = m_categoryModel->enabledCategories();
@@ -663,13 +663,13 @@ void LoggingViewManagerWidget::saveEnabledCategoryPreset() const
if (!fp.writeFileContents(doc.toJson(QJsonDocument::Compact))) if (!fp.writeFileContents(doc.toJson(QJsonDocument::Compact)))
QMessageBox::critical( QMessageBox::critical(
ICore::dialogParent(), tr("Error"), ICore::dialogParent(), tr("Error"),
tr("Failed to write preset file '%1'.").arg(fp.toUserOutput())); tr("Failed to write preset file \"%1\".").arg(fp.toUserOutput()));
} }
void LoggingViewManagerWidget::loadAndUpdateFromPreset() void LoggingViewManagerWidget::loadAndUpdateFromPreset()
{ {
Utils::FilePath fp = Utils::FileUtils::getOpenFilePath(ICore::dialogParent(), Utils::FilePath fp = Utils::FileUtils::getOpenFilePath(ICore::dialogParent(),
tr("Load enabled categories from")); tr("Load Enabled Categories From"));
if (fp.isEmpty()) if (fp.isEmpty())
return; return;
// read file, update categories // read file, update categories
@@ -677,7 +677,7 @@ void LoggingViewManagerWidget::loadAndUpdateFromPreset()
QJsonDocument doc = QJsonDocument::fromJson(fp.fileContents(), &error); QJsonDocument doc = QJsonDocument::fromJson(fp.fileContents(), &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
QMessageBox::critical(ICore::dialogParent(), tr("Error"), QMessageBox::critical(ICore::dialogParent(), tr("Error"),
tr("Failed to read preset file '%1': %2").arg(fp.toUserOutput()) tr("Failed to read preset file \"%1\": %2").arg(fp.toUserOutput())
.arg(error.errorString())); .arg(error.errorString()));
return; return;
} }

View File

@@ -41,7 +41,7 @@ namespace CppEditor {
ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWidget *parent) ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_label(new QLabel(tr("Diagnostic Configuration:"))) , m_label(new QLabel(tr("Diagnostic configuration:")))
, m_button(new QPushButton) , m_button(new QPushButton)
{ {
auto *layout = new QHBoxLayout(this); auto *layout = new QHBoxLayout(this);

View File

@@ -177,6 +177,8 @@ QList<AccessRange> collectAccessRanges(const CPlusPlus::TranslationUnit *tu,
if (AccessDeclarationAST *xsDecl = decl->asAccessDeclaration()) { if (AccessDeclarationAST *xsDecl = decl->asAccessDeclaration()) {
const unsigned token = xsDecl->access_specifier_token; const unsigned token = xsDecl->access_specifier_token;
if (tu->tokenAt(token).generated())
continue;
InsertionPointLocator::AccessSpec newXsSpec = initialXs; InsertionPointLocator::AccessSpec newXsSpec = initialXs;
bool isSlot = xsDecl->slots_token && tu->tokenKind(xsDecl->slots_token) == T_Q_SLOTS; bool isSlot = xsDecl->slots_token && tu->tokenKind(xsDecl->slots_token) == T_Q_SLOTS;

View File

@@ -120,7 +120,7 @@ DebuggerSettings::DebuggerSettings()
forceLoggingToConsole.setSettingsKey(debugModeGroup, "ForceLoggingToConsole"); forceLoggingToConsole.setSettingsKey(debugModeGroup, "ForceLoggingToConsole");
forceLoggingToConsole.setLabelText(tr("Force logging to console")); forceLoggingToConsole.setLabelText(tr("Force logging to console"));
forceLoggingToConsole.setToolTip(tr("This sets QT_LOGGING_TO_CONSOLE=1 in the environment " forceLoggingToConsole.setToolTip(tr("Sets QT_LOGGING_TO_CONSOLE=1 in the environment "
"of the debugged program, preventing storing debug output " "of the debugged program, preventing storing debug output "
"in system logs.")); "in system logs."));
@@ -165,7 +165,7 @@ DebuggerSettings::DebuggerSettings()
CommonOptionsPage::msgSetBreakpointAtFunction(Constants::CRT_DEBUG_REPORT)); CommonOptionsPage::msgSetBreakpointAtFunction(Constants::CRT_DEBUG_REPORT));
cdbBreakOnCrtDbgReport.setToolTip( cdbBreakOnCrtDbgReport.setToolTip(
CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(Constants::CRT_DEBUG_REPORT, CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(Constants::CRT_DEBUG_REPORT,
tr("This is useful to catch runtime error messages for example caused by assert()."))); tr("Catches runtime error messages caused by assert(), for example.")));
useCdbConsole.setSettingsKey(cdbSettingsGroup, "CDB_Console"); useCdbConsole.setSettingsKey(cdbSettingsGroup, "CDB_Console");
useCdbConsole.setToolTip("<html><head/><body><p>" + tr( useCdbConsole.setToolTip("<html><head/><body><p>" + tr(
@@ -421,7 +421,7 @@ DebuggerSettings::DebuggerSettings()
useAnnotationsInMainEditor.setSettingsKey(debugModeGroup, "UseAnnotations"); useAnnotationsInMainEditor.setSettingsKey(debugModeGroup, "UseAnnotations");
useAnnotationsInMainEditor.setLabelText(tr("Use annotations in main editor when debugging")); useAnnotationsInMainEditor.setLabelText(tr("Use annotations in main editor when debugging"));
useAnnotationsInMainEditor.setToolTip(tr("<p>Checking this will show simple variable values " useAnnotationsInMainEditor.setToolTip(tr("<p>Shows simple variable values "
"as annotations in the main editor during debugging.")); "as annotations in the main editor during debugging."));
useAnnotationsInMainEditor.setDefaultValue(true); useAnnotationsInMainEditor.setDefaultValue(true);
@@ -440,7 +440,7 @@ DebuggerSettings::DebuggerSettings()
useToolTipsInMainEditor.setSettingsKey(debugModeGroup, "UseToolTips"); useToolTipsInMainEditor.setSettingsKey(debugModeGroup, "UseToolTips");
useToolTipsInMainEditor.setLabelText(tr("Use tooltips in main editor when debugging")); useToolTipsInMainEditor.setLabelText(tr("Use tooltips in main editor when debugging"));
useToolTipsInMainEditor.setToolTip(tr("<p>Checking this will enable tooltips for variable " useToolTipsInMainEditor.setToolTip(tr("<p>Enables tooltips for variable "
"values during debugging. Since this can slow down debugging and " "values during debugging. Since this can slow down debugging and "
"does not provide reliable information as it does not use scope " "does not provide reliable information as it does not use scope "
"information, it is switched off by default.")); "information, it is switched off by default."));
@@ -448,17 +448,17 @@ DebuggerSettings::DebuggerSettings()
useToolTipsInLocalsView.setSettingsKey(debugModeGroup, "UseToolTipsInLocalsView"); useToolTipsInLocalsView.setSettingsKey(debugModeGroup, "UseToolTipsInLocalsView");
useToolTipsInLocalsView.setLabelText(tr("Use Tooltips in Locals View when Debugging")); useToolTipsInLocalsView.setLabelText(tr("Use Tooltips in Locals View when Debugging"));
useToolTipsInLocalsView.setToolTip(tr("<p>Checking this will enable tooltips in the locals " useToolTipsInLocalsView.setToolTip(tr("<p>Enables tooltips in the locals "
"view during debugging.")); "view during debugging."));
useToolTipsInBreakpointsView.setSettingsKey(debugModeGroup, "UseToolTipsInBreakpointsView"); useToolTipsInBreakpointsView.setSettingsKey(debugModeGroup, "UseToolTipsInBreakpointsView");
useToolTipsInBreakpointsView.setLabelText(tr("Use Tooltips in Breakpoints View when Debugging")); useToolTipsInBreakpointsView.setLabelText(tr("Use Tooltips in Breakpoints View when Debugging"));
useToolTipsInBreakpointsView.setToolTip(tr("<p>Checking this will enable tooltips in the breakpoints " useToolTipsInBreakpointsView.setToolTip(tr("<p>Enables tooltips in the breakpoints "
"view during debugging.")); "view during debugging."));
useToolTipsInStackView.setSettingsKey(debugModeGroup, "UseToolTipsInStackView"); useToolTipsInStackView.setSettingsKey(debugModeGroup, "UseToolTipsInStackView");
useToolTipsInStackView.setLabelText(tr("Use Tooltips in Stack View when Debugging")); useToolTipsInStackView.setLabelText(tr("Use Tooltips in Stack View when Debugging"));
useToolTipsInStackView.setToolTip(tr("<p>Checking this will enable tooltips in the stack " useToolTipsInStackView.setToolTip(tr("<p>Enables tooltips in the stack "
"view during debugging.")); "view during debugging."));
useToolTipsInStackView.setDefaultValue(true); useToolTipsInStackView.setDefaultValue(true);

View File

@@ -333,7 +333,7 @@ public:
m_runAsOutsideUser = new QCheckBox(tr("Run as outside user")); m_runAsOutsideUser = new QCheckBox(tr("Run as outside user"));
m_runAsOutsideUser->setToolTip(tr("Uses user ID and group ID of the user running Qt Creator " m_runAsOutsideUser->setToolTip(tr("Uses user ID and group ID of the user running Qt Creator "
"in the Docker container.")); "in the docker container."));
m_runAsOutsideUser->setChecked(data.useLocalUidGid); m_runAsOutsideUser->setChecked(data.useLocalUidGid);
m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost()); m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost());
@@ -361,7 +361,7 @@ public:
m_pathsListEdit = new PathListEditor; m_pathsListEdit = new PathListEditor;
m_pathsListEdit->setToolTip(tr("Maps paths in this list one-to-one to the " m_pathsListEdit->setToolTip(tr("Maps paths in this list one-to-one to the "
"Docker container.")); "docker container."));
m_pathsListEdit->setPathList(data.mounts); m_pathsListEdit->setPathList(data.mounts);
connect(m_pathsListEdit, &PathListEditor::changed, this, [dockerDevice, this]() { connect(m_pathsListEdit, &PathListEditor::changed, this, [dockerDevice, this]() {
@@ -378,12 +378,12 @@ public:
auto searchDirsComboBox = new QComboBox; auto searchDirsComboBox = new QComboBox;
searchDirsComboBox->addItem(tr("Search in PATH")); searchDirsComboBox->addItem(tr("Search in PATH"));
searchDirsComboBox->addItem(tr("Search in selected directories")); searchDirsComboBox->addItem(tr("Search in Selected Directories"));
auto searchDirsLineEdit = new QLineEdit; auto searchDirsLineEdit = new QLineEdit;
searchDirsLineEdit->setText("/usr/bin;/opt"); searchDirsLineEdit->setText("/usr/bin;/opt");
searchDirsLineEdit->setToolTip( searchDirsLineEdit->setToolTip(
tr("Select the paths in the Docker image that should be scanned for Kit entries")); tr("Select the paths in the docker image that should be scanned for kit entries."));
auto searchPaths = [this, searchDirsComboBox, searchDirsLineEdit, dockerDevice] { auto searchPaths = [this, searchDirsComboBox, searchDirsLineEdit, dockerDevice] {
FilePaths paths; FilePaths paths;
@@ -491,7 +491,7 @@ Tasks DockerDevice::validate() const
Tasks result; Tasks result;
if (d->m_data.mounts.isEmpty()) { if (d->m_data.mounts.isEmpty()) {
result << Task(Task::Error, result << Task(Task::Error,
tr("The Docker device has not set up shared directories." tr("The docker device has not set up shared directories."
"This will not work for building."), "This will not work for building."),
{}, -1, {}); {}, -1, {});
} }
@@ -529,7 +529,7 @@ DockerDevice::DockerDevice(const DockerDeviceData &data)
Q_UNUSED(env); // TODO: That's the runnable's environment in general. Use it via -e below. Q_UNUSED(env); // TODO: That's the runnable's environment in general. Use it via -e below.
updateContainerAccess(); updateContainerAccess();
if (d->m_container.isEmpty()) { if (d->m_container.isEmpty()) {
MessageManager::writeDisrupting(tr("Error starting remote shell. No container")); MessageManager::writeDisrupting(tr("Error starting remote shell. No container."));
return; return;
} }
@@ -910,7 +910,7 @@ void DockerDevicePrivate::startContainer()
if (exitCode > 120) { if (exitCode > 120) {
DockerPlugin::setGlobalDaemonState(false); DockerPlugin::setGlobalDaemonState(false);
LOG("DOCKER DAEMON NOT RUNNING?"); LOG("DOCKER DAEMON NOT RUNNING?");
MessageManager::writeFlashing(tr("Docker Daemon appears to be not running. " MessageManager::writeFlashing(tr("Docker daemon appears to be not running. "
"Verify daemon is up and running and reset the " "Verify daemon is up and running and reset the "
"docker daemon on the docker device settings page " "docker daemon on the docker device settings page "
"or restart Qt Creator.")); "or restart Qt Creator."));
@@ -974,7 +974,7 @@ void DockerDevicePrivate::updateFileSystemAccess()
if (!QFileInfo(m_mergedDir).isReadable()) { if (!QFileInfo(m_mergedDir).isReadable()) {
MessageManager::writeFlashing( MessageManager::writeFlashing(
tr("Local read access to Docker container %1 unavailable through directory \"%2\".") tr("Local read access to docker container %1 unavailable through directory \"%2\".")
.arg(m_container, m_mergedDir) .arg(m_container, m_mergedDir)
+ '\n' + tr("Output: \"%1\"").arg(out) + '\n' + tr("Output: \"%1\"").arg(out)
+ '\n' + tr("Error: \"%1\"").arg(proc.stdErr())); + '\n' + tr("Error: \"%1\"").arg(proc.stdErr()));

View File

@@ -112,6 +112,11 @@ Client::Client(BaseClientInterface *clientInterface)
m_tokenSupport.setTokenTypesMap(SemanticTokens::defaultTokenTypesMap()); m_tokenSupport.setTokenTypesMap(SemanticTokens::defaultTokenTypesMap());
m_tokenSupport.setTokenModifiersMap(SemanticTokens::defaultTokenModifiersMap()); m_tokenSupport.setTokenModifiersMap(SemanticTokens::defaultTokenModifiersMap());
m_shutdownTimer.setInterval(20 /*seconds*/ * 1000);
connect(&m_shutdownTimer, &QTimer::timeout, this, [this] {
LanguageClientManager::deleteClient(this);
});
} }
QString Client::name() const QString Client::name() const
@@ -317,7 +322,6 @@ void Client::initialize()
// directly send message otherwise the state check of sendContent would fail // directly send message otherwise the state check of sendContent would fail
sendMessage(initRequest.toBaseMessage()); sendMessage(initRequest.toBaseMessage());
m_clientInterface->sendMessage(initRequest.toBaseMessage());
m_state = InitializeRequested; m_state = InitializeRequested;
} }
@@ -331,6 +335,7 @@ void Client::shutdown()
}); });
sendContent(shutdown); sendContent(shutdown);
m_state = ShutdownRequested; m_state = ShutdownRequested;
m_shutdownTimer.start();
} }
Client::State Client::state() const Client::State Client::state() const
@@ -364,7 +369,7 @@ void Client::setClientCapabilities(const LanguageServerProtocol::ClientCapabilit
void Client::openDocument(TextEditor::TextDocument *document) void Client::openDocument(TextEditor::TextDocument *document)
{ {
using namespace TextEditor; using namespace TextEditor;
if (!isSupportedDocument(document)) if (m_openedDocument.contains(document) || !isSupportedDocument(document))
return; return;
if (m_state != Initialized) { if (m_state != Initialized) {
@@ -372,8 +377,6 @@ void Client::openDocument(TextEditor::TextDocument *document)
return; return;
} }
QTC_ASSERT(!m_openedDocument.contains(document), return);
const FilePath &filePath = document->filePath(); const FilePath &filePath = document->filePath();
const QString method(DidOpenTextDocumentNotification::methodName); const QString method(DidOpenTextDocumentNotification::methodName);
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) { if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
@@ -1622,6 +1625,7 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse) void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)
{ {
m_shutdownTimer.stop();
QTC_ASSERT(m_state == ShutdownRequested, return); QTC_ASSERT(m_state == ShutdownRequested, return);
QTC_ASSERT(m_clientInterface, return); QTC_ASSERT(m_clientInterface, return);
optional<ShutdownRequest::Response::Error> errorValue = shutdownResponse.error(); optional<ShutdownRequest::Response::Error> errorValue = shutdownResponse.error();
@@ -1634,6 +1638,7 @@ void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)
sendMessage(ExitNotification().toBaseMessage()); sendMessage(ExitNotification().toBaseMessage());
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown"; qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
m_state = Shutdown; m_state = Shutdown;
m_shutdownTimer.start();
} }
bool Client::sendWorkspceFolderChanges() const bool Client::sendWorkspceFolderChanges() const

View File

@@ -316,6 +316,7 @@ private:
LogTarget m_logTarget = LogTarget::Ui; LogTarget m_logTarget = LogTarget::Ui;
bool m_locatorsEnabled = true; bool m_locatorsEnabled = true;
bool m_autoRequestCodeActions = true; bool m_autoRequestCodeActions = true;
QTimer m_shutdownTimer;
}; };
} // namespace LanguageClient } // namespace LanguageClient

View File

@@ -232,7 +232,7 @@ void LanguageClientManager::deleteClient(Client *client)
QTC_ASSERT(managerInstance, return); QTC_ASSERT(managerInstance, return);
QTC_ASSERT(client, return); QTC_ASSERT(client, return);
qCDebug(Log) << "delete client: " << client->name() << client; qCDebug(Log) << "delete client: " << client->name() << client;
client->disconnect(); client->disconnect(managerInstance);
managerInstance->m_clients.removeAll(client); managerInstance->m_clients.removeAll(client);
for (QVector<Client *> &clients : managerInstance->m_clientsForSetting) for (QVector<Client *> &clients : managerInstance->m_clientsForSetting)
clients.removeAll(client); clients.removeAll(client);

View File

@@ -8,8 +8,10 @@ add_qtc_plugin(McuSupport
mcusupportconstants.h mcusupportconstants.h
mcusupportdevice.cpp mcusupportdevice.h mcusupportdevice.cpp mcusupportdevice.h
mcusupportoptions.cpp mcusupportoptions.h mcuabstractpackage.h mcusupportoptions.cpp mcusupportoptions.h mcuabstractpackage.h
mcukitmanager.cpp mcukitmanager.h
mcusupportoptionspage.cpp mcusupportoptionspage.h mcusupportoptionspage.cpp mcusupportoptionspage.h
mcupackage.cpp mcupackage.h mcupackage.cpp mcupackage.h
mcutarget.cpp mcutarget.h
mcusupportplugin.cpp mcusupportplugin.h mcusupportplugin.cpp mcusupportplugin.h
mcusupportsdk.cpp mcusupportsdk.h mcusupportsdk.cpp mcusupportsdk.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h

View File

@@ -58,14 +58,10 @@ public:
virtual const QString &environmentVariableName() const = 0; virtual const QString &environmentVariableName() const = 0;
virtual void setAddToPath(bool) = 0; virtual void setAddToPath(bool) = 0;
virtual bool addToPath() const = 0; virtual bool addToPath() const = 0;
virtual void writeGeneralSettings() const = 0;
virtual bool writeToSettings() const = 0; virtual bool writeToSettings() const = 0;
virtual void setRelativePathModifier(const QString &) = 0; virtual void setRelativePathModifier(const QString &) = 0;
virtual void setVersions(const QStringList &) = 0; virtual void setVersions(const QStringList &) = 0;
virtual bool automaticKitCreationEnabled() const = 0;
virtual void setAutomaticKitCreationEnabled(const bool enabled) = 0;
virtual QWidget *widget() = 0; virtual QWidget *widget() = 0;
signals: signals:

View File

@@ -0,0 +1,596 @@
/****************************************************************************
**
** 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 "mcukitmanager.h"
#include "mcusupportoptions.h"
#include "mcusupportconstants.h"
#include "mcukitinformation.h"
#include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h"
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/icore.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h>
#include <utils/algorithm.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversionmanager.h>
#include <QMessageBox>
#include <QPushButton>
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
using namespace ProjectExplorer;
using namespace Utils;
namespace McuSupport {
namespace Internal {
namespace McuKitManager {
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static FilePath qulDocsDir()
{
const FilePath qulDir = McuSupportOptions::qulDirFromSettings();
if (qulDir.isEmpty() || !qulDir.exists())
return {};
const FilePath docsDir = qulDir.pathAppended("docs");
return docsDir.exists() ? docsDir : FilePath();
}
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{
switch (tcPackage->type()) {
case McuToolChainPackage::Type::Unsupported:
return;
case McuToolChainPackage::Type::GHS:
case McuToolChainPackage::Type::GHSArm:
return; // No Green Hills toolchain, because support for it is missing.
case McuToolChainPackage::Type::IAR:
case McuToolChainPackage::Type::KEIL:
case McuToolChainPackage::Type::MSVC:
case McuToolChainPackage::Type::GCC:
case McuToolChainPackage::Type::ArmGcc:
ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain(
ProjectExplorer::Constants::C_LANGUAGE_ID));
ToolChainKitAspect::setToolChain(k,
tcPackage->toolChain(
ProjectExplorer::Constants::CXX_LANGUAGE_ID));
return;
default:
Q_UNREACHABLE();
}
}
static void setKitProperties(const QString &kitName,
Kit *k,
const McuTarget *mcuTarget,
const FilePath &sdkPath)
{
using namespace Constants;
k->setUnexpandedDisplayName(kitName);
k->setValue(KIT_MCUTARGET_VENDOR_KEY, mcuTarget->platform().vendor);
k->setValue(KIT_MCUTARGET_MODEL_KEY, mcuTarget->platform().name);
k->setValue(KIT_MCUTARGET_COLORDEPTH_KEY, mcuTarget->colorDepth());
k->setValue(KIT_MCUTARGET_SDKVERSION_KEY, mcuTarget->qulVersion().toString());
k->setValue(KIT_MCUTARGET_KITVERSION_KEY, KIT_VERSION);
k->setValue(KIT_MCUTARGET_OS_KEY, static_cast<int>(mcuTarget->os()));
k->setValue(KIT_MCUTARGET_TOOCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName());
k->setAutoDetected(false);
k->makeSticky();
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
k->setDeviceTypeForIcon(DEVICE_TYPE);
k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true);
k->setValue(QtSupport::KitQmlImportPath::id(), sdkPath.pathAppended("include/qul").toVariant());
k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true);
QSet<Id> irrelevant = {
SysRootKitAspect::id(),
QtSupport::SuppliesQtQuickImportPath::id(),
QtSupport::KitQmlImportPath::id(),
QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(),
};
if (!McuSupportOptions::kitsNeedQtVersion())
irrelevant.insert(QtSupport::QtKitAspect::id());
k->setIrrelevantAspects(irrelevant);
}
static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
{
if (tcPackage->isDesktopToolchain()) {
// Qt Creator seems to be smart enough to deduce the right Kit debugger from the ToolChain
return;
}
switch (tcPackage->type()) {
case McuToolChainPackage::Type::Unsupported:
case McuToolChainPackage::Type::GHS:
case McuToolChainPackage::Type::GHSArm:
case McuToolChainPackage::Type::IAR:
return; // No Green Hills and IAR debugger, because support for it is missing.
case McuToolChainPackage::Type::KEIL:
case McuToolChainPackage::Type::MSVC:
case McuToolChainPackage::Type::GCC:
case McuToolChainPackage::Type::ArmGcc: {
const QVariant debuggerId = tcPackage->debuggerId();
if (debuggerId.isValid()) {
Debugger::DebuggerKitAspect::setDebugger(k, debuggerId);
}
return;
}
default:
Q_UNREACHABLE();
}
}
static void setKitDevice(Kit *k, const McuTarget *mcuTarget)
{
// "Device Type" Desktop is the default. We use that for the Qt for MCUs Desktop Kit
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
return;
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static bool expectsCmakeVars(const McuTarget *mcuTarget)
{
return mcuTarget->qulVersion() >= QVersionNumber{2, 0};
}
static void setKitDependencies(Kit *k,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
NameValueItems dependencies;
auto processPackage = [&dependencies](const McuAbstractPackage *package) {
if (!package->environmentVariableName().isEmpty())
dependencies.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->detectionPath())});
};
for (auto package : mcuTarget->packages())
processPackage(package);
processPackage(qtForMCUsSdkPackage);
McuDependenciesKitAspect::setDependencies(k, dependencies);
auto irrelevant = k->irrelevantAspects();
irrelevant.insert(McuDependenciesKitAspect::id());
k->setIrrelevantAspects(irrelevant);
}
static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePath &qulDir)
{
using namespace CMakeProjectManager;
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
// CMake ToolChain file for ghs handles CMAKE_*_COMPILER autonomously
if (mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHS
&& mcuTarget->toolChainPackage()->type() != McuToolChainPackage::Type::GHSArm) {
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
}
if (!mcuTarget->toolChainPackage()->isDesktopToolchain()) {
const FilePath cMakeToolchainFile = qulDir.pathAppended(
"lib/cmake/Qul/toolchain/" + mcuTarget->toolChainPackage()->cmakeToolChainFileName());
config.append(
CMakeConfigItem("CMAKE_TOOLCHAIN_FILE", cMakeToolchainFile.toString().toUtf8()));
if (!cMakeToolchainFile.exists()) {
printMessage(McuTarget::tr(
"Warning for target %1: missing CMake toolchain file expected at %2.")
.arg(kitName(mcuTarget),
cMakeToolchainFile.toUserOutput()),
false);
}
}
const FilePath generatorsPath = qulDir.pathAppended("/lib/cmake/Qul/QulGenerators.cmake");
config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8()));
if (!generatorsPath.exists()) {
printMessage(McuTarget::tr("Warning for target %1: missing QulGenerators expected at %2.")
.arg(kitName(mcuTarget), generatorsPath.toUserOutput()),
false);
}
config.append(CMakeConfigItem("QUL_PLATFORM", mcuTarget->platform().name.toUtf8()));
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1()));
if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
CMakeConfigurationKitAspect::setConfiguration(k, config);
if (HostOsInfo::isWindowsHost()) {
auto type = mcuTarget->toolChainPackage()->type();
if (type == McuToolChainPackage::Type::GHS || type == McuToolChainPackage::Type::GHSArm) {
// See https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565802&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565802
// and https://bugreports.qt.io/browse/UL-4247?focusedCommentId=565803&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-565803
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
}
}
}
static void setKitQtVersionOptions(Kit *k)
{
if (!McuSupportOptions::kitsNeedQtVersion())
QtSupport::QtKitAspect::setQtVersion(k, nullptr);
// else: auto-select a Qt version
}
QString kitName(const McuTarget *mcuTarget)
{
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg(
tcPkg->toolChainName().toUpper())
: "";
const QString colorDepth = mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: "";
const QString targetName = mcuTarget->platform().displayName.isEmpty()
? mcuTarget->platform().name
: mcuTarget->platform().displayName;
return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5")
.arg(QString::number(mcuTarget->qulVersion().majorVersion()),
QString::number(mcuTarget->qulVersion().minorVersion()),
targetName,
colorDepth,
compilerName);
}
QList<Kit *> existingKits(const McuTarget *mcuTarget)
{
using namespace Constants;
return Utils::filtered(KitManager::kits(), [mcuTarget](Kit *kit) {
return kit->value(KIT_MCUTARGET_KITVERSION_KEY) == KIT_VERSION
&& (!mcuTarget
|| (kit->value(KIT_MCUTARGET_VENDOR_KEY) == mcuTarget->platform().vendor
&& kit->value(KIT_MCUTARGET_MODEL_KEY) == mcuTarget->platform().name
&& kit->value(KIT_MCUTARGET_COLORDEPTH_KEY) == mcuTarget->colorDepth()
&& kit->value(KIT_MCUTARGET_OS_KEY).toInt()
== static_cast<int>(mcuTarget->os())
&& kit->value(KIT_MCUTARGET_TOOCHAIN_KEY)
== mcuTarget->toolChainPackage()->toolChainName()));
});
}
QList<Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitIsUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) {
const auto environment = Utils::NameValueDictionary(
Utils::NameValueItem::toStringList(EnvironmentKitAspect::environmentChanges(kit)));
return Utils::anyOf(mcuTarget->packages(),
[&environment](const McuAbstractPackage *package) {
return !package->environmentVariableName().isEmpty()
&& environment.value(package->environmentVariableName())
!= package->path().toUserOutput();
});
});
}
QList<Kit *> outdatedKits()
{
return Utils::filtered(KitManager::kits(), [](Kit *kit) {
return !kit->value(Constants::KIT_MCUTARGET_VENDOR_KEY).isNull()
&& kit->value(Constants::KIT_MCUTARGET_KITVERSION_KEY) != KIT_VERSION;
});
}
void removeOutdatedKits()
{
for (auto kit : outdatedKits())
KitManager::deregisterKit(kit);
}
Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(kitName(mcuTarget), k, mcuTarget, qtForMCUsSdk->path());
setKitDevice(k, mcuTarget);
setKitToolchains(k, mcuTarget->toolChainPackage());
setKitDebugger(k, mcuTarget->toolChainPackage());
McuSupportOptions::setKitEnvironment(k, mcuTarget, qtForMCUsSdk);
setKitDependencies(k, mcuTarget, qtForMCUsSdk);
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path());
setKitQtVersionOptions(k);
k->setup();
k->fix();
};
return KitManager::registerKit(init);
}
QVersionNumber kitQulVersion(const Kit *kit)
{
return QVersionNumber::fromString(
kit->value(McuSupport::Constants::KIT_MCUTARGET_SDKVERSION_KEY).toString());
}
static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
{
for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) {
if (nameValueItem.name == variableName)
return FilePath::fromUserInput(nameValueItem.value);
}
return FilePath();
}
bool kitIsUpToDate(const Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput()
== qtForMCUsSdkPackage->path().toUserOutput();
}
void createAutomaticKits()
{
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
const auto createKits = [qtForMCUsPackage]() {
if (McuSupportOptions::automaticKitCreationFromSettings()) {
qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) {
case McuAbstractPackage::Status::ValidPathInvalidPackage: {
const QString displayPath
= FilePath::fromString(qtForMCUsPackage->detectionPath()).toUserOutput();
printMessage(McuPackage::tr("Path %1 exists, but does not contain %2.")
.arg(qtForMCUsPackage->path().toUserOutput(), displayPath),
true);
break;
}
case McuAbstractPackage::Status::InvalidPath: {
printMessage(McuPackage::tr("Path %1 does not exist. Add the path in Tools > Options > "
"Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()),
true);
break;
}
case McuAbstractPackage::Status::EmptyPath: {
printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()),
true);
return;
}
default:
break;
}
return;
}
if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) {
printMessage(McuPackage::tr("No CMake tool was detected. Add a CMake tool in Tools > Options > "
"Kits > CMake."),
true);
return;
}
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false;
for (const auto &target : qAsConst(repo.mcuTargets)) {
// if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty())
continue;
if (!upgradeableKits(target, qtForMCUsPackage).empty()) {
// if kit exists but wrong version/path
needsUpgrade = true;
} else {
// if no kits for this target, create
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
}
};
createKits();
delete qtForMCUsPackage;
}
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption)
{
if (upgradeOption == UpgradeOption::Ignore)
return;
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
auto dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (!matchingKits(target, qtForMCUsPackage).empty())
// already up-to-date
continue;
const auto kits = upgradeableKits(target, qtForMCUsPackage);
if (!kits.empty()) {
if (upgradeOption == UpgradeOption::Replace) {
for (auto existingKit : kits)
KitManager::deregisterKit(existingKit);
}
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk)
{
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path());
McuSupportOptions::setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
}
void fixKitsDependencies()
{
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (target->isValid()) {
for (auto *kit : kitsWithMismatchedDependencies(target)) {
McuSupportOptions::updateKitEnvironment(kit, target);
}
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
}
/**
* @brief Fix/update existing kits if needed
*/
void fixExistingKits()
{
for (Kit *kit : KitManager::kits()) {
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY))
continue;
if (kit->isAutoDetected()) {
kit->setAutoDetected(false);
}
// Check if the MCU kits are flagged as supplying a QtQuick import path, in order
// to tell the QMLJS code-model that it won't need to add a fall-back import
// path.
const auto bringsQtQuickImportPath = QtSupport::SuppliesQtQuickImportPath::id();
auto irrelevantAspects = kit->irrelevantAspects();
if (!irrelevantAspects.contains(bringsQtQuickImportPath)) {
irrelevantAspects.insert(bringsQtQuickImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(bringsQtQuickImportPath)) {
kit->setValue(bringsQtQuickImportPath, true);
}
// Check if the MCU kit supplies its import path.
const auto kitQmlImportPath = QtSupport::KitQmlImportPath::id();
if (!irrelevantAspects.contains(kitQmlImportPath)) {
irrelevantAspects.insert(kitQmlImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(kitQmlImportPath)) {
auto config = CMakeProjectManager::CMakeConfigurationKitAspect::configuration(kit);
for (const auto &cfgItem : qAsConst(config)) {
if (cfgItem.key == "QUL_GENERATORS") {
auto idx = cfgItem.value.indexOf("/lib/cmake/Qul");
auto qulDir = cfgItem.value.left(idx);
kit->setValue(kitQmlImportPath, QVariant(qulDir + "/include/qul"));
break;
}
}
}
// Check if the MCU kit has the flag for merged header/qml-import paths set.
const auto mergedPaths = QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id();
if (!irrelevantAspects.contains(mergedPaths)) {
irrelevantAspects.insert(mergedPaths);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->value(mergedPaths, false).toBool()) {
kit->setValue(mergedPaths, true);
}
}
// Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) {
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
setKitDependencies(kit, target, qtForMCUsPackage);
}
}
repo.deletePackagesAndTargets();
}
delete qtForMCUsPackage;
}
} // namespace McuKitManager
} // namespace Internal
} // namespace McuSupport

View File

@@ -0,0 +1,86 @@
/****************************************************************************
**
** Copyright (C) 2022 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 <utils/environmentfwd.h>
#include "mcusupport_global.h"
#include <QCoreApplication>
#include <QObject>
#include <QVector>
#include <QVersionNumber>
namespace ProjectExplorer {
class Kit;
} // namespace ProjectExplorer
namespace McuSupport {
namespace Internal {
class McuAbstractPackage;
class McuToolChainPackage;
class McuTarget;
namespace McuKitManager
{
enum class UpgradeOption {
Ignore,
Keep,
Replace
};
// Creating kits:
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
void createAutomaticKits();
// Querying the kits:
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> upgradeableKits(
const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
// Upgrading kits:
void upgradeKitsByCreatingNewPackage(UpgradeOption upgradeOption);
void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
// Fixing kits:
void fixKitsDependencies();
void fixExistingKits();
// Outdated kits:
QList<ProjectExplorer::Kit *> outdatedKits();
void removeOutdatedKits();
// Querying kits:
QString kitName(const McuTarget* mcuTarget);
QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
bool kitIsUpToDate(const ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
} // namespace McuKitManager
} // namespace Internal
} // namespace McuSupport

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -25,6 +25,7 @@
#include "mcupackage.h" #include "mcupackage.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportversiondetection.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -40,15 +41,6 @@ using namespace Utils;
namespace McuSupport::Internal { namespace McuSupport::Internal {
static bool automaticKitCreationFromSettings(QSettings::Scope scope = QSettings::UserScope)
{
QSettings *settings = Core::ICore::settings(scope);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
bool automaticKitCreation = settings->value(key, true).toBool();
return automaticKitCreation;
}
McuPackage::McuPackage(const QString &label, McuPackage::McuPackage(const QString &label,
const FilePath &defaultPath, const FilePath &defaultPath,
const QString &detectionPath, const QString &detectionPath,
@@ -65,7 +57,6 @@ McuPackage::McuPackage(const QString &label,
, m_downloadUrl(downloadUrl) , m_downloadUrl(downloadUrl)
{ {
m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath); m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath);
m_automaticKitCreation = automaticKitCreationFromSettings(QSettings::UserScope);
} }
FilePath McuPackage::basePath() const FilePath McuPackage::basePath() const
@@ -161,14 +152,6 @@ bool McuPackage::addToPath() const
return m_addToPath; return m_addToPath;
} }
void McuPackage::writeGeneralSettings() const
{
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
QSettings *settings = Core::ICore::settings();
settings->setValue(key, m_automaticKitCreation);
}
bool McuPackage::writeToSettings() const bool McuPackage::writeToSettings() const
{ {
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey, const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
@@ -191,16 +174,6 @@ void McuPackage::setVersions(const QStringList &versions)
m_versions = versions; m_versions = versions;
} }
bool McuPackage::automaticKitCreationEnabled() const
{
return m_automaticKitCreation;
}
void McuPackage::setAutomaticKitCreationEnabled(const bool enabled)
{
m_automaticKitCreation = enabled;
}
void McuPackage::updatePath() void McuPackage::updatePath()
{ {
m_path = m_fileChooser->rawFilePath(); m_path = m_fileChooser->rawFilePath();
@@ -269,9 +242,10 @@ QString McuPackage::statusText() const
.arg(displayPackagePath, displayDetectedPath); .arg(displayPackagePath, displayDetectedPath);
break; break;
case Status::ValidPackageMismatchedVersion: { case Status::ValidPackageMismatchedVersion: {
const QString versionWarning = m_versions.size() == 1 ? const QString versionWarning
tr("but only version %1 is supported").arg(m_versions.first()) : = m_versions.size() == 1
tr("but only versions %1 are supported").arg(displayVersions); ? tr("but only version %1 is supported").arg(m_versions.first())
: tr("but only versions %1 are supported").arg(displayVersions);
response = tr("Path %1 is valid, %2 was found, %3.") response = tr("Path %1 is valid, %2 was found, %3.")
.arg(displayPackagePath, displayDetectedPath, versionWarning); .arg(displayPackagePath, displayDetectedPath, versionWarning);
break; break;
@@ -313,4 +287,5 @@ bool McuToolChainPackage::isDesktopToolchain() const
return m_type == Type::MSVC || m_type == Type::GCC; return m_type == Type::MSVC || m_type == Type::GCC;
} }
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -26,10 +26,8 @@
#pragma once #pragma once
#include "mcuabstractpackage.h" #include "mcuabstractpackage.h"
#include "mcusupportversiondetection.h"
#include <utils/filepath.h> #include <utils/filepath.h>
#include <utils/id.h>
#include <QObject> #include <QObject>
@@ -42,11 +40,14 @@ class ToolChain;
namespace Utils { namespace Utils {
class PathChooser; class PathChooser;
class InfoLabel; class InfoLabel;
class Id;
} // namespace Utils } // namespace Utils
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class McuPackageVersionDetector;
class McuPackage : public McuAbstractPackage class McuPackage : public McuAbstractPackage
{ {
Q_OBJECT Q_OBJECT
@@ -73,23 +74,14 @@ public:
bool validStatus() const override; bool validStatus() const override;
void setAddToPath(bool addToPath) override; void setAddToPath(bool addToPath) override;
bool addToPath() const override; bool addToPath() const override;
void writeGeneralSettings() const override;
bool writeToSettings() const override; bool writeToSettings() const override;
void setRelativePathModifier(const QString &path) override; void setRelativePathModifier(const QString &path) override;
void setVersions(const QStringList &versions) override; void setVersions(const QStringList &versions) override;
//TODO(piotr.mucko): Why every package knows about automatic kit creation. This should be outside of this class.
bool automaticKitCreationEnabled() const override;
void setAutomaticKitCreationEnabled(const bool enabled) override;
QWidget *widget() override; QWidget *widget() override;
const QString &environmentVariableName() const override; const QString &environmentVariableName() const override;
signals:
void changed();
void statusChanged();
private: private:
void updatePath(); void updatePath();
void updateStatusUi(); void updateStatusUi();
@@ -111,7 +103,6 @@ private:
const QString m_environmentVariableName; const QString m_environmentVariableName;
const QString m_downloadUrl; const QString m_downloadUrl;
bool m_addToPath = false; bool m_addToPath = false;
bool m_automaticKitCreation = true;
Status m_status = Status::InvalidPath; Status m_status = Status::InvalidPath;
}; };

View File

@@ -18,6 +18,8 @@ QtcPlugin {
"mcuabstractpackage.h", "mcuabstractpackage.h",
"mcupackage.cpp", "mcupackage.cpp",
"mcupackage.h", "mcupackage.h",
"mcutarget.cpp",
"mcutarget.h",
"mcusupport.qrc", "mcusupport.qrc",
"mcusupport_global.h", "mcusupport_global.h",
"mcusupportconstants.h", "mcusupportconstants.h",
@@ -25,6 +27,8 @@ QtcPlugin {
"mcusupportdevice.h", "mcusupportdevice.h",
"mcusupportoptions.cpp", "mcusupportoptions.cpp",
"mcusupportoptions.h", "mcusupportoptions.h",
"mcukitmanager.cpp",
"mcukitmanager.h",
"mcusupportoptionspage.cpp", "mcusupportoptionspage.cpp",
"mcusupportoptionspage.h", "mcusupportoptionspage.h",
"mcusupportplugin.cpp", "mcusupportplugin.cpp",

View File

@@ -24,47 +24,27 @@
****************************************************************************/ ****************************************************************************/
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcukitinformation.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcutarget.h"
#include "mcukitmanager.h"
#include "mcukitinformation.h"
#include "mcusupportcmakemapper.h" #include "mcusupportcmakemapper.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/helpmanager.h> #include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h> #include <debugger/debuggerkitinformation.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/infolabel.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversionmanager.h> #include <qtsupport/qtversionmanager.h>
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
using CMakeProjectManager::CMakeConfigItem; using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect; using CMakeProjectManager::CMakeConfigurationKitAspect;
@@ -74,263 +54,6 @@ using namespace Utils;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
static const int KIT_VERSION = 9; // Bumps up whenever details in Kit creation change
static bool kitNeedsQtVersion()
{
// Only on Windows, Qt is linked into the distributed qul Desktop libs. Also, the host tools
// are missing the Qt runtime libraries on non-Windows.
return !HostOsInfo::isWindowsHost();
}
static ToolChain *msvcToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor
|| abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
&& abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64
&& t->language() == language;
});
return toolChain;
}
static ToolChain *gccToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture
&& abi.wordWidth() == 64 && t->language() == language;
});
return toolChain;
}
static ToolChain *armGccToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) {
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain *> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static ToolChain *iarToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID
&& t->language() == language;
});
if (!toolChain) {
ToolChainFactory *iarFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (iarFactory) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language});
for (auto tc : detected) {
if (tc->language() == language) {
toolChain = tc;
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("IAREW");
ToolChainManager::registerToolChain(toolChain);
}
}
}
}
return toolChain;
}
ToolChain *McuToolChainPackage::toolChain(Id language) const
{
switch (m_type) {
case Type::MSVC:
return msvcToolChain(language);
case Type::GCC:
return gccToolChain(language);
case Type::IAR: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
return iarToolChain(compiler, language);
}
case Type::ArmGcc:
case Type::KEIL:
case Type::GHS:
case Type::GHSArm:
case Type::Unsupported: {
const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
const QString comp = QLatin1String(m_type == Type::ArmGcc ? "/bin/arm-none-eabi-%1"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
case Type::ArmGcc:
return QLatin1String("armgcc");
case Type::IAR:
return QLatin1String("iar");
case Type::KEIL:
return QLatin1String("keil");
case Type::GHS:
return QLatin1String("ghs");
case Type::GHSArm:
return QLatin1String("ghs-arm");
default:
return QLatin1String("unsupported");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
QVariant McuToolChainPackage::debuggerId() const
{
using namespace Debugger;
QString sub, displayName;
DebuggerEngineType engineType;
switch (m_type) {
case Type::ArmGcc: {
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
displayName = McuPackage::tr("Arm GDB at %1");
engineType = Debugger::GdbEngineType;
break;
}
case Type::IAR: {
sub = QString::fromLatin1("../common/bin/CSpyBat");
displayName = QLatin1String("CSpy");
engineType = Debugger::NoEngineType; // support for IAR missing
break;
}
case Type::KEIL: {
sub = QString::fromLatin1("UV4/UV4");
displayName = QLatin1String("KEIL uVision Debugger");
engineType = Debugger::UvscEngineType;
break;
}
default:
return QVariant();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
if (const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command)) {
return debugger->id();
}
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
newDebugger.setEngineType(engineType);
return DebuggerItemManager::registerDebugger(newDebugger);
}
McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth)
: m_qulVersion(qulVersion)
, m_platform(platform)
, m_os(os)
, m_packages(packages)
, m_toolChainPackage(toolChainPackage)
, m_colorDepth(colorDepth)
{}
const QVector<McuAbstractPackage *> &McuTarget::packages() const
{
return m_packages;
}
const McuToolChainPackage *McuTarget::toolChainPackage() const
{
return m_toolChainPackage;
}
McuTarget::OS McuTarget::os() const
{
return m_os;
}
const McuTarget::Platform &McuTarget::platform() const
{
return m_platform;
}
bool McuTarget::isValid() const
{
return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus();
return package->validStatus();
});
}
void McuTarget::printPackageProblems() const
{
for (auto package : packages()) {
package->updateStatus();
if (!package->validStatus()) {
printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuSupportOptions::kitName(this),
package->label(),
package->statusText()),
true);
}
if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion) {
printMessage(tr("Warning creating kit for target %1, package %2: %3")
.arg(McuSupportOptions::kitName(this),
package->label(),
package->statusText()),
false);
}
}
}
const QVersionNumber &McuTarget::qulVersion() const
{
return m_qulVersion;
}
int McuTarget::colorDepth() const
{
return m_colorDepth;
}
void McuSdkRepository::deletePackagesAndTargets() void McuSdkRepository::deletePackagesAndTargets()
{ {
qDeleteAll(packages); qDeleteAll(packages);
@@ -347,6 +70,7 @@ McuSupportOptions::McuSupportOptions(QObject *parent)
&McuAbstractPackage::changed, &McuAbstractPackage::changed,
this, this,
&McuSupportOptions::populatePackagesAndTargets); &McuSupportOptions::populatePackagesAndTargets);
m_automaticKitCreation = automaticKitCreationFromSettings();
} }
McuSupportOptions::~McuSupportOptions() McuSupportOptions::~McuSupportOptions()
@@ -402,7 +126,7 @@ void McuSupportOptions::registerExamples()
const QVersionNumber &McuSupportOptions::minimalQulVersion() const QVersionNumber &McuSupportOptions::minimalQulVersion()
{ {
static const QVersionNumber v({1, 3}); static const QVersionNumber v({2, 0});
return v; return v;
} }
@@ -413,48 +137,16 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
if (qtForMCUsSdkPackage->validStatus()) if (qtForMCUsSdkPackage->validStatus())
Sdk::targetsAndPackages(dir, &sdkRepository); Sdk::targetsAndPackages(dir, &sdkRepository);
for (const auto &package : qAsConst(sdkRepository.packages)) for (const auto &package : qAsConst(sdkRepository.packages))
connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::changed); connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::packagesChanged);
emit changed(); emit packagesChanged();
} }
FilePath McuSupportOptions::qulDirFromSettings() FilePath McuSupportOptions::qulDirFromSettings()
{ {
return Sdk::packagePathFromSettings(Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, return Sdk::packagePathFromSettings(Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK,
QSettings::UserScope); QSettings::UserScope,
} {});
static void setKitProperties(const QString &kitName,
Kit *k,
const McuTarget *mcuTarget,
const FilePath &sdkPath)
{
using namespace Constants;
k->setUnexpandedDisplayName(kitName);
k->setValue(KIT_MCUTARGET_VENDOR_KEY, mcuTarget->platform().vendor);
k->setValue(KIT_MCUTARGET_MODEL_KEY, mcuTarget->platform().name);
k->setValue(KIT_MCUTARGET_COLORDEPTH_KEY, mcuTarget->colorDepth());
k->setValue(KIT_MCUTARGET_SDKVERSION_KEY, mcuTarget->qulVersion().toString());
k->setValue(KIT_MCUTARGET_KITVERSION_KEY, KIT_VERSION);
k->setValue(KIT_MCUTARGET_OS_KEY, static_cast<int>(mcuTarget->os()));
k->setValue(KIT_MCUTARGET_TOOCHAIN_KEY, mcuTarget->toolChainPackage()->toolChainName());
k->setAutoDetected(false);
k->makeSticky();
if (mcuTarget->toolChainPackage()->isDesktopToolchain())
k->setDeviceTypeForIcon(DEVICE_TYPE);
k->setValue(QtSupport::SuppliesQtQuickImportPath::id(), true);
k->setValue(QtSupport::KitQmlImportPath::id(), sdkPath.pathAppended("include/qul").toVariant());
k->setValue(QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(), true);
QSet<Id> irrelevant = {
SysRootKitAspect::id(),
QtSupport::SuppliesQtQuickImportPath::id(),
QtSupport::KitQmlImportPath::id(),
QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id(),
};
if (!kitNeedsQtVersion())
irrelevant.insert(QtSupport::QtKitAspect::id());
k->setIrrelevantAspects(irrelevant);
} }
void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems) void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
@@ -472,7 +164,6 @@ void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &en
CMakeConfigurationKitAspect::setConfiguration(kit, config); CMakeConfigurationKitAspect::setConfiguration(kit, config);
} }
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{ {
switch (tcPackage->type()) { switch (tcPackage->type()) {
@@ -569,15 +260,7 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
processPackage(package); processPackage(package);
processPackage(qtForMCUsSdkPackage); processPackage(qtForMCUsSdkPackage);
// Clang not needed in version 1.7+ if (McuSupportOptions::kitsNeedQtVersion())
if (mcuTarget->qulVersion() < QVersionNumber{1, 7}) {
const QString path = QLatin1String(HostOsInfo::isWindowsHost() ? "Path" : "PATH");
pathAdditions.append("${" + path + "}");
pathAdditions.append(Core::ICore::libexecPath("clang/bin").toUserOutput());
changes.append({path, pathAdditions.join(HostOsInfo::pathListSeparator())});
}
if (kitNeedsQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"}); changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});
// Hack, this problem should be solved in lower layer // Hack, this problem should be solved in lower layer
@@ -657,7 +340,7 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
if (!cMakeToolchainFile.exists()) { if (!cMakeToolchainFile.exists()) {
printMessage(McuTarget::tr( printMessage(McuTarget::tr(
"Warning for target %1: missing CMake toolchain file expected at %2.") "Warning for target %1: missing CMake toolchain file expected at %2.")
.arg(McuSupportOptions::kitName(mcuTarget), .arg(McuKitManager::kitName(mcuTarget),
cMakeToolchainFile.toUserOutput()), cMakeToolchainFile.toUserOutput()),
false); false);
} }
@@ -667,19 +350,16 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8())); config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8()));
if (!generatorsPath.exists()) { if (!generatorsPath.exists()) {
printMessage(McuTarget::tr("Warning for target %1: missing QulGenerators expected at %2.") printMessage(McuTarget::tr("Warning for target %1: missing QulGenerators expected at %2.")
.arg(McuSupportOptions::kitName(mcuTarget), generatorsPath.toUserOutput()), .arg(McuKitManager::kitName(mcuTarget), generatorsPath.toUserOutput()),
false); false);
} }
config.append(CMakeConfigItem("QUL_PLATFORM", mcuTarget->platform().name.toUtf8())); config.append(CMakeConfigItem("QUL_PLATFORM", mcuTarget->platform().name.toUtf8()));
if (mcuTarget->qulVersion() <= QVersionNumber{1, 3} // OS variable was removed in Qul 1.4
&& mcuTarget->os() == McuTarget::OS::FreeRTOS)
config.append(CMakeConfigItem("OS", "FreeRTOS"));
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth) if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH", config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1())); QString::number(mcuTarget->colorDepth()).toLatin1()));
if (kitNeedsQtVersion()) if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}")); config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
CMakeConfigurationKitAspect::setConfiguration(k, config); CMakeConfigurationKitAspect::setConfiguration(k, config);
@@ -695,134 +375,11 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
static void setKitQtVersionOptions(Kit *k) static void setKitQtVersionOptions(Kit *k)
{ {
if (!kitNeedsQtVersion()) if (!McuSupportOptions::kitsNeedQtVersion())
QtSupport::QtKitAspect::setQtVersion(k, nullptr); QtSupport::QtKitAspect::setQtVersion(k, nullptr);
// else: auto-select a Qt version // else: auto-select a Qt version
} }
QString McuSupportOptions::kitName(const McuTarget *mcuTarget)
{
QString os;
if (mcuTarget->qulVersion() <= QVersionNumber{1, 3}
&& mcuTarget->os() == McuTarget::OS::FreeRTOS)
// Starting from Qul 1.4 each OS is a separate platform
os = QLatin1String(" FreeRTOS");
const McuToolChainPackage *tcPkg = mcuTarget->toolChainPackage();
const QString compilerName = tcPkg && !tcPkg->isDesktopToolchain()
? QString::fromLatin1(" (%1)").arg(
tcPkg->toolChainName().toUpper())
: "";
const QString colorDepth = mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: "";
const QString targetName = mcuTarget->platform().displayName.isEmpty()
? mcuTarget->platform().name
: mcuTarget->platform().displayName;
return QString::fromLatin1("Qt for MCUs %1.%2 - %3%4%5%6")
.arg(QString::number(mcuTarget->qulVersion().majorVersion()),
QString::number(mcuTarget->qulVersion().minorVersion()),
targetName,
os,
colorDepth,
compilerName);
}
QList<Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTarget)
{
using namespace Constants;
return Utils::filtered(KitManager::kits(), [mcuTarget](Kit *kit) {
return kit->value(KIT_MCUTARGET_KITVERSION_KEY) == KIT_VERSION
&& (!mcuTarget
|| (kit->value(KIT_MCUTARGET_VENDOR_KEY) == mcuTarget->platform().vendor
&& kit->value(KIT_MCUTARGET_MODEL_KEY) == mcuTarget->platform().name
&& kit->value(KIT_MCUTARGET_COLORDEPTH_KEY) == mcuTarget->colorDepth()
&& kit->value(KIT_MCUTARGET_OS_KEY).toInt()
== static_cast<int>(mcuTarget->os())
&& kit->value(KIT_MCUTARGET_TOOCHAIN_KEY)
== mcuTarget->toolChainPackage()->toolChainName()));
});
}
QList<Kit *> McuSupportOptions::matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> McuSupportOptions::upgradeableKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
});
}
QList<Kit *> McuSupportOptions::kitsWithMismatchedDependencies(const McuTarget *mcuTarget)
{
return Utils::filtered(existingKits(mcuTarget), [mcuTarget](Kit *kit) {
const auto environment = Utils::NameValueDictionary(
Utils::NameValueItem::toStringList(EnvironmentKitAspect::environmentChanges(kit)));
return Utils::anyOf(mcuTarget->packages(), [&environment](const McuAbstractPackage *package) {
return !package->environmentVariableName().isEmpty() &&
environment.value(package->environmentVariableName()) != package->path().toUserOutput();
});
});
}
QList<Kit *> McuSupportOptions::outdatedKits()
{
return Utils::filtered(KitManager::kits(), [](Kit *kit) {
return !kit->value(Constants::KIT_MCUTARGET_VENDOR_KEY).isNull()
&& kit->value(Constants::KIT_MCUTARGET_KITVERSION_KEY) != KIT_VERSION;
});
}
void McuSupportOptions::removeOutdatedKits()
{
for (auto kit : McuSupportOptions::outdatedKits())
KitManager::deregisterKit(kit);
}
Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(kitName(mcuTarget), k, mcuTarget, qtForMCUsSdk->path());
setKitDevice(k, mcuTarget);
setKitToolchains(k, mcuTarget->toolChainPackage());
setKitDebugger(k, mcuTarget->toolChainPackage());
setKitEnvironment(k, mcuTarget, qtForMCUsSdk);
setKitDependencies(k, mcuTarget, qtForMCUsSdk);
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdk->path());
setKitQtVersionOptions(k);
k->setup();
k->fix();
};
return KitManager::registerKit(init);
}
void printMessage(const QString &message, bool important)
{
const QString displayMessage = QCoreApplication::translate("QtForMCUs", "Qt for MCUs: %1")
.arg(message);
if (important)
Core::MessageManager::writeFlashing(displayMessage);
else
Core::MessageManager::writeSilently(displayMessage);
}
QVersionNumber McuSupportOptions::kitQulVersion(const Kit *kit)
{
return QVersionNumber::fromString(
kit->value(McuSupport::Constants::KIT_MCUTARGET_SDKVERSION_KEY).toString());
}
static FilePath kitDependencyPath(const Kit *kit, const QString &variableName) static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
{ {
for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) { for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) {
@@ -832,21 +389,7 @@ static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
return FilePath(); return FilePath();
} }
bool McuSupportOptions::kitUpToDate(const Kit *kit, McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades()
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage)
{
return kitQulVersion(kit) == mcuTarget->qulVersion()
&& kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput()
== qtForMCUsSdkPackage->path().toUserOutput();
}
void McuSupportOptions::deletePackagesAndTargets()
{
sdkRepository.deletePackagesAndTargets();
}
McuSupportOptions::UpgradeOption McuSupportOptions::askForKitUpgrades()
{ {
QMessageBox upgradePopup(Core::ICore::dialogParent()); QMessageBox upgradePopup(Core::ICore::dialogParent());
upgradePopup.setStandardButtons(QMessageBox::Cancel); upgradePopup.setStandardButtons(QMessageBox::Cancel);
@@ -859,86 +402,17 @@ McuSupportOptions::UpgradeOption McuSupportOptions::askForKitUpgrades()
upgradePopup.exec(); upgradePopup.exec();
if (upgradePopup.clickedButton() == keepButton) if (upgradePopup.clickedButton() == keepButton)
return Keep; return McuKitManager::UpgradeOption::Keep;
if (upgradePopup.clickedButton() == replaceButton) if (upgradePopup.clickedButton() == replaceButton)
return Replace; return McuKitManager::UpgradeOption::Replace;
return Ignore; return McuKitManager::UpgradeOption::Ignore;
} }
void McuSupportOptions::createAutomaticKits() void McuSupportOptions::deletePackagesAndTargets()
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); sdkRepository.deletePackagesAndTargets();
const auto createKits = [qtForMCUsPackage]() {
if (qtForMCUsPackage->automaticKitCreationEnabled()) {
qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) {
case McuAbstractPackage::Status::ValidPathInvalidPackage: {
const QString displayPath = FilePath::fromString(qtForMCUsPackage->detectionPath())
.toUserOutput();
printMessage(tr("Path %1 exists, but does not contain %2.")
.arg(qtForMCUsPackage->path().toUserOutput(), displayPath),
true);
break;
}
case McuAbstractPackage::Status::InvalidPath: {
printMessage(tr("Path %1 does not exist. Add the path in Tools > Options > "
"Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()),
true);
break;
}
case McuAbstractPackage::Status::EmptyPath: {
printMessage(tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()),
true);
return;
}
default:
break;
}
return;
}
if (CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty()) {
printMessage(tr("No CMake tool was detected. Add a CMake tool in Tools > Options > "
"Kits > CMake."),
true);
return;
}
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
bool needsUpgrade = false;
for (const auto &target : qAsConst(repo.mcuTargets)) {
// if kit already exists, skip
if (!matchingKits(target, qtForMCUsPackage).empty())
continue;
if (!upgradeableKits(target, qtForMCUsPackage).empty()) {
// if kit exists but wrong version/path
needsUpgrade = true;
} else {
// if no kits for this target, create
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
if (needsUpgrade)
McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade();
}
};
createKits();
delete qtForMCUsPackage;
} }
void McuSupportOptions::checkUpgradeableKits() void McuSupportOptions::checkUpgradeableKits()
@@ -947,144 +421,44 @@ void McuSupportOptions::checkUpgradeableKits()
return; return;
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) { if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) {
return !upgradeableKits(target, this->qtForMCUsSdkPackage).empty() return !McuKitManager::upgradeableKits(target, this->qtForMCUsSdkPackage).empty()
&& matchingKits(target, this->qtForMCUsSdkPackage).empty(); && McuKitManager::matchingKits(target, this->qtForMCUsSdkPackage).empty();
})) }))
upgradeKits(askForKitUpgrades()); McuKitManager::upgradeKitsByCreatingNewPackage(askForKitUpgrades());
} }
void McuSupportOptions::upgradeKits(UpgradeOption upgradeOption) bool McuSupportOptions::kitsNeedQtVersion()
{ {
if (upgradeOption == Ignore) // Only on Windows, Qt is linked into the distributed qul Desktop libs. Also, the host tools
return; // are missing the Qt runtime libraries on non-Windows.
return !HostOsInfo::isWindowsHost();
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
auto dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (!matchingKits(target, qtForMCUsPackage).empty())
// already up-to-date
continue;
const auto kits = upgradeableKits(target, qtForMCUsPackage);
if (!kits.empty()) {
if (upgradeOption == Replace)
for (auto existingKit : kits)
KitManager::deregisterKit(existingKit);
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
} }
repo.deletePackagesAndTargets(); bool McuSupportOptions::automaticKitCreationEnabled() const
delete qtForMCUsPackage;
}
void McuSupportOptions::upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk)
{ {
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path()); return m_automaticKitCreation;
setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
} }
void McuSupportOptions::fixKitsDependencies() void McuSupportOptions::setAutomaticKitCreationEnabled(const bool enabled)
{ {
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage(); m_automaticKitCreation = enabled;
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets)) {
if (target->isValid()) {
for (auto* kit : kitsWithMismatchedDependencies(target)) {
updateKitEnvironment(kit, target);
}
}
} }
repo.deletePackagesAndTargets(); void McuSupportOptions::writeGeneralSettings() const
delete qtForMCUsPackage;
}
/**
* @brief Fix/update existing kits if needed
*/
void McuSupportOptions::fixExistingKits()
{ {
for (Kit *kit : KitManager::kits()) { const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY)) + QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
continue; QSettings *settings = Core::ICore::settings(QSettings::UserScope);
settings->setValue(key, m_automaticKitCreation);
if (kit->isAutoDetected()) {
kit->setAutoDetected(false);
} }
// Check if the MCU kits are flagged as supplying a QtQuick import path, in order bool McuSupportOptions::automaticKitCreationFromSettings()
// to tell the QMLJS code-model that it won't need to add a fall-back import {
// path. QSettings *settings = Core::ICore::settings(QSettings::UserScope);
const auto bringsQtQuickImportPath = QtSupport::SuppliesQtQuickImportPath::id(); const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
auto irrelevantAspects = kit->irrelevantAspects(); + QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
if (!irrelevantAspects.contains(bringsQtQuickImportPath)) { const bool automaticKitCreation = settings->value(key, true).toBool();
irrelevantAspects.insert(bringsQtQuickImportPath); return automaticKitCreation;
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(bringsQtQuickImportPath)) {
kit->setValue(bringsQtQuickImportPath, true);
}
// Check if the MCU kit supplies its import path.
const auto kitQmlImportPath = QtSupport::KitQmlImportPath::id();
if (!irrelevantAspects.contains(kitQmlImportPath)) {
irrelevantAspects.insert(kitQmlImportPath);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->hasValue(kitQmlImportPath)) {
auto config = CMakeProjectManager::CMakeConfigurationKitAspect::configuration(kit);
for (const auto &cfgItem : qAsConst(config)) {
if (cfgItem.key == "QUL_GENERATORS") {
auto idx = cfgItem.value.indexOf("/lib/cmake/Qul");
auto qulDir = cfgItem.value.left(idx);
kit->setValue(kitQmlImportPath, QVariant(qulDir + "/include/qul"));
break;
}
}
}
// Check if the MCU kit has the flag for merged header/qml-import paths set.
const auto mergedPaths = QtSupport::KitHasMergedHeaderPathsWithQmlImportPaths::id();
if (!irrelevantAspects.contains(mergedPaths)) {
irrelevantAspects.insert(mergedPaths);
kit->setIrrelevantAspects(irrelevantAspects);
}
if (!kit->value(mergedPaths, false).toBool()) {
kit->setValue(mergedPaths, true);
}
}
// Fix kit dependencies for known targets
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
qtForMCUsPackage->updateStatus();
if (qtForMCUsPackage->validStatus()) {
FilePath dir = qtForMCUsPackage->path();
McuSdkRepository repo;
Sdk::targetsAndPackages(dir, &repo);
for (const auto &target : qAsConst(repo.mcuTargets))
for (auto kit : existingKits(target)) {
if (McuDependenciesKitAspect::dependencies(kit).isEmpty()) {
setKitDependencies(kit, target, qtForMCUsPackage);
}
}
repo.deletePackagesAndTargets();
}
delete qtForMCUsPackage;
} }
} // namespace Internal } // namespace Internal

View File

@@ -26,6 +26,9 @@
#pragma once #pragma once
#include <utils/environmentfwd.h> #include <utils/environmentfwd.h>
#include "mcusupport_global.h"
#include "mcukitmanager.h"
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
#include <QVersionNumber> #include <QVersionNumber>
@@ -48,49 +51,7 @@ namespace Internal {
class McuAbstractPackage; class McuAbstractPackage;
class McuToolChainPackage; class McuToolChainPackage;
class McuTarget;
void printMessage(const QString &message, bool important);
class McuTarget : public QObject
{
Q_OBJECT
public:
enum class OS { Desktop, BareMetal, FreeRTOS };
struct Platform
{
QString name;
QString displayName;
QString vendor;
};
enum { UnspecifiedColorDepth = -1 };
McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const;
const QVector<McuAbstractPackage *> &packages() const;
const McuToolChainPackage *toolChainPackage() const;
const Platform &platform() const;
OS os() const;
int colorDepth() const;
bool isValid() const;
void printPackageProblems() const;
private:
const QVersionNumber m_qulVersion;
const Platform m_platform;
const OS m_os;
const QVector<McuAbstractPackage *> m_packages;
const McuToolChainPackage *m_toolChainPackage;
const int m_colorDepth;
}; // class McuTarget
class McuSdkRepository class McuSdkRepository
{ {
@@ -106,8 +67,6 @@ class McuSupportOptions : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum UpgradeOption { Ignore, Keep, Replace };
explicit McuSupportOptions(QObject *parent = nullptr); explicit McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override; ~McuSupportOptions() override;
@@ -115,47 +74,36 @@ public:
McuSdkRepository sdkRepository; McuSdkRepository sdkRepository;
void setQulDir(const Utils::FilePath &dir); void setQulDir(const Utils::FilePath &dir);
static void setKitEnvironment(ProjectExplorer::Kit *, const McuTarget *, const McuAbstractPackage *); static void setKitEnvironment(ProjectExplorer::Kit *,
const McuTarget *,
const McuAbstractPackage *);
static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *); static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *);
static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &); static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &);
static Utils::FilePath qulDirFromSettings(); static Utils::FilePath qulDirFromSettings();
static McuKitManager::UpgradeOption askForKitUpgrades();
static QString kitName(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> outdatedKits();
static void removeOutdatedKits();
static ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
static void createAutomaticKits();
static UpgradeOption askForKitUpgrades();
static void upgradeKits(UpgradeOption upgradeOption);
static void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk);
static void fixKitsDependencies();
void checkUpgradeableKits();
static void fixExistingKits();
void populatePackagesAndTargets();
static void registerQchFiles(); static void registerQchFiles();
static void registerExamples(); static void registerExamples();
static const QVersionNumber &minimalQulVersion(); static const QVersionNumber &minimalQulVersion();
static QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit); void checkUpgradeableKits();
static bool kitUpToDate(const ProjectExplorer::Kit *kit, void populatePackagesAndTargets();
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
static bool kitsNeedQtVersion();
bool automaticKitCreationEnabled() const;
void setAutomaticKitCreationEnabled(const bool enabled);
void writeGeneralSettings() const;
static bool automaticKitCreationFromSettings();
private: private:
void deletePackagesAndTargets(); void deletePackagesAndTargets();
bool m_automaticKitCreation = true;
signals: signals:
void changed(); void packagesChanged();
}; };
} // namespace Internal } // namespace Internal
} // namespace McuSupport } // namespace McuSupport

View File

@@ -24,10 +24,12 @@
****************************************************************************/ ****************************************************************************/
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcukitmanager.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcutarget.h"
#include <cmakeprojectmanager/cmakeprojectconstants.h> #include <cmakeprojectmanager/cmakeprojectconstants.h>
#include <cmakeprojectmanager/cmaketoolmanager.h> #include <cmakeprojectmanager/cmaketoolmanager.h>
@@ -121,8 +123,10 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
&QComboBox::currentTextChanged, &QComboBox::currentTextChanged,
this, this,
&McuSupportOptionsWidget::showMcuTargetPackages); &McuSupportOptionsWidget::showMcuTargetPackages);
connect(m_options.qtForMCUsSdkPackage, &McuAbstractPackage::changed, connect(m_options.qtForMCUsSdkPackage,
this, &McuSupportOptionsWidget::populateMcuTargetsComboBox); &McuAbstractPackage::changed,
this,
&McuSupportOptionsWidget::populateMcuTargetsComboBox);
} }
{ {
@@ -142,7 +146,7 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
m_kitAutomaticCreationCheckBox = new QCheckBox( m_kitAutomaticCreationCheckBox = new QCheckBox(
tr("Automatically create kits for all available targets on start")); tr("Automatically create kits for all available targets on start"));
connect(m_kitAutomaticCreationCheckBox, &QCheckBox::stateChanged, this, [this](int state) { connect(m_kitAutomaticCreationCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
m_options.qtForMCUsSdkPackage->setAutomaticKitCreationEnabled( m_options.setAutomaticKitCreationEnabled(
state == Qt::CheckState::Checked); state == Qt::CheckState::Checked);
}); });
mainLayout->addWidget(m_kitAutomaticCreationCheckBox); mainLayout->addWidget(m_kitAutomaticCreationCheckBox);
@@ -158,16 +162,16 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
m_kitCreationPushButton = new QPushButton(tr("Create Kit")); m_kitCreationPushButton = new QPushButton(tr("Create Kit"));
m_kitCreationPushButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_kitCreationPushButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
connect(m_kitCreationPushButton, &QPushButton::clicked, this, [this] { connect(m_kitCreationPushButton, &QPushButton::clicked, this, [this] {
McuSupportOptions::newKit(currentMcuTarget(), m_options.qtForMCUsSdkPackage); McuKitManager::newKit(currentMcuTarget(), m_options.qtForMCUsSdkPackage);
McuSupportOptions::registerQchFiles(); McuSupportOptions::registerQchFiles();
updateStatus(); updateStatus();
}); });
m_kitUpdatePushButton = new QPushButton(tr("Update Kit")); m_kitUpdatePushButton = new QPushButton(tr("Update Kit"));
m_kitUpdatePushButton->setSizePolicy(m_kitCreationPushButton->sizePolicy()); m_kitUpdatePushButton->setSizePolicy(m_kitCreationPushButton->sizePolicy());
connect(m_kitUpdatePushButton, &QPushButton::clicked, this, [this] { connect(m_kitUpdatePushButton, &QPushButton::clicked, this, [this] {
for (auto kit : McuSupportOptions::upgradeableKits(currentMcuTarget(), for (auto kit :
m_options.qtForMCUsSdkPackage)) McuKitManager::upgradeableKits(currentMcuTarget(), m_options.qtForMCUsSdkPackage))
m_options.upgradeKitInPlace(kit, currentMcuTarget(), m_options.qtForMCUsSdkPackage); McuKitManager::upgradeKitInPlace(kit, currentMcuTarget(), m_options.qtForMCUsSdkPackage);
updateStatus(); updateStatus();
}); });
vLayout->addWidget(m_kitCreationPushButton); vLayout->addWidget(m_kitCreationPushButton);
@@ -176,7 +180,10 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
mainLayout->addStretch(); mainLayout->addStretch();
connect(&m_options, &McuSupportOptions::changed, this, &McuSupportOptionsWidget::updateStatus); connect(&m_options,
&McuSupportOptions::packagesChanged,
this,
&McuSupportOptionsWidget::updateStatus);
showMcuTargetPackages(); showMcuTargetPackages();
} }
@@ -215,12 +222,10 @@ void McuSupportOptionsWidget::updateStatus()
m_kitUpdatePushButton->setVisible(mcuTargetValid); m_kitUpdatePushButton->setVisible(mcuTargetValid);
if (mcuTargetValid) { if (mcuTargetValid) {
const bool hasMatchingKits const bool hasMatchingKits
= !McuSupportOptions::matchingKits(mcuTarget, m_options.qtForMCUsSdkPackage) = !McuKitManager::matchingKits(mcuTarget, m_options.qtForMCUsSdkPackage).isEmpty();
.isEmpty(); const bool hasUpgradeableKits = !hasMatchingKits &&
const bool hasUpgradeableKits !McuKitManager::upgradeableKits(
= !hasMatchingKits mcuTarget, m_options.qtForMCUsSdkPackage).isEmpty();
&& !McuSupportOptions::upgradeableKits(mcuTarget, m_options.qtForMCUsSdkPackage)
.isEmpty();
m_kitCreationPushButton->setEnabled(!hasMatchingKits); m_kitCreationPushButton->setEnabled(!hasMatchingKits);
m_kitUpdatePushButton->setEnabled(hasUpgradeableKits); m_kitUpdatePushButton->setEnabled(hasUpgradeableKits);
@@ -241,8 +246,7 @@ void McuSupportOptionsWidget::updateStatus()
} }
// Automatic Kit creation // Automatic Kit creation
m_kitAutomaticCreationCheckBox->setChecked( m_kitAutomaticCreationCheckBox->setChecked(m_options.automaticKitCreationEnabled());
m_options.qtForMCUsSdkPackage->automaticKitCreationEnabled());
// Status label in the bottom // Status label in the bottom
{ {
@@ -296,14 +300,14 @@ void McuSupportOptionsWidget::apply()
{ {
bool pathsChanged = false; bool pathsChanged = false;
m_options.qtForMCUsSdkPackage->writeGeneralSettings(); m_options.writeGeneralSettings();
pathsChanged |= m_options.qtForMCUsSdkPackage->writeToSettings(); pathsChanged |= m_options.qtForMCUsSdkPackage->writeToSettings();
for (auto package : qAsConst(m_options.sdkRepository.packages)) for (auto package : qAsConst(m_options.sdkRepository.packages))
pathsChanged |= package->writeToSettings(); pathsChanged |= package->writeToSettings();
if (pathsChanged) { if (pathsChanged) {
m_options.checkUpgradeableKits(); m_options.checkUpgradeableKits();
m_options.fixKitsDependencies(); McuKitManager::fixKitsDependencies();
} }
} }
@@ -313,7 +317,7 @@ void McuSupportOptionsWidget::populateMcuTargetsComboBox()
m_mcuTargetsComboBox->clear(); m_mcuTargetsComboBox->clear();
m_mcuTargetsComboBox->addItems( m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets, Utils::transform<QStringList>(m_options.sdkRepository.mcuTargets,
[](McuTarget *t) { return McuSupportOptions::kitName(t); })); [](McuTarget *t) { return McuKitManager::kitName(t); }));
updateStatus(); updateStatus();
} }

View File

@@ -28,6 +28,7 @@
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportdevice.h" #include "mcusupportdevice.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcukitmanager.h"
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcusupportrunconfiguration.h" #include "mcusupportrunconfiguration.h"
@@ -38,6 +39,7 @@
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/jsonwizard/jsonwizardfactory.h> #include <projectexplorer/jsonwizard/jsonwizardfactory.h>
@@ -53,6 +55,16 @@ using namespace ProjectExplorer;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
void printMessage(const QString &message, bool important)
{
const QString displayMessage = QCoreApplication::translate("QtForMCUs", "Qt for MCUs: %1")
.arg(message);
if (important)
Core::MessageManager::writeFlashing(displayMessage);
else
Core::MessageManager::writeSilently(displayMessage);
}
class McuSupportPluginPrivate class McuSupportPluginPrivate
{ {
public: public:
@@ -93,9 +105,9 @@ void McuSupportPlugin::extensionsInitialized()
ProjectExplorer::DeviceManager::instance()->addDevice(McuSupportDevice::create()); ProjectExplorer::DeviceManager::instance()->addDevice(McuSupportDevice::create());
connect(KitManager::instance(), &KitManager::kitsLoaded, []() { connect(KitManager::instance(), &KitManager::kitsLoaded, []() {
McuSupportOptions::removeOutdatedKits(); McuKitManager::removeOutdatedKits();
McuSupportOptions::createAutomaticKits(); McuKitManager::createAutomaticKits();
McuSupportOptions::fixExistingKits(); McuKitManager::fixExistingKits();
McuSupportPlugin::askUserAboutMcuSupportKitsSetup(); McuSupportPlugin::askUserAboutMcuSupportKitsSetup();
}); });
} }
@@ -106,7 +118,7 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsSetup()
if (!ICore::infoBar()->canInfoBeAdded(setupMcuSupportKits) if (!ICore::infoBar()->canInfoBeAdded(setupMcuSupportKits)
|| McuSupportOptions::qulDirFromSettings().isEmpty() || McuSupportOptions::qulDirFromSettings().isEmpty()
|| !McuSupportOptions::existingKits(nullptr).isEmpty()) || !McuKitManager::existingKits(nullptr).isEmpty())
return; return;
Utils::InfoBarEntry info(setupMcuSupportKits, Utils::InfoBarEntry info(setupMcuSupportKits,
@@ -130,18 +142,19 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade()
Utils::InfoBarEntry info(upgradeMcuSupportKits, Utils::InfoBarEntry info(upgradeMcuSupportKits,
tr("New version of Qt for MCUs detected. Upgrade existing Kits?"), tr("New version of Qt for MCUs detected. Upgrade existing Kits?"),
Utils::InfoBarEntry::GlobalSuppression::Enabled); Utils::InfoBarEntry::GlobalSuppression::Enabled);
static McuKitManager::UpgradeOption selectedOption = McuKitManager::UpgradeOption::Keep;
static McuSupportOptions::UpgradeOption selectedOption;
const QStringList options = {tr("Create new kits"), tr("Replace existing kits")}; const QStringList options = {tr("Create new kits"), tr("Replace existing kits")};
selectedOption = McuSupportOptions::UpgradeOption::Keep;
info.setComboInfo(options, [options](const QString &selected) { info.setComboInfo(options, [options](const QString &selected) {
selectedOption = options.indexOf(selected) == 0 ? McuSupportOptions::UpgradeOption::Keep selectedOption = options.indexOf(selected) == 0 ? McuKitManager::UpgradeOption::Keep
: McuSupportOptions::UpgradeOption::Replace; : McuKitManager::UpgradeOption::Replace;
}); });
info.addCustomButton(tr("Proceed"), [upgradeMcuSupportKits] { info.addCustomButton(tr("Proceed"), [upgradeMcuSupportKits] {
ICore::infoBar()->removeInfo(upgradeMcuSupportKits); ICore::infoBar()->removeInfo(upgradeMcuSupportKits);
QTimer::singleShot(0, []() { McuSupportOptions::upgradeKits(selectedOption); }); QTimer::singleShot(0, []() {
McuKitManager::upgradeKitsByCreatingNewPackage(selectedOption);
});
}); });
ICore::infoBar()->addInfo(info); ICore::infoBar()->addInfo(info);

View File

@@ -31,6 +31,8 @@
namespace McuSupport::Internal { namespace McuSupport::Internal {
void printMessage(const QString &message, bool important);
class McuSupportPlugin final : public ExtensionSystem::IPlugin class McuSupportPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT

View File

@@ -24,10 +24,13 @@
****************************************************************************/ ****************************************************************************/
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcukitmanager.h"
#include "mcupackage.h" #include "mcupackage.h"
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportplugin.h"
#include "mcusupportversiondetection.h" #include "mcusupportversiondetection.h"
#include "mcutarget.h"
#include "mcutargetdescription.h" #include "mcutargetdescription.h"
#include <baremetal/baremetalconstants.h> #include <baremetal/baremetalconstants.h>
@@ -527,10 +530,9 @@ protected:
QVector<McuTarget *> mcuTargets; QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id); McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id);
if (tcPkg) { if (tcPkg)
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1, 8}))
tcPkg->setVersions(desc.toolchain.versions); tcPkg->setVersions(desc.toolchain.versions);
} else else
tcPkg = createUnsupportedToolChainPackage(); tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.platform.colorDepths) { for (int colorDepth : desc.platform.colorDepths) {
QVector<McuAbstractPackage *> required3rdPartyPkgs; QVector<McuAbstractPackage *> required3rdPartyPkgs;
@@ -551,7 +553,6 @@ protected:
boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg); boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg);
} }
auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdk.envVar); auto boardSdkPkg = boardSdkPkgs.value(desc.boardSdk.envVar);
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1, 8}))
boardSdkPkg->setVersions(desc.boardSdk.versions); boardSdkPkg->setVersions(desc.boardSdk.versions);
boardSdkDefaultPath = boardSdkPkg->defaultPath(); boardSdkDefaultPath = boardSdkPkg->defaultPath();
required3rdPartyPkgs.append(boardSdkPkg); required3rdPartyPkgs.append(boardSdkPkg);
@@ -641,9 +642,12 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)
return kitsDir.entryInfoList(); return kitsDir.entryInfoList();
} }
static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion, McuTargetDescription parseDescriptionJson(const QByteArray &data)
const QJsonObject &target)
{ {
const QJsonDocument document = QJsonDocument::fromJson(data);
const QJsonObject target = document.object();
const QString qulVersion = target.value("qulVersion").toString();
const QJsonObject platform = target.value("platform").toObject();
const QString compatVersion = target.value("compatVersion").toString(); const QString compatVersion = target.value("compatVersion").toString();
const QJsonObject toolchain = target.value("toolchain").toObject(); const QJsonObject toolchain = target.value("toolchain").toObject();
const QJsonObject boardSdk = target.value("boardSdk").toObject(); const QJsonObject boardSdk = target.value("boardSdk").toObject();
@@ -660,9 +664,23 @@ static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion
return version.toString(); return version.toString();
}); });
const QVariantList colorDepths = platform.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int>>(colorDepths,
[&](const QVariant &colorDepth) {
return colorDepth.toInt();
});
const QString platformName = platform.value("platformName").toString();
return {qulVersion, return {qulVersion,
compatVersion, compatVersion,
{}, {
platform.value("id").toString(),
platformName,
platform.value("vendor").toString(),
colorDepthsVector,
platformName == "Desktop" ? McuTargetDescription::TargetType::Desktop
: McuTargetDescription::TargetType::MCU,
},
{ {
toolchain.value("id").toString(), toolchain.value("id").toString(),
toolchainVersionsList, toolchainVersionsList,
@@ -679,86 +697,36 @@ static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion
}}; }};
} }
static McuTargetDescription parseDescriptionJsonV1x(const QString &qulVersion,
const QJsonObject &target)
{
auto description = parseDescriptionJsonCommon(qulVersion, target);
const QVariantList colorDepths = target.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int>>(colorDepths,
[&](const QVariant &colorDepth) {
return colorDepth.toInt();
});
description.platform = {target.value("platform").toString(),
target.value("platformName").toString(),
target.value("platformVendor").toString(),
colorDepthsVector,
description.boardSdk.envVar.isEmpty()
? McuTargetDescription::TargetType::Desktop
: McuTargetDescription::TargetType::MCU};
return description;
}
static McuTargetDescription parseDescriptionJsonV2x(const QString &qulVersion,
const QJsonObject &target)
{
const QJsonObject platform = target.value("platform").toObject();
const QVariantList colorDepths = platform.value("colorDepths").toArray().toVariantList();
const auto colorDepthsVector = Utils::transform<QVector<int>>(colorDepths,
[&](const QVariant &colorDepth) {
return colorDepth.toInt();
});
const QString platformName = platform.value("platformName").toString();
McuTargetDescription description = parseDescriptionJsonCommon(qulVersion, target);
description.platform = {
platform.value("id").toString(),
platformName,
platform.value("vendor").toString(),
colorDepthsVector,
platformName == "Desktop" ? McuTargetDescription::TargetType::Desktop
: McuTargetDescription::TargetType::MCU,
};
return description;
}
McuTargetDescription parseDescriptionJson(const QByteArray &data)
{
const QJsonDocument document = QJsonDocument::fromJson(data);
const QJsonObject target = document.object();
const QString qulVersion = target.value("qulVersion").toString();
switch (QVersionNumber::fromString(qulVersion).majorVersion()) {
case 1:
return parseDescriptionJsonV1x(qulVersion, target);
case 2:
return parseDescriptionJsonV2x(qulVersion, target);
default:
return {qulVersion};
}
}
// https://doc.qt.io/qtcreator/creator-developing-mcu.html#supported-qt-for-mcus-sdks // https://doc.qt.io/qtcreator/creator-developing-mcu.html#supported-qt-for-mcus-sdks
const QHash<QString, QString> oldSdkQtcRequiredVersion = { static const QString legacySupportVersionFor(const QString &sdkVersion)
{
static const QHash<QString, QString> oldSdkQtcRequiredVersion = {
{{"1.0"}, {"4.11.x"}}, {{"1.0"}, {"4.11.x"}},
{{"1.1"}, {"4.12.0 or 4.12.1"}}, {{"1.1"}, {"4.12.0 or 4.12.1"}},
{{"1.2"}, {"4.12.2 or 4.12.3"}}, {{"1.2"}, {"4.12.2 or 4.12.3"}}
}; };
if (oldSdkQtcRequiredVersion.contains(sdkVersion))
return oldSdkQtcRequiredVersion.value(sdkVersion);
if (QVersionNumber::fromString(sdkVersion).majorVersion() == 1)
return "4.12.4 up to 6.0";
return QString();
}
bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message) bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message)
{ {
const McuPackagePathVersionDetector versionDetector("(?<=\\bQtMCUs.)(\\d+\\.\\d+)"); const McuPackagePathVersionDetector versionDetector("(?<=\\bQtMCUs.)(\\d+\\.\\d+)");
const QString sdkDetectedVersion = versionDetector.parseVersion(qulDir.toString()); const QString sdkDetectedVersion = versionDetector.parseVersion(qulDir.toString());
const QString legacyVersion = legacySupportVersionFor(sdkDetectedVersion);
if (oldSdkQtcRequiredVersion.contains(sdkDetectedVersion)) { if (!legacyVersion.isEmpty()) {
message = McuTarget::tr("Qt for MCUs SDK version %1 detected, " message = McuTarget::tr("Qt for MCUs SDK version %1 detected, "
"only supported by Qt Creator version %2. " "only supported by Qt Creator version %2. "
"This version of Qt Creator requires Qt for MCUs %3 or greater.") "This version of Qt Creator requires Qt for MCUs %3 or greater.")
.arg(sdkDetectedVersion, .arg(sdkDetectedVersion,
oldSdkQtcRequiredVersion.value(sdkDetectedVersion), legacyVersion,
McuSupportOptions::minimalQulVersion().toString()); McuSupportOptions::minimalQulVersion().toString());
return true; return true;
} }
@@ -787,10 +755,11 @@ void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
continue; continue;
} }
if (QVersionNumber::fromString(desc.qulVersion) < McuSupportOptions::minimalQulVersion()) { if (QVersionNumber::fromString(desc.qulVersion) < McuSupportOptions::minimalQulVersion()) {
const QString legacyVersion = legacySupportVersionFor(desc.qulVersion);
const QString qtcSupportText const QString qtcSupportText
= oldSdkQtcRequiredVersion.contains(desc.qulVersion) = !legacyVersion.isEmpty()
? McuTarget::tr("Detected version \"%1\", only supported by Qt Creator %2.") ? McuTarget::tr("Detected version \"%1\", only supported by Qt Creator %2.")
.arg(desc.qulVersion, oldSdkQtcRequiredVersion.value(desc.qulVersion)) .arg(desc.qulVersion, legacyVersion)
: McuTarget::tr("Unsupported version \"%1\".").arg(desc.qulVersion); : McuTarget::tr("Unsupported version \"%1\".").arg(desc.qulVersion);
printMessage(McuTarget::tr("Skipped %1. %2 Qt for MCUs version >= %3 required.") printMessage(McuTarget::tr("Skipped %1. %2 Qt for MCUs version >= %3 required.")
.arg(QDir::toNativeSeparators(pth.fileNameWithPathComponents(1)), .arg(QDir::toNativeSeparators(pth.fileNameWithPathComponents(1)),
@@ -818,68 +787,13 @@ void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
} }
} }
// Workaround for missing JSON file for Desktop target.
// Desktop JSON file is shipped starting from Qul 1.5.
// This whole section could be removed when minimalQulVersion will reach 1.5 or above
{
const bool hasDesktopDescription
= contains(descriptions, [](const McuTargetDescription &desc) {
return desc.platform.type == McuTargetDescription::TargetType::Desktop;
});
if (!hasDesktopDescription) {
QVector<FilePath> desktopLibs;
if (HostOsInfo::isWindowsHost()) {
desktopLibs << dir / "lib/QulQuickUltralite_QT_32bpp_Windows_Release.lib"; // older versions of QUL (<1.5?)
desktopLibs
<< dir / "lib/QulQuickUltralitePlatform_QT_32bpp_Windows_msvc_Release.lib"; // newer versions of QUL
} else {
desktopLibs << dir / "lib/libQulQuickUltralite_QT_32bpp_Linux_Debug.a"; // older versions of QUL (<1.5?)
desktopLibs << dir / "lib/libQulQuickUltralitePlatform_QT_32bpp_Linux_gnu_Debug.a"; // newer versions of QUL
}
if (anyOf(desktopLibs, [](const FilePath &desktopLib) { return desktopLib.exists(); })) {
McuTargetDescription desktopDescription;
desktopDescription.qulVersion
= descriptions.empty() ? McuSupportOptions::minimalQulVersion().toString()
: descriptions.first().qulVersion;
desktopDescription.platform.id = "Qt";
desktopDescription.platform.name = "Desktop";
desktopDescription.platform.vendor = "Qt";
desktopDescription.platform.colorDepths = {32};
desktopDescription.toolchain.id = HostOsInfo::isWindowsHost() ? QString("msvc")
: QString("gcc");
desktopDescription.platform.type = McuTargetDescription::TargetType::Desktop;
descriptions.prepend(desktopDescription);
} else {
// show error only on 1.x SDKs, but skip on 2.x
const FilePath desktopLibV2
= HostOsInfo::isWindowsHost()
? dir / "lib/QulPlatform_qt_32bpp_Windows_msvc_Release.lib"
: dir / "lib/libQulPlatform_qt_32bpp_Linux_gnu_Release.a";
if (dir.exists() && !desktopLibV2.exists())
printMessage(
McuTarget::tr(
"Skipped creating fallback desktop kit: Could not find any of %1.")
.arg(transform(desktopLibs,
[](const auto &path) {
return QDir::toNativeSeparators(
path.fileNameWithPathComponents(1));
})
.toList()
.join(" or ")),
false);
}
}
}
repo->mcuTargets.append(targetsFromDescriptions(descriptions, &(repo->packages))); repo->mcuTargets.append(targetsFromDescriptions(descriptions, &(repo->packages)));
// Keep targets sorted lexicographically // Keep targets sorted lexicographically
std::sort(repo->mcuTargets.begin(), std::sort(repo->mcuTargets.begin(),
repo->mcuTargets.end(), repo->mcuTargets.end(),
[](const McuTarget *lhs, const McuTarget *rhs) { [](const McuTarget *lhs, const McuTarget *rhs) {
return McuSupportOptions::kitName(lhs) < McuSupportOptions::kitName(rhs); return McuKitManager::kitName(lhs) < McuKitManager::kitName(rhs);
}); });
} }

View File

@@ -51,13 +51,14 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message);
void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo); void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo);
McuTargetDescription parseDescriptionJson(const QByteArray &); McuTargetDescription parseDescriptionJson(const QByteArray &);
QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescription> &, QVector<McuAbstractPackage *> *); QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescription> &,
QVector<McuAbstractPackage *> *);
Utils::FilePath kitsPath(const Utils::FilePath &dir); Utils::FilePath kitsPath(const Utils::FilePath &dir);
Utils::FilePath packagePathFromSettings(const QString &settingsKey, Utils::FilePath packagePathFromSettings(const QString &settingsKey,
QSettings::Scope scope = QSettings::UserScope, QSettings::Scope scope,
const Utils::FilePath &defaultPath = {}); const Utils::FilePath &defaultPath);
} // namespace Sdk } // namespace Sdk
} // namespace Internal } // namespace Internal
} // namespace McuSupport } // namespace McuSupport

View File

@@ -0,0 +1,290 @@
/****************************************************************************
**
** Copyright (C) 2022 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 "mcutarget.h"
#include "mcupackage.h"
#include "mcukitmanager.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace McuSupport::Internal {
static ToolChain *msvcToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor
|| abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
&& abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64
&& t->language() == language;
});
return toolChain;
}
static ToolChain *gccToolChain(Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi();
return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture
&& abi.wordWidth() == 64 && t->language() == language;
});
return toolChain;
}
static ToolChain *armGccToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) {
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain *> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static ToolChain *iarToolChain(const FilePath &path, Id language)
{
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID
&& t->language() == language;
});
if (!toolChain) {
ToolChainFactory *iarFactory
= Utils::findOrDefault(ToolChainFactory::allToolChainFactories(),
[](ToolChainFactory *f) {
return f->supportedToolChainType()
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (iarFactory) {
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language});
for (auto tc : detected) {
if (tc->language() == language) {
toolChain = tc;
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("IAREW");
ToolChainManager::registerToolChain(toolChain);
}
}
}
}
return toolChain;
}
ToolChain *McuToolChainPackage::toolChain(Id language) const
{
switch (m_type) {
case Type::MSVC:
return msvcToolChain(language);
case Type::GCC:
return gccToolChain(language);
case Type::IAR: {
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
return iarToolChain(compiler, language);
}
case Type::ArmGcc:
case Type::KEIL:
case Type::GHS:
case Type::GHSArm:
case Type::Unsupported: {
const QLatin1String compilerName(
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
const QString comp = QLatin1String(m_type == Type::ArmGcc ? "/bin/arm-none-eabi-%1"
: "/bar/foo-keil-%1")
.arg(compilerName);
const FilePath compiler = path().pathAppended(comp).withExecutableSuffix();
return armGccToolChain(compiler, language);
}
default:
Q_UNREACHABLE();
}
}
QString McuToolChainPackage::toolChainName() const
{
switch (m_type) {
case Type::ArmGcc:
return QLatin1String("armgcc");
case Type::IAR:
return QLatin1String("iar");
case Type::KEIL:
return QLatin1String("keil");
case Type::GHS:
return QLatin1String("ghs");
case Type::GHSArm:
return QLatin1String("ghs-arm");
default:
return QLatin1String("unsupported");
}
}
QString McuToolChainPackage::cmakeToolChainFileName() const
{
return toolChainName() + QLatin1String(".cmake");
}
QVariant McuToolChainPackage::debuggerId() const
{
using namespace Debugger;
QString sub, displayName;
DebuggerEngineType engineType;
switch (m_type) {
case Type::ArmGcc: {
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
displayName = McuPackage::tr("Arm GDB at %1");
engineType = Debugger::GdbEngineType;
break;
}
case Type::IAR: {
sub = QString::fromLatin1("../common/bin/CSpyBat");
displayName = QLatin1String("CSpy");
engineType = Debugger::NoEngineType; // support for IAR missing
break;
}
case Type::KEIL: {
sub = QString::fromLatin1("UV4/UV4");
displayName = QLatin1String("KEIL uVision Debugger");
engineType = Debugger::UvscEngineType;
break;
}
default:
return QVariant();
}
const FilePath command = path().pathAppended(sub).withExecutableSuffix();
if (const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command)) {
return debugger->id();
}
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(displayName.arg(command.toUserOutput()));
newDebugger.setEngineType(engineType);
return DebuggerItemManager::registerDebugger(newDebugger);
}
McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth)
: m_qulVersion(qulVersion)
, m_platform(platform)
, m_os(os)
, m_packages(packages)
, m_toolChainPackage(toolChainPackage)
, m_colorDepth(colorDepth)
{}
const QVector<McuAbstractPackage *> &McuTarget::packages() const
{
return m_packages;
}
const McuToolChainPackage *McuTarget::toolChainPackage() const
{
return m_toolChainPackage;
}
McuTarget::OS McuTarget::os() const
{
return m_os;
}
const McuTarget::Platform &McuTarget::platform() const
{
return m_platform;
}
bool McuTarget::isValid() const
{
return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus();
return package->validStatus();
});
}
void McuTarget::printPackageProblems() const
{
for (auto package : packages()) {
package->updateStatus();
if (!package->validStatus())
printMessage(tr("Error creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
true);
if (package->status() == McuAbstractPackage::Status::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3")
.arg(McuKitManager::kitName(this),
package->label(),
package->statusText()),
false);
}
}
const QVersionNumber &McuTarget::qulVersion() const
{
return m_qulVersion;
}
int McuTarget::colorDepth() const
{
return m_colorDepth;
}
} // namespace McuSupport::Internal

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** Copyright (C) 2022 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 <QObject>
#include <QVersionNumber>
namespace ProjectExplorer {
class ToolChain;
}
namespace Utils {
class PathChooser;
class InfoLabel;
} // namespace Utils
namespace McuSupport {
namespace Internal {
class McuAbstractPackage;
class McuToolChainPackage;
class McuTarget : public QObject
{
Q_OBJECT
public:
enum class OS { Desktop, BareMetal, FreeRTOS };
struct Platform
{
QString name;
QString displayName;
QString vendor;
};
enum { UnspecifiedColorDepth = -1 };
McuTarget(const QVersionNumber &qulVersion,
const Platform &platform,
OS os,
const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage,
int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const;
const QVector<McuAbstractPackage *> &packages() const;
const McuToolChainPackage *toolChainPackage() const;
const Platform &platform() const;
OS os() const;
int colorDepth() const;
bool isValid() const;
void printPackageProblems() const;
private:
const QVersionNumber m_qulVersion;
const Platform m_platform;
const OS m_os;
const QVector<McuAbstractPackage *> m_packages;
const McuToolChainPackage *m_toolChainPackage;
const int m_colorDepth;
}; // class McuTarget
} // namespace Internal
} // namespace McuSupport

View File

@@ -27,8 +27,8 @@
#include "mcuabstractpackage.h" #include "mcuabstractpackage.h"
#include <utils/filepath.h>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <utils/filepath.h>
namespace McuSupport::Internal { namespace McuSupport::Internal {
@@ -45,19 +45,13 @@ public:
MOCK_METHOD(Status, status, (), (const)); MOCK_METHOD(Status, status, (), (const));
MOCK_METHOD(bool, validStatus, (), (const)); MOCK_METHOD(bool, validStatus, (), (const));
MOCK_METHOD(void, setDownloadUrl, (const QString &) );
MOCK_METHOD(void, setEnvironmentVariableName, (const QString &) );
MOCK_METHOD(const QString &, environmentVariableName, (), (const)); MOCK_METHOD(const QString &, environmentVariableName, (), (const));
MOCK_METHOD(void, setAddToPath, (bool) ); MOCK_METHOD(void, setAddToPath, (bool) );
MOCK_METHOD(bool, addToPath, (), (const)); MOCK_METHOD(bool, addToPath, (), (const));
MOCK_METHOD(void, writeGeneralSettings, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const)); MOCK_METHOD(bool, writeToSettings, (), (const));
MOCK_METHOD(void, setRelativePathModifier, (const QString &) ); MOCK_METHOD(void, setRelativePathModifier, (const QString &) );
MOCK_METHOD(void, setVersions, (const QStringList &) ); MOCK_METHOD(void, setVersions, (const QStringList &) );
MOCK_METHOD(bool, automaticKitCreationEnabled, (), (const));
MOCK_METHOD(void, setAutomaticKitCreationEnabled, (const bool enabled));
MOCK_METHOD(QWidget *, widget, ()); MOCK_METHOD(QWidget *, widget, ());
}; // class PackageMock }; // class PackageMock
} // namespace McuSupport::Internal } // namespace McuSupport::Internal

View File

@@ -23,9 +23,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "mcutargetdescription.h"
#include "nxp_1064_json.h"
#include "unittest.h" #include "unittest.h"
#include "mcutargetdescription.h"
#include "mcukitmanager.h"
#include "nxp_1064_json.h"
#include "utils/filepath.h" #include "utils/filepath.h"
#include <cmakeprojectmanager/cmakeconfigitem.h> #include <cmakeprojectmanager/cmakeconfigitem.h>
#include <cmakeprojectmanager/cmakekitinformation.h> #include <cmakeprojectmanager/cmakekitinformation.h>
@@ -55,7 +56,7 @@ void McuSupportTest::test_parseBasicInfoFromJson()
{ {
const auto description = Sdk::parseDescriptionJson(nxp_1064_json); const auto description = Sdk::parseDescriptionJson(nxp_1064_json);
QVERIFY(not description.freeRTOS.envVar.isEmpty()); QVERIFY(!description.freeRTOS.envVar.isEmpty());
QVERIFY(description.freeRTOS.boardSdkSubDir.isEmpty()); QVERIFY(description.freeRTOS.boardSdkSubDir.isEmpty());
} }
@@ -65,7 +66,7 @@ void McuSupportTest::test_addNewKit()
QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded); QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded);
auto *newKit{McuSupportOptions::newKit(&mcuTarget, &freeRtosPackage)}; auto *newKit{McuKitManager::newKit(&mcuTarget, &freeRtosPackage)};
QVERIFY(newKit != nullptr); QVERIFY(newKit != nullptr);
QCOMPARE(kitAddedSpy.count(), 1); QCOMPARE(kitAddedSpy.count(), 1);
@@ -85,13 +86,13 @@ void McuSupportTest::test_addFreeRtosCmakeVarToKit()
QVERIFY(kit.hasValue(EnvironmentKitAspect::id())); QVERIFY(kit.hasValue(EnvironmentKitAspect::id()));
QVERIFY(kit.isValid()); QVERIFY(kit.isValid());
QVERIFY(not kit.allKeys().empty()); QVERIFY(!kit.allKeys().empty());
const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)}; const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)};
QCOMPARE(cmakeConfig.size(), 1); QCOMPARE(cmakeConfig.size(), 1);
CMakeConfigItem expectedCmakeVar{freeRtosCmakeVar.toLocal8Bit(), CMakeConfigItem expectedCmakeVar{freeRtosCmakeVar.toLocal8Bit(),
defaultfreeRtosPath.toLocal8Bit()}; FilePath::fromString(defaultfreeRtosPath).toUserOutput().toLocal8Bit()};
QVERIFY(cmakeConfig.contains(expectedCmakeVar)); QVERIFY(cmakeConfig.contains(expectedCmakeVar));
} }

View File

@@ -25,10 +25,11 @@
#pragma once #pragma once
#include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportoptions.h" #include "mcusupportoptions.h"
#include "mcusupportplugin.h" #include "mcusupportplugin.h"
#include "mcusupportsdk.h" #include "mcusupportsdk.h"
#include "mcupackage.h"
#include "packagemock.h" #include "packagemock.h"
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>

View File

@@ -4,20 +4,7 @@ project(%{ProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM ASM_MASM)
find_package(Qul) find_package(Qul)
if(Qul_VERSION VERSION_GREATER_EQUAL "1.7")
qul_add_target(%{ProjectName}) qul_add_target(%{ProjectName})
else()
add_executable(%{ProjectName})
target_link_libraries(%{ProjectName}
Qul::QuickUltralite
Qul::QuickUltralitePlatform)
endif()
qul_target_qml_sources(%{ProjectName} %{MainQmlFile}) qul_target_qml_sources(%{ProjectName} %{MainQmlFile})
app_target_setup_os(%{ProjectName}) app_target_setup_os(%{ProjectName})
if(Qul_VERSION VERSION_GREATER_EQUAL "2.0")
app_target_default_entrypoint(%{ProjectName} %{RootItemName}) app_target_default_entrypoint(%{ProjectName} %{RootItemName})
else()
app_target_default_main(%{ProjectName} %{RootItemName})
endif()

View File

@@ -73,7 +73,7 @@ MercurialSettingsPage::MercurialSettingsPage(MercurialSettings *settings)
setId(VcsBase::Constants::VCS_ID_MERCURIAL); setId(VcsBase::Constants::VCS_ID_MERCURIAL);
setDisplayName(MercurialSettings::tr("Mercurial")); setDisplayName(MercurialSettings::tr("Mercurial"));
setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY); setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY);
setSettings(m_settings); setSettings(settings);
setLayouter([settings](QWidget *widget) { setLayouter([settings](QWidget *widget) {
MercurialSettings &s = *settings; MercurialSettings &s = *settings;

Some files were not shown because too many files have changed in this diff Show More