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:
config:
- {
name: "Windows Latest MSVC", artifact: "Windows-MSVC",
os: windows-latest,
name: "Windows MSVC 2019", artifact: "Windows-MSVC",
os: windows-2019,
cc: "cl", cxx: "cl",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat",
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)
add_compile_options(/permissive- /Zc:__cplusplus)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
add_compile_options(-Wno-missing-field-initializers)
endif()
else()
# Common intermediate directory for QML modules which are defined via qt_add_qml_module()
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"
\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
to CMake. Variable names are listed in the \uicontrol Key column and their
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/
**
** This file is part of the Qt Creator documentation.
@@ -291,7 +291,7 @@
\row
\li M106
\li Warning
\li \c Name is already a var
\li \c Name already is a var
\li
\row
@@ -416,6 +416,12 @@
\li A state cannot have the specified child item
\li
\row
\li M129
\li Error
\li Type cannot be instantiated recursively
\li
\row
\li M201
\li Hint
@@ -430,6 +436,7 @@
\li Use only one statement per line
\li
\if defined(qtdesignstudio)
\row
\li M203
\li Warning
@@ -463,60 +470,70 @@
\row
\li M208
\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
\row
\li M209
\li Error
\li This type (type name) is not supported as a root element in
\QDS.
\QDS
\li
\endif
\row
\li M220
\li Error
\li This type (type name) is not supported as a root element of a
UI file (.ui.qml).
\li
UI file (.ui.qml)
\li For more information about supported QML types, see \l{UI Files}.
\row
\li M221
\li Error
\li This type (type name) is not supported in a UI file (.ui.qml).
\li
\li This type (type name) is not supported in a UI file (.ui.qml)
\li For more information about supported QML types, see \l{UI Files}.
\row
\li M222
\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
\l{Supported Methods}.
\row
\li M223
\li Error
\li Java Script blocks are not supported in a UI file (.ui.qml).
\li
\li JavaScript blocks are not supported in a UI file (.ui.qml)
\li For more information about supported features, see \l{UI Files}.
\row
\li M224
\li Error
\li Behavior type is not supported in a UI file (.ui.qml).
\li
\li Behavior type is not supported in a UI file (.ui.qml)
\li For more information about supported QML types, see \l{UI Files}.
\row
\li M225
\li Error
\li States are only supported in the root item in a UI file (.ui.qml).
\li
\li States are only supported in the root item in a UI file (.ui.qml)
\li For more information about supported features, see \l{UI Files}.
\row
\li M226
\li Error
\li Referencing the parent of the root item is not supported in a
UI file (.ui.qml).
\li
UI file (.ui.qml)
\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
\li M300
@@ -674,11 +691,30 @@
and most likely invalid
\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
\li M400
\li Warning
\li Duplicate import
\li
\li An import statement has been added twice. For more information,
see \l{Import Statements}.
\endtable

View File

@@ -83,7 +83,7 @@
By default, logging categories and messages coming directly from Qt are
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.
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/
**
** This file is part of the Qt Creator documentation.
@@ -52,6 +52,7 @@
be edited in \QDS only.
\endif
The following features are not supported in .ui.qml files:
\list
@@ -61,6 +62,7 @@
\li States in other components than the root component
\li Root components that are not derived from \l QQuickItem or
\l [QML]{Item}
\li Referencing the parent of the root component
\endlist
The following components are not supported:
@@ -69,11 +71,9 @@
\li Behavior
\li Binding
\li Canvas
\li Component
\li Shader Effect
\li Timer
\li Transform
\li Transition
\endlist
\section1 Supported Methods
@@ -165,6 +165,8 @@
\li \l{Qt::}{qsTrNoOp()}
\endlist
\note Do not mix translation methods in a UI file.
For more information about using the methods, see
\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
\uicontrol Properties, set \uicontrol Translation > \uicontrol Y to 193.
\li Set the \e rain-drop-white-square.png as texture for the particles.
From \uicontrol Library > \uicontrol Components, drag a \uicontrol Texture
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.
From \uicontrol Library > \uicontrol Assets, drag
\e {rain-drop-white-square.png} to \e spriteParticle.
\li Adjust the apperance and behavior of the sprite further. In \uicontrol
Properties, set:
\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:
\list
\li \macOS 10.15
\li \macOS 11.0
\li Linux:
\list
\li CentOS 8.1

View File

@@ -92,22 +92,9 @@
\li Drag-and-drop an instance of the \uicontrol {Particle System}
component from \uicontrol Library to a scene component instance
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 >
\uicontrol Assets to the texture instance in \uicontrol Navigator.
\li Select the sprite particle instance in \uicontrol Navigator to
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.
\uicontrol Assets to the sprite particle instance
in \uicontrol Navigator.
\endlist
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
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}:
\list
@@ -199,12 +189,16 @@
\uicontrol {Particle end scale} to \e 5.00 for the flame
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,
orange, and transparent gray in \uicontrol Color and set values for
\uicontrol {Color variation} to use slightly different colors for the
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"
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"
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
modifying the property values of the \uicontrol {Vector Direction} component
instances in \uicontrol Properties > \uicontrol {Particle Vector Direction}.

View File

@@ -50,7 +50,7 @@ Product {
flags.push("-Wno-deprecated-copy", "-Wno-constant-logical-operand");
}
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)
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.ModUtils",
"qbs.PathTools",
"qbs.PkgConfig",
"qbs.Probes",
"qbs.Process",
"qbs.PropertyList",

View File

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

View File

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

View File

@@ -133,6 +133,14 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
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;
}
}

View File

@@ -55,6 +55,8 @@
namespace QmlDesigner {
namespace Internal {
const QRectF preview3dBoundingRect(0, 0, 640, 480);
Quick3DNodeInstance::Quick3DNodeInstance(QObject *node)
: ObjectNodeInstance(node)
{
@@ -97,7 +99,7 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
#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 preview puppets
if (instanceId() == 0 && nodeInstanceServer()->isPreviewServer()) {
if (instanceId() == 0 && (!nodeInstanceServer()->isInformationServer())) {
auto helper = new QmlDesigner::Internal::GeneralHelper();
engine()->rootContext()->setContextProperty("_generalHelper", helper);
@@ -111,8 +113,8 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
nodeInstanceServer()->setRootItem(m_dummyRootView);
}
#endif
#endif
#endif // QT_VERSION
#endif // QUICK3D_MODULE
ObjectNodeInstance::initialize(objectNodeInstance, flags);
}
@@ -122,7 +124,7 @@ QImage Quick3DNodeInstance::renderImage() const
if (!isRootNodeInstance() || !m_dummyRootView)
return {};
QSize size(640, 480);
QSize size = preview3dBoundingRect.size().toSize();
nodeInstanceServer()->quickWindow()->resize(size);
m_dummyRootView->setSize(size);
@@ -190,13 +192,37 @@ bool Quick3DNodeInstance::isRenderable() const
return m_dummyRootView;
}
bool Quick3DNodeInstance::hasContent() const
{
return true;
}
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)
return m_dummyRootView->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> instanceList;
@@ -212,6 +238,11 @@ QList<ServerNodeInstance> Quick3DNodeInstance::stateInstances() const
return instanceList;
}
QQuickItem *Quick3DNodeInstance::contentItem() const
{
return m_dummyRootView;
}
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
{
return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer());

View File

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

View File

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

View File

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

View File

@@ -98,6 +98,8 @@ Item {
StudioControls.Menu {
id: contextMenu
closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
StudioControls.MenuItem {
text: qsTr("Expand All")
enabled: allExpandedState !== 1
@@ -167,7 +169,7 @@ Item {
Dialog {
id: renameFolderDialog
title: qsTr("Rename folder")
title: qsTr("Rename Folder")
anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape
implicitWidth: 280
@@ -192,15 +194,15 @@ Item {
}
Text {
text: qsTr("Folder Name cannot be empty.")
text: qsTr("Folder name cannot be empty.")
color: "#ff0000"
visible: folderRename.text === "" && !renameFolderDialog.renameError
}
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
width: renameFolderDialog.width
width: renameFolderDialog.width - 12
color: "#ff0000"
visible: renameFolderDialog.renameError
}
@@ -259,7 +261,7 @@ Item {
Dialog {
id: newFolderDialog
title: qsTr("Create new folder")
title: qsTr("Create New Folder")
anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape
modal: true
@@ -269,7 +271,7 @@ Item {
Row {
Text {
text: qsTr("Folder Name: ")
text: qsTr("Folder name: ")
anchors.verticalCenter: parent.verticalCenter
color: StudioTheme.Values.themeTextColor
}
@@ -287,7 +289,7 @@ Item {
}
Text {
text: qsTr("Folder Name cannot be empty.")
text: qsTr("Folder name cannot be empty.")
color: "#ff0000"
anchors.right: parent.right
visible: folderName.text === ""
@@ -329,7 +331,7 @@ Item {
Dialog {
id: confirmDeleteFolderDialog
title: qsTr("Folder not empty")
title: qsTr("Folder Not Empty")
anchors.centerIn: parent
closePolicy: Popup.CloseOnEscape
implicitWidth: 300
@@ -342,7 +344,7 @@ Item {
Text {
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 : "")
color: StudioTheme.Values.themeTextColor
wrapMode: Text.WordWrap

View File

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

View File

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

View File

@@ -41,7 +41,7 @@ Column {
SectionLayout {
PropertyLabel {
text: qsTr("Active")
tooltip: qsTr("This property is true if the Loader is currently active.")
tooltip: qsTr("Whether the loader is currently active.")
}
SecondColumnLayout {
@@ -57,7 +57,7 @@ Column {
PropertyLabel {
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 {
@@ -70,8 +70,8 @@ Column {
}
PropertyLabel {
text: qsTr("Source Component")
tooltip: qsTr("This property holds the component to instantiate.")
text: qsTr("Source component")
tooltip: qsTr("Component to instantiate.")
}
SecondColumnLayout {
@@ -88,7 +88,7 @@ Column {
PropertyLabel {
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 {

View File

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

View File

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

View File

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

View File

@@ -62,6 +62,10 @@ Project {
Environment {
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
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}
QT_IM_MODULE: "qtvirtualkeyboard"
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>
<name>Android::Internal::AndroidServiceWidget::AndroidServiceModel</name>
<message>
<source>The name of the class implementing the service</source>
<translation>Имя класса, реализующего сервис</translation>
<source>The name of the class implementing the service.</source>
<translation>Имя класса, реализующего сервис.</translation>
</message>
<message>
<source>Checked if the service is run in an external process</source>
<translation>Отмечено, если сервис работает во внешнем процессе</translation>
<source>Checked if the service is run in an external process.</source>
<translation>Отмечено, если сервис работает во внешнем процессе.</translation>
</message>
<message>
<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>
</message>
<message>
<source>Checked if the service is in a separate dynamic library</source>
<translation>Отмечено, если сервис в отдельной динамической библиотеке</translation>
<source>Checked if the service is in a separate dynamic library.</source>
<translation>Отмечено, если сервис в отдельной динамической библиотеке.</translation>
</message>
<message>
<source>The name of the separate dynamic library</source>
<translation>Имя отдельной динамической библиотеки</translation>
<source>The name of the separate dynamic library.</source>
<translation>Имя отдельной динамической библиотеки.</translation>
</message>
<message>
<source>The arguments for telling the app to run the service instead of the main activity</source>
<translation>Параметры запуска сервиса вместо основной функциональности приложения</translation>
<source>The arguments for telling the app to run the service instead of the main activity.</source>
<translation>Параметры запуска сервиса вместо основной функциональности приложения.</translation>
</message>
<message>
<source>Service class name</source>
<translation>Имя класса сервиса</translation>
<source>Service class name.</source>
<translation>Имя класса сервиса.</translation>
</message>
<message>
<source>Run in external process</source>
<translation>Работа во внешнем процессе</translation>
<source>Run in external process.</source>
<translation>Работа во внешнем процессе.</translation>
</message>
<message>
<source>Process name</source>
<translation>Имя процесса</translation>
<source>Process name.</source>
<translation>Имя процесса.</translation>
</message>
<message>
<source>Run in external library</source>
<translation>Работа во внешней библиотеке</translation>
<source>Run in external library.</source>
<translation>Работа во внешней библиотеке.</translation>
</message>
<message>
<source>Library name</source>
<translation>Имя библиотеки</translation>
<source>Library name.</source>
<translation>Имя библиотеки.</translation>
</message>
<message>
<source>Service arguments</source>
<translation>Параметры сервиса</translation>
<source>Service arguments.</source>
<translation>Параметры сервиса.</translation>
</message>
<message>
<source>The class name must be set</source>
<translation>Должно быть задано имя класса</translation>
<source>The class name must be set.</source>
<translation>Должно быть задано имя класса.</translation>
</message>
<message>
<source>The process name must be set for a service run in an external process</source>
<translation>Имя процесса должно быть задано для сервиса, работающего во внешнем процессе</translation>
<source>The process name must be set for a service run in an external process.</source>
<translation>Имя процесса должно быть задано для сервиса, работающего во внешнем процессе.</translation>
</message>
<message>
<source>The library name must be set for a service run in an external library</source>
<translation>Имя библиотеки должно быть задано для сервиса, работающего во внешней библиотеке</translation>
<source>The library name must be set for a service run in an external library.</source>
<translation>Имя библиотеки должно быть задано для сервиса, работающего во внешней библиотеке.</translation>
</message>
<message>
<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
CONDITION APPLE
DEPENDS ${FWFoundation}
SOURCES
main_mac.mm
)

View File

@@ -43,6 +43,8 @@ QtcProduct {
project.sharedSourcesDir + "/qtlockedfile",
]
cpp.frameworks: base.concat(qbs.targetOS.contains("macos") ? ["Foundation"] : [])
Depends { name: "app_version_header" }
Depends { name: "Qt"; submodules: ["widgets", "network"] }
Depends { name: "Utils" }
@@ -97,4 +99,12 @@ QtcProduct {
"../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 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 AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
} // namespace Constants

View File

@@ -60,7 +60,7 @@ struct ConvertArgValueToString {
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
#endif
#include <utils/variant.h> // revert when macos minimum target is >= 10.14
#include <string>
#include <variant>
#include <vector>
@@ -80,7 +80,7 @@ using TimePoint = std::chrono::time_point< Clock >;
class NANOTRACESHARED_EXPORT Arg
{
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);
std::string name() const;

View File

@@ -185,7 +185,7 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
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)

View File

@@ -71,7 +71,7 @@ static inline QString msgInvalidConstructor(const char *what)
StaticAnalysisMessages::StaticAnalysisMessages()
{
// When changing a message or severity, update the documentation, currently
// in creator-editors.qdoc, accordingly.
// in creator-code-syntax.qdoc, accordingly.
newMsg(ErrInvalidEnumValue, Error,
tr("Invalid value for enum."));
newMsg(ErrEnumValueMustBeStringOrNumber, Error,
@@ -211,36 +211,36 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(ErrInvalidArrayValueLength, Error,
tr("%1 elements expected in array value."), 1);
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
tr("A State cannot have a child item (%1)."), 1);
newMsg(WarnDuplicateImport, Warning,
@@ -250,7 +250,7 @@ StaticAnalysisMessages::StaticAnalysisMessages()
newMsg(ErrTypeIsInstantiatedRecursively, Error,
tr("Type cannot be instantiated recursively (%1)."), 1);
newMsg(WarnLogicalValueDoesNotDependOnValues, Warning,
tr("Logical value does not depend on actual values"));
tr("Logical value does not depend on actual values."));
newMsg(ErrToManyComponentChildren, Error,
tr("Components are only allowed to have a single child element."));
newMsg(WarnComponentRequiresChildren, Warning,

View File

@@ -34,6 +34,7 @@ add_qtc_library(Utils
differ.cpp differ.h
displayname.cpp displayname.h
dropsupport.cpp dropsupport.h
dynamiclicensecheck.h
elfreader.cpp elfreader.h
elidinglabel.cpp elidinglabel.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);
handleError(QCoreApplication::translate("Utils::LauncherSocket",
"Launcher socket closed unexpectedly"));
"Launcher socket closed unexpectedly."));
}
void LauncherSocket::handleError(const QString &error)

View File

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

View File

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

View File

@@ -980,12 +980,12 @@ static bool askToKill(const QString &command)
#ifdef QT_GUI_LIB
if (QThread::currentThread() != QCoreApplication::instance()->thread())
return true;
const QString title = QtcProcess::tr("Process not Responding");
const QString title = QtcProcess::tr("Process Not Responding");
QString msg = command.isEmpty() ?
QtcProcess::tr("The process is not responding.") :
QtcProcess::tr("The process \"%1\" is not responding.").arg(command);
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.
const bool hasOverrideCursor = QApplication::overrideCursor() != nullptr;
if (hasOverrideCursor)

View File

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

View File

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

View File

@@ -204,31 +204,31 @@ QVariant AndroidServiceWidget::AndroidServiceModel::headerData(int section, Qt::
{
if (role == Qt::ToolTipRole && orientation == Qt::Horizontal) {
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)
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)
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.");
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)
return tr("The name of the separate dynamic library");
return tr("The name of the separate dynamic library.");
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) {
if (section == 0)
return tr("Service class name");
return tr("Service class name.");
else if (section == 1)
return tr("Run in external process");
return tr("Run in external process.");
else if (section == 2)
return tr("Process name");
return tr("Process name.");
else if (section == 3)
return tr("Run in external library");
return tr("Run in external library.");
else if (section == 4)
return tr("Library name");
return tr("Library name.");
else if (section == 5)
return tr("Service arguments");
return tr("Service arguments.");
}
return {};
}
@@ -247,22 +247,22 @@ QVariant AndroidServiceWidget::AndroidServiceModel::data(const QModelIndex &inde
if (index.column() == 0)
return m_services[index.row()].className();
else if (index.column() == 1)
return tr("Run in external process");
return tr("Run in external process.");
else if (index.column() == 2)
return m_services[index.row()].externalProcessName();
else if (index.column() == 3)
return tr("Run in external library");
return tr("Run in external library.");
else if (index.column() == 4)
return m_services[index.row()].externalLibraryName();
else if (index.column() == 5)
return m_services[index.row()].serviceArguments();
} else if (role == Qt::ToolTipRole) {
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())
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())
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) {
if (index.column() == 0)
return m_services[index.row()].className();

View File

@@ -65,7 +65,7 @@
<item>
<widget class="QPushButton" name="makeDefaultNdkButton">
<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>
</widget>
</item>

View File

@@ -1402,7 +1402,10 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
setClientCapabilities(caps);
setLocatorsEnabled(false);
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);
setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold);
@@ -2958,9 +2961,10 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
int version, bool force)
{
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())) {
qCDebug(clangdLogHighlight) << "LSP tokens outdated; aborting highlighting procedure"
qCInfo(clangdLogHighlight) << "LSP tokens outdated; aborting highlighting procedure"
<< version << q->documentVersion(doc->filePath());
return;
}
@@ -2968,7 +2972,7 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
const auto previous = previousTokens.find(doc);
if (previous != previousTokens.end()) {
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;
}
previous->first = tokens;
@@ -2985,7 +2989,7 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
if (!q->documentOpen(doc))
return;
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());
return;
}

View File

@@ -44,6 +44,7 @@
#include <coreplugin/messagemanager.h>
#include <cppeditor/cppcodemodelsettings.h>
#include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cppfollowsymbolundercursor.h>
#include <cppeditor/cppmodelmanager.h>
#include <cppeditor/cppprojectfile.h>
@@ -58,6 +59,7 @@
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
@@ -85,21 +87,20 @@ static CppEditor::CppModelManager *cppModelManager()
return CppEditor::CppModelManager::instance();
}
static const QList<TextEditor::BaseTextEditor *> allCppEditors()
static ProjectExplorer::Project *fallbackProject()
{
QList<TextEditor::BaseTextEditor *> cppEditors;
for (const Core::DocumentModel::Entry * const entry : Core::DocumentModel::entries()) {
const auto textDocument = qobject_cast<TextEditor::TextDocument *>(entry->document);
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;
if (ProjectExplorer::Project * const p = ProjectExplorer::ProjectTree::currentProject())
return p;
return ProjectExplorer::SessionManager::startupProject();
}
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()
@@ -149,10 +150,7 @@ ClangModelManagerSupport::ClangModelManagerSupport()
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
this, &ClangModelManagerSupport::onAboutToRemoveProject);
connect(sessionManager, &ProjectExplorer::SessionManager::projectRemoved,
this, [this] {
if (ClangdClient * const fallbackClient = clientForProject(nullptr))
claimNonProjectSources(fallbackClient);
});
this, [this] { claimNonProjectSources(clientForProject(fallbackProject())); });
CppEditor::ClangdSettings::setDefaultClangdPath(Core::ICore::clangdExecutable(CLANG_BINDIR));
connect(&CppEditor::ClangdSettings::instance(), &CppEditor::ClangdSettings::changed,
@@ -369,13 +367,15 @@ void ClangModelManagerSupport::updateLanguageClient(
// Acquaint the client with all open C++ documents for this project.
bool hasDocuments = false;
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) {
const Utils::FilePath filePath = editor->textDocument()->filePath();
if (!project->isKnownFile(filePath))
continue;
LanguageClientManager::openDocumentWithClient(editor->textDocument(), client);
ClangEditorDocumentProcessor::clearTextMarks(filePath);
hasDocuments = true;
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
const Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (!currentClient || !currentClient->project()
|| currentClient->state() != Client::Initialized
|| project->isKnownFile(doc->filePath())) {
LanguageClientManager::openDocumentWithClient(doc, client);
ClangEditorDocumentProcessor::clearTextMarks(doc->filePath());
hasDocuments = true;
}
}
if (client->state() == Client::Initialized)
@@ -444,7 +444,7 @@ ClangdClient *ClangModelManagerSupport::clientForProject(
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,
@@ -455,15 +455,18 @@ ClangdClient *ClangModelManagerSupport::createClient(ProjectExplorer::Project *p
return client;
}
void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *fallbackClient)
void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
{
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) {
if (ProjectExplorer::SessionManager::projectForFile(editor->textDocument()->filePath()))
if (!client)
return;
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
if (Client * const currentClient = LanguageClientManager::clientForDocument(doc);
currentClient && currentClient->state() == Client::Initialized
&& (currentClient == client || currentClient->project())) {
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?
ProjectExplorer::Project * const project
ProjectExplorer::Project * project
= ProjectExplorer::SessionManager::projectForFile(document->filePath());
if (!project)
project = fallbackProject();
if (ClangdClient * const client = clientForProject(project))
LanguageClientManager::openDocumentWithClient(textDocument, client);
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -303,7 +303,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_resetButton->setEnabled(false);
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"));
@@ -339,16 +339,18 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
qmlDebugAspect
},
m_warningMessageLabel,
Space(10),
Row{m_kitConfiguration, m_configurationStates},
Group {
cmakeConfiguration,
Row {
bc->aspect<InitialCMakeArgumentsAspect>(),
bc->aspect<AdditionalCMakeOptionsAspect>()
},
m_reconfigureButton,
}
m_kitConfiguration,
Column {
m_configurationStates,
Group {
cmakeConfiguration,
Row {
bc->aspect<InitialCMakeArgumentsAspect>(),
bc->aspect<AdditionalCMakeOptionsAspect>()
},
m_reconfigureButton,
}
}.setSpacing(0)
}.attachTo(details, false);
updateAdvancedCheckBox();

View File

@@ -326,7 +326,7 @@ QSet<Id> CMakeKitAspect::availableFeatures(const Kit *k) const
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.")
.arg(QString::fromUtf8(versionString));
}

View File

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

View File

@@ -83,13 +83,16 @@ protected:
void setSettings(Utils::AspectContainer *settings);
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_category;
QString m_displayName;
QString m_displayCategory;
Utils::Icon m_categoryIcon;
WidgetCreator m_widgetCreator;
QPointer<QWidget> m_widget; // Used in conjunction with m_widgetCreator
mutable bool m_keywordsInitialized = false;
mutable QStringList m_keywords;

View File

@@ -199,6 +199,7 @@ public:
IDocument *m_blockedIDocument = nullptr;
QAction *m_saveAllAction;
QString fileDialogFilterOverride;
};
static DocumentManager *m_instance;
@@ -770,6 +771,16 @@ bool DocumentManager::saveDocument(IDocument *document,
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)
{
QSet<QString> uniqueFilters;
@@ -1531,6 +1542,11 @@ void DocumentManager::notifyFilesChangedInternally(const FilePaths &filePaths)
emit m_instance->filesChangedInternally(filePaths);
}
void DocumentManager::setFileDialogFilter(const QString &filter)
{
d->fileDialogFilterOverride = filter;
}
void DocumentManager::registerSaveAllAction()
{
d->registerSaveAllAction();

View File

@@ -142,6 +142,10 @@ public:
lead to any editors to reload or any other editor manager actions. */
static void notifyFilesChangedInternally(const Utils::FilePaths &filePaths);
static void setFileDialogFilter(const QString &filter);
static QString fileDialogFilter(QString *selectedFilter = nullptr);
signals:
/* 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. */

View File

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

View File

@@ -425,7 +425,7 @@ LoggingViewManagerWidget::LoggingViewManagerWidget(QWidget *parent)
buttonsLayout->addWidget(stop);
auto qtInternal = new QToolButton;
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->setChecked(false);
buttonsLayout->addWidget(qtInternal);
@@ -616,7 +616,7 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
if (enabled)
m_manager->setEnabled(false);
const Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(),
tr("Save logs as"));
tr("Save Logs As"));
if (fp.isEmpty())
return;
const bool useTS = m_timestamps->isChecked();
@@ -628,7 +628,7 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
if (res == -1) {
QMessageBox::critical(
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;
}
}
@@ -636,14 +636,14 @@ void LoggingViewManagerWidget::saveLoggingsToFile() const
} else {
QMessageBox::critical(
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
{
Utils::FilePath fp = Utils::FileUtils::getSaveFilePath(ICore::dialogParent(),
tr("Save enabled categories as"));
tr("Save Enabled Categories As"));
if (fp.isEmpty())
return;
const QList<LoggingCategoryItem> enabled = m_categoryModel->enabledCategories();
@@ -663,13 +663,13 @@ void LoggingViewManagerWidget::saveEnabledCategoryPreset() const
if (!fp.writeFileContents(doc.toJson(QJsonDocument::Compact)))
QMessageBox::critical(
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()
{
Utils::FilePath fp = Utils::FileUtils::getOpenFilePath(ICore::dialogParent(),
tr("Load enabled categories from"));
tr("Load Enabled Categories From"));
if (fp.isEmpty())
return;
// read file, update categories
@@ -677,7 +677,7 @@ void LoggingViewManagerWidget::loadAndUpdateFromPreset()
QJsonDocument doc = QJsonDocument::fromJson(fp.fileContents(), &error);
if (error.error != QJsonParseError::NoError) {
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()));
return;
}

View File

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

View File

@@ -177,6 +177,8 @@ QList<AccessRange> collectAccessRanges(const CPlusPlus::TranslationUnit *tu,
if (AccessDeclarationAST *xsDecl = decl->asAccessDeclaration()) {
const unsigned token = xsDecl->access_specifier_token;
if (tu->tokenAt(token).generated())
continue;
InsertionPointLocator::AccessSpec newXsSpec = initialXs;
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.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 "
"in system logs."));
@@ -165,7 +165,7 @@ DebuggerSettings::DebuggerSettings()
CommonOptionsPage::msgSetBreakpointAtFunction(Constants::CRT_DEBUG_REPORT));
cdbBreakOnCrtDbgReport.setToolTip(
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.setToolTip("<html><head/><body><p>" + tr(
@@ -421,7 +421,7 @@ DebuggerSettings::DebuggerSettings()
useAnnotationsInMainEditor.setSettingsKey(debugModeGroup, "UseAnnotations");
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."));
useAnnotationsInMainEditor.setDefaultValue(true);
@@ -440,7 +440,7 @@ DebuggerSettings::DebuggerSettings()
useToolTipsInMainEditor.setSettingsKey(debugModeGroup, "UseToolTips");
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 "
"does not provide reliable information as it does not use scope "
"information, it is switched off by default."));
@@ -448,17 +448,17 @@ DebuggerSettings::DebuggerSettings()
useToolTipsInLocalsView.setSettingsKey(debugModeGroup, "UseToolTipsInLocalsView");
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."));
useToolTipsInBreakpointsView.setSettingsKey(debugModeGroup, "UseToolTipsInBreakpointsView");
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."));
useToolTipsInStackView.setSettingsKey(debugModeGroup, "UseToolTipsInStackView");
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."));
useToolTipsInStackView.setDefaultValue(true);

View File

@@ -333,7 +333,7 @@ public:
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 "
"in the Docker container."));
"in the docker container."));
m_runAsOutsideUser->setChecked(data.useLocalUidGid);
m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost());
@@ -361,7 +361,7 @@ public:
m_pathsListEdit = new PathListEditor;
m_pathsListEdit->setToolTip(tr("Maps paths in this list one-to-one to the "
"Docker container."));
"docker container."));
m_pathsListEdit->setPathList(data.mounts);
connect(m_pathsListEdit, &PathListEditor::changed, this, [dockerDevice, this]() {
@@ -378,12 +378,12 @@ public:
auto searchDirsComboBox = new QComboBox;
searchDirsComboBox->addItem(tr("Search in PATH"));
searchDirsComboBox->addItem(tr("Search in selected directories"));
searchDirsComboBox->addItem(tr("Search in Selected Directories"));
auto searchDirsLineEdit = new QLineEdit;
searchDirsLineEdit->setText("/usr/bin;/opt");
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] {
FilePaths paths;
@@ -491,7 +491,7 @@ Tasks DockerDevice::validate() const
Tasks result;
if (d->m_data.mounts.isEmpty()) {
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."),
{}, -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.
updateContainerAccess();
if (d->m_container.isEmpty()) {
MessageManager::writeDisrupting(tr("Error starting remote shell. No container"));
MessageManager::writeDisrupting(tr("Error starting remote shell. No container."));
return;
}
@@ -910,7 +910,7 @@ void DockerDevicePrivate::startContainer()
if (exitCode > 120) {
DockerPlugin::setGlobalDaemonState(false);
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 "
"docker daemon on the docker device settings page "
"or restart Qt Creator."));
@@ -974,7 +974,7 @@ void DockerDevicePrivate::updateFileSystemAccess()
if (!QFileInfo(m_mergedDir).isReadable()) {
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)
+ '\n' + tr("Output: \"%1\"").arg(out)
+ '\n' + tr("Error: \"%1\"").arg(proc.stdErr()));

View File

@@ -112,6 +112,11 @@ Client::Client(BaseClientInterface *clientInterface)
m_tokenSupport.setTokenTypesMap(SemanticTokens::defaultTokenTypesMap());
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
@@ -317,7 +322,6 @@ void Client::initialize()
// directly send message otherwise the state check of sendContent would fail
sendMessage(initRequest.toBaseMessage());
m_clientInterface->sendMessage(initRequest.toBaseMessage());
m_state = InitializeRequested;
}
@@ -331,6 +335,7 @@ void Client::shutdown()
});
sendContent(shutdown);
m_state = ShutdownRequested;
m_shutdownTimer.start();
}
Client::State Client::state() const
@@ -364,7 +369,7 @@ void Client::setClientCapabilities(const LanguageServerProtocol::ClientCapabilit
void Client::openDocument(TextEditor::TextDocument *document)
{
using namespace TextEditor;
if (!isSupportedDocument(document))
if (m_openedDocument.contains(document) || !isSupportedDocument(document))
return;
if (m_state != Initialized) {
@@ -372,8 +377,6 @@ void Client::openDocument(TextEditor::TextDocument *document)
return;
}
QTC_ASSERT(!m_openedDocument.contains(document), return);
const FilePath &filePath = document->filePath();
const QString method(DidOpenTextDocumentNotification::methodName);
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)
{
m_shutdownTimer.stop();
QTC_ASSERT(m_state == ShutdownRequested, return);
QTC_ASSERT(m_clientInterface, return);
optional<ShutdownRequest::Response::Error> errorValue = shutdownResponse.error();
@@ -1634,6 +1638,7 @@ void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)
sendMessage(ExitNotification().toBaseMessage());
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
m_state = Shutdown;
m_shutdownTimer.start();
}
bool Client::sendWorkspceFolderChanges() const

View File

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

View File

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

View File

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

View File

@@ -58,14 +58,10 @@ public:
virtual const QString &environmentVariableName() const = 0;
virtual void setAddToPath(bool) = 0;
virtual bool addToPath() const = 0;
virtual void writeGeneralSettings() const = 0;
virtual bool writeToSettings() const = 0;
virtual void setRelativePathModifier(const QString &) = 0;
virtual void setVersions(const QStringList &) = 0;
virtual bool automaticKitCreationEnabled() const = 0;
virtual void setAutomaticKitCreationEnabled(const bool enabled) = 0;
virtual QWidget *widget() = 0;
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/
**
** This file is part of Qt Creator.
@@ -25,6 +25,7 @@
#include "mcupackage.h"
#include "mcusupportconstants.h"
#include "mcusupportversiondetection.h"
#include "mcusupportsdk.h"
#include <coreplugin/icore.h>
@@ -40,15 +41,6 @@ using namespace Utils;
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,
const FilePath &defaultPath,
const QString &detectionPath,
@@ -65,7 +57,6 @@ McuPackage::McuPackage(const QString &label,
, m_downloadUrl(downloadUrl)
{
m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath);
m_automaticKitCreation = automaticKitCreationFromSettings(QSettings::UserScope);
}
FilePath McuPackage::basePath() const
@@ -161,14 +152,6 @@ bool McuPackage::addToPath() const
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
{
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
@@ -191,16 +174,6 @@ void McuPackage::setVersions(const QStringList &versions)
m_versions = versions;
}
bool McuPackage::automaticKitCreationEnabled() const
{
return m_automaticKitCreation;
}
void McuPackage::setAutomaticKitCreationEnabled(const bool enabled)
{
m_automaticKitCreation = enabled;
}
void McuPackage::updatePath()
{
m_path = m_fileChooser->rawFilePath();
@@ -269,9 +242,10 @@ QString McuPackage::statusText() const
.arg(displayPackagePath, displayDetectedPath);
break;
case Status::ValidPackageMismatchedVersion: {
const QString versionWarning = m_versions.size() == 1 ?
tr("but only version %1 is supported").arg(m_versions.first()) :
tr("but only versions %1 are supported").arg(displayVersions);
const QString versionWarning
= m_versions.size() == 1
? 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.")
.arg(displayPackagePath, displayDetectedPath, versionWarning);
break;
@@ -313,4 +287,5 @@ bool McuToolChainPackage::isDesktopToolchain() const
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/
**
** This file is part of Qt Creator.
@@ -26,10 +26,8 @@
#pragma once
#include "mcuabstractpackage.h"
#include "mcusupportversiondetection.h"
#include <utils/filepath.h>
#include <utils/id.h>
#include <QObject>
@@ -42,11 +40,14 @@ class ToolChain;
namespace Utils {
class PathChooser;
class InfoLabel;
class Id;
} // namespace Utils
namespace McuSupport {
namespace Internal {
class McuPackageVersionDetector;
class McuPackage : public McuAbstractPackage
{
Q_OBJECT
@@ -73,23 +74,14 @@ public:
bool validStatus() const override;
void setAddToPath(bool addToPath) override;
bool addToPath() const override;
void writeGeneralSettings() const override;
bool writeToSettings() const override;
void setRelativePathModifier(const QString &path) 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;
const QString &environmentVariableName() const override;
signals:
void changed();
void statusChanged();
private:
void updatePath();
void updateStatusUi();
@@ -111,7 +103,6 @@ private:
const QString m_environmentVariableName;
const QString m_downloadUrl;
bool m_addToPath = false;
bool m_automaticKitCreation = true;
Status m_status = Status::InvalidPath;
};

View File

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

View File

@@ -24,47 +24,27 @@
****************************************************************************/
#include "mcusupportoptions.h"
#include "mcukitinformation.h"
#include "mcupackage.h"
#include "mcutarget.h"
#include "mcukitmanager.h"
#include "mcukitinformation.h"
#include "mcusupportcmakemapper.h"
#include "mcusupportconstants.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h"
#include "mcusupportplugin.h"
#include <baremetal/baremetalconstants.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
#include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.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/fileutils.h>
#include <utils/infolabel.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtversionmanager.h>
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
@@ -74,263 +54,6 @@ using namespace Utils;
namespace McuSupport {
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()
{
qDeleteAll(packages);
@@ -347,6 +70,7 @@ McuSupportOptions::McuSupportOptions(QObject *parent)
&McuAbstractPackage::changed,
this,
&McuSupportOptions::populatePackagesAndTargets);
m_automaticKitCreation = automaticKitCreationFromSettings();
}
McuSupportOptions::~McuSupportOptions()
@@ -402,7 +126,7 @@ void McuSupportOptions::registerExamples()
const QVersionNumber &McuSupportOptions::minimalQulVersion()
{
static const QVersionNumber v({1, 3});
static const QVersionNumber v({2, 0});
return v;
}
@@ -413,48 +137,16 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
if (qtForMCUsSdkPackage->validStatus())
Sdk::targetsAndPackages(dir, &sdkRepository);
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()
{
return Sdk::packagePathFromSettings(Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK,
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);
QSettings::UserScope,
{});
}
void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
@@ -465,14 +157,13 @@ void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &en
// First filter out all Qul2.x CMake vars
auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit),
[&](const auto &configItem) {
return !cmakeVarNames.contains(configItem.key);
});
return !cmakeVarNames.contains(configItem.key);
});
// Then append them with new values
config.append(cmakeVars);
CMakeConfigurationKitAspect::setConfiguration(kit, config);
}
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{
switch (tcPackage->type()) {
@@ -569,15 +260,7 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
processPackage(package);
processPackage(qtForMCUsSdkPackage);
// Clang not needed in version 1.7+
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())
if (McuSupportOptions::kitsNeedQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});
// 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()) {
printMessage(McuTarget::tr(
"Warning for target %1: missing CMake toolchain file expected at %2.")
.arg(McuSupportOptions::kitName(mcuTarget),
.arg(McuKitManager::kitName(mcuTarget),
cMakeToolchainFile.toUserOutput()),
false);
}
@@ -667,19 +350,16 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
config.append(CMakeConfigItem("QUL_GENERATORS", generatorsPath.toString().toUtf8()));
if (!generatorsPath.exists()) {
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);
}
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)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1()));
if (kitNeedsQtVersion())
if (McuSupportOptions::kitsNeedQtVersion())
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
CMakeConfigurationKitAspect::setConfiguration(k, config);
@@ -695,134 +375,11 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
static void setKitQtVersionOptions(Kit *k)
{
if (!kitNeedsQtVersion())
if (!McuSupportOptions::kitsNeedQtVersion())
QtSupport::QtKitAspect::setQtVersion(k, nullptr);
// 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)
{
for (const NameValueItem &nameValueItem : EnvironmentKitAspect::environmentChanges(kit)) {
@@ -832,21 +389,7 @@ static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
return FilePath();
}
bool McuSupportOptions::kitUpToDate(const Kit *kit,
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()
McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades()
{
QMessageBox upgradePopup(Core::ICore::dialogParent());
upgradePopup.setStandardButtons(QMessageBox::Cancel);
@@ -859,86 +402,17 @@ McuSupportOptions::UpgradeOption McuSupportOptions::askForKitUpgrades()
upgradePopup.exec();
if (upgradePopup.clickedButton() == keepButton)
return Keep;
return McuKitManager::UpgradeOption::Keep;
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();
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;
sdkRepository.deletePackagesAndTargets();
}
void McuSupportOptions::checkUpgradeableKits()
@@ -947,144 +421,44 @@ void McuSupportOptions::checkUpgradeableKits()
return;
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) {
return !upgradeableKits(target, this->qtForMCUsSdkPackage).empty()
&& matchingKits(target, this->qtForMCUsSdkPackage).empty();
return !McuKitManager::upgradeableKits(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)
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 == Replace)
for (auto existingKit : kits)
KitManager::deregisterKit(existingKit);
if (target->isValid())
newKit(target, qtForMCUsPackage);
target->printPackageProblems();
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
// 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();
}
void McuSupportOptions::upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk)
bool McuSupportOptions::automaticKitCreationEnabled() const
{
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path());
setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
setKitDependencies(kit, mcuTarget, qtForMCUsSdk);
return m_automaticKitCreation;
}
void McuSupportOptions::fixKitsDependencies()
void McuSupportOptions::setAutomaticKitCreationEnabled(const bool enabled)
{
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)) {
updateKitEnvironment(kit, target);
}
}
}
repo.deletePackagesAndTargets();
delete qtForMCUsPackage;
m_automaticKitCreation = enabled;
}
/**
* @brief Fix/update existing kits if needed
*/
void McuSupportOptions::fixExistingKits()
void McuSupportOptions::writeGeneralSettings() const
{
for (Kit *kit : KitManager::kits()) {
if (!kit->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY))
continue;
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
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
// 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;
bool McuSupportOptions::automaticKitCreationFromSettings()
{
QSettings *settings = Core::ICore::settings(QSettings::UserScope);
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
+ QLatin1String(Constants::SETTINGS_KEY_AUTOMATIC_KIT_CREATION);
const bool automaticKitCreation = settings->value(key, true).toBool();
return automaticKitCreation;
}
} // namespace Internal

View File

@@ -26,6 +26,9 @@
#pragma once
#include <utils/environmentfwd.h>
#include "mcusupport_global.h"
#include "mcukitmanager.h"
#include <QObject>
#include <QVector>
#include <QVersionNumber>
@@ -48,49 +51,7 @@ namespace Internal {
class McuAbstractPackage;
class McuToolChainPackage;
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 McuTarget;
class McuSdkRepository
{
@@ -106,8 +67,6 @@ class McuSupportOptions : public QObject
Q_OBJECT
public:
enum UpgradeOption { Ignore, Keep, Replace };
explicit McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
@@ -115,47 +74,36 @@ public:
McuSdkRepository sdkRepository;
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 remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &);
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 registerExamples();
static const QVersionNumber &minimalQulVersion();
static QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
static bool kitUpToDate(const ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
void checkUpgradeableKits();
void populatePackagesAndTargets();
static bool kitsNeedQtVersion();
bool automaticKitCreationEnabled() const;
void setAutomaticKitCreationEnabled(const bool enabled);
void writeGeneralSettings() const;
static bool automaticKitCreationFromSettings();
private:
void deletePackagesAndTargets();
bool m_automaticKitCreation = true;
signals:
void changed();
void packagesChanged();
};
} // namespace Internal
} // namespace McuSupport

View File

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

View File

@@ -28,6 +28,7 @@
#include "mcusupportconstants.h"
#include "mcusupportdevice.h"
#include "mcusupportoptions.h"
#include "mcukitmanager.h"
#include "mcusupportoptionspage.h"
#include "mcusupportrunconfiguration.h"
@@ -38,6 +39,7 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/jsonwizard/jsonwizardfactory.h>
@@ -53,6 +55,16 @@ using namespace ProjectExplorer;
namespace McuSupport {
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
{
public:
@@ -65,7 +77,7 @@ public:
McuDependenciesKitAspect environmentPathsKitAspect;
}; // class McuSupportPluginPrivate
static McuSupportPluginPrivate* dd{nullptr};
static McuSupportPluginPrivate *dd{nullptr};
McuSupportPlugin::~McuSupportPlugin()
{
@@ -93,9 +105,9 @@ void McuSupportPlugin::extensionsInitialized()
ProjectExplorer::DeviceManager::instance()->addDevice(McuSupportDevice::create());
connect(KitManager::instance(), &KitManager::kitsLoaded, []() {
McuSupportOptions::removeOutdatedKits();
McuSupportOptions::createAutomaticKits();
McuSupportOptions::fixExistingKits();
McuKitManager::removeOutdatedKits();
McuKitManager::createAutomaticKits();
McuKitManager::fixExistingKits();
McuSupportPlugin::askUserAboutMcuSupportKitsSetup();
});
}
@@ -106,7 +118,7 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsSetup()
if (!ICore::infoBar()->canInfoBeAdded(setupMcuSupportKits)
|| McuSupportOptions::qulDirFromSettings().isEmpty()
|| !McuSupportOptions::existingKits(nullptr).isEmpty())
|| !McuKitManager::existingKits(nullptr).isEmpty())
return;
Utils::InfoBarEntry info(setupMcuSupportKits,
@@ -130,18 +142,19 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade()
Utils::InfoBarEntry info(upgradeMcuSupportKits,
tr("New version of Qt for MCUs detected. Upgrade existing Kits?"),
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")};
selectedOption = McuSupportOptions::UpgradeOption::Keep;
info.setComboInfo(options, [options](const QString &selected) {
selectedOption = options.indexOf(selected) == 0 ? McuSupportOptions::UpgradeOption::Keep
: McuSupportOptions::UpgradeOption::Replace;
selectedOption = options.indexOf(selected) == 0 ? McuKitManager::UpgradeOption::Keep
: McuKitManager::UpgradeOption::Replace;
});
info.addCustomButton(tr("Proceed"), [upgradeMcuSupportKits] {
ICore::infoBar()->removeInfo(upgradeMcuSupportKits);
QTimer::singleShot(0, []() { McuSupportOptions::upgradeKits(selectedOption); });
QTimer::singleShot(0, []() {
McuKitManager::upgradeKitsByCreatingNewPackage(selectedOption);
});
});
ICore::infoBar()->addInfo(info);

View File

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

View File

@@ -24,10 +24,13 @@
****************************************************************************/
#include "mcusupportsdk.h"
#include "mcukitmanager.h"
#include "mcupackage.h"
#include "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include "mcusupportplugin.h"
#include "mcusupportversiondetection.h"
#include "mcutarget.h"
#include "mcutargetdescription.h"
#include <baremetal/baremetalconstants.h>
@@ -527,10 +530,9 @@ protected:
QVector<McuTarget *> mcuTargets;
McuToolChainPackage *tcPkg = tcPkgs.value(desc.toolchain.id);
if (tcPkg) {
if (QVersionNumber::fromString(desc.qulVersion) >= QVersionNumber({1, 8}))
tcPkg->setVersions(desc.toolchain.versions);
} else
if (tcPkg)
tcPkg->setVersions(desc.toolchain.versions);
else
tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.platform.colorDepths) {
QVector<McuAbstractPackage *> required3rdPartyPkgs;
@@ -551,8 +553,7 @@ protected:
boardSdkPkgs.insert(desc.boardSdk.envVar, boardSdkPkg);
}
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();
required3rdPartyPkgs.append(boardSdkPkg);
}
@@ -641,9 +642,12 @@ static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)
return kitsDir.entryInfoList();
}
static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion,
const QJsonObject &target)
McuTargetDescription parseDescriptionJson(const QByteArray &data)
{
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 QJsonObject toolchain = target.value("toolchain").toObject();
const QJsonObject boardSdk = target.value("boardSdk").toObject();
@@ -660,9 +664,23 @@ static McuTargetDescription parseDescriptionJsonCommon(const QString &qulVersion
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,
compatVersion,
{},
{
platform.value("id").toString(),
platformName,
platform.value("vendor").toString(),
colorDepthsVector,
platformName == "Desktop" ? McuTargetDescription::TargetType::Desktop
: McuTargetDescription::TargetType::MCU,
},
{
toolchain.value("id").toString(),
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
const QHash<QString, QString> oldSdkQtcRequiredVersion = {
{{"1.0"}, {"4.11.x"}},
{{"1.1"}, {"4.12.0 or 4.12.1"}},
{{"1.2"}, {"4.12.2 or 4.12.3"}},
};
static const QString legacySupportVersionFor(const QString &sdkVersion)
{
static const QHash<QString, QString> oldSdkQtcRequiredVersion = {
{{"1.0"}, {"4.11.x"}},
{{"1.1"}, {"4.12.0 or 4.12.1"}},
{{"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)
{
const McuPackagePathVersionDetector versionDetector("(?<=\\bQtMCUs.)(\\d+\\.\\d+)");
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, "
"only supported by Qt Creator version %2. "
"This version of Qt Creator requires Qt for MCUs %3 or greater.")
.arg(sdkDetectedVersion,
oldSdkQtcRequiredVersion.value(sdkDetectedVersion),
legacyVersion,
McuSupportOptions::minimalQulVersion().toString());
return true;
}
@@ -787,10 +755,11 @@ void targetsAndPackages(const Utils::FilePath &dir, McuSdkRepository *repo)
continue;
}
if (QVersionNumber::fromString(desc.qulVersion) < McuSupportOptions::minimalQulVersion()) {
const QString legacyVersion = legacySupportVersionFor(desc.qulVersion);
const QString qtcSupportText
= oldSdkQtcRequiredVersion.contains(desc.qulVersion)
= !legacyVersion.isEmpty()
? 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);
printMessage(McuTarget::tr("Skipped %1. %2 Qt for MCUs version >= %3 required.")
.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)));
// Keep targets sorted lexicographically
std::sort(repo->mcuTargets.begin(),
repo->mcuTargets.end(),
[](const McuTarget *lhs, const McuTarget *rhs) {
return McuSupportOptions::kitName(lhs) < McuSupportOptions::kitName(rhs);
return McuKitManager::kitName(lhs) < McuKitManager::kitName(rhs);
});
}

View File

@@ -33,7 +33,7 @@
namespace McuSupport {
namespace Internal {
constexpr int MAX_COMPATIBILITY_VERSION {1};
constexpr int MAX_COMPATIBILITY_VERSION{1};
class McuSdkRepository;
class McuAbstractPackage;
@@ -51,13 +51,14 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message);
void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo);
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 packagePathFromSettings(const QString &settingsKey,
QSettings::Scope scope = QSettings::UserScope,
const Utils::FilePath &defaultPath = {});
QSettings::Scope scope,
const Utils::FilePath &defaultPath);
} // namespace Sdk
} // namespace Internal
} // 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 <utils/filepath.h>
#include <gmock/gmock.h>
#include <utils/filepath.h>
namespace McuSupport::Internal {
@@ -45,19 +45,13 @@ public:
MOCK_METHOD(Status, status, (), (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(bool, addToPath, (), (const));
MOCK_METHOD(void, writeGeneralSettings, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const));
MOCK_METHOD(void, setRelativePathModifier, (const QString &) );
MOCK_METHOD(void, setVersions, (const QStringList &) );
MOCK_METHOD(bool, automaticKitCreationEnabled, (), (const));
MOCK_METHOD(void, setAutomaticKitCreationEnabled, (const bool enabled));
MOCK_METHOD(QWidget *, widget, ());
}; // class PackageMock
} // namespace McuSupport::Internal

View File

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

View File

@@ -25,10 +25,11 @@
#pragma once
#include "mcupackage.h"
#include "mcutarget.h"
#include "mcusupportoptions.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h"
#include "mcupackage.h"
#include "packagemock.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)
if(Qul_VERSION VERSION_GREATER_EQUAL "1.7")
qul_add_target(%{ProjectName})
else()
add_executable(%{ProjectName})
target_link_libraries(%{ProjectName}
Qul::QuickUltralite
Qul::QuickUltralitePlatform)
endif()
qul_add_target(%{ProjectName})
qul_target_qml_sources(%{ProjectName} %{MainQmlFile})
app_target_setup_os(%{ProjectName})
if(Qul_VERSION VERSION_GREATER_EQUAL "2.0")
app_target_default_entrypoint(%{ProjectName} %{RootItemName})
else()
app_target_default_main(%{ProjectName} %{RootItemName})
endif()
app_target_default_entrypoint(%{ProjectName} %{RootItemName})

View File

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

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