Merge remote-tracking branch 'origin/7.0'
Conflicts: src/libs/utils/qtcprocess.cpp src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp Change-Id: Id0c31719e46d1c44770ea89663eee321a0517ff4
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
@@ -157,14 +157,6 @@
|
||||
re-scanning is incremental, so nothing is lost by closing and re-starting
|
||||
\QC.
|
||||
|
||||
Because clangd considers only the on-disk state of included header files
|
||||
when parsing a source file, you need to save changes in header files to
|
||||
have them considered elsewhere for completion, diagnostics, and so on.
|
||||
Partly for this reason, files that are changed by refactoring actions are
|
||||
saved automatically. To disable this feature, select \uicontrol Tools >
|
||||
\uicontrol Options > \uicontrol Environment > \uicontrol System >
|
||||
\uicontrol {Auto-save files after refactoring}.
|
||||
|
||||
The document outline in the \l{Viewing Defined Types and Symbols}
|
||||
{Outline} view is backed by clangd's document symbol support, which
|
||||
makes the results more reliable than before.
|
||||
|
@@ -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.
|
||||
@@ -114,7 +114,7 @@
|
||||
\c {share/qtcreator/templates/wizards/classes/mycpp}
|
||||
|
||||
\li Use the \uicontrol {Factory.Reset} action to make the wizard appear
|
||||
in \uicontrol File > \uicontrol {New File or Project} without
|
||||
in \uicontrol File > \uicontrol {New File} without
|
||||
restarting \QC.
|
||||
|
||||
\li Open the wizard configuration file, \c {wizard.json} for editing:
|
||||
@@ -122,7 +122,7 @@
|
||||
\list
|
||||
|
||||
\li The following settings determine the type of the wizard and
|
||||
its place in the \uicontrol {New File or Project} dialog:
|
||||
its place in the \uicontrol {New File} dialog:
|
||||
|
||||
\code
|
||||
"version": 1,
|
||||
@@ -163,14 +163,14 @@
|
||||
\li \c category is the category in which to place the wizard
|
||||
in the list. You can use a leading letter to specify the
|
||||
position of the category in the list in the
|
||||
\uicontrol {New File or Project} dialog.
|
||||
\uicontrol {New File} dialog.
|
||||
|
||||
This information is available in the wizard as
|
||||
\c {%\{category\}}.
|
||||
\endlist
|
||||
|
||||
\li The following settings specify the icon and text that appear in
|
||||
the \uicontrol {New File or Project} dialog:
|
||||
the \uicontrol {New File} dialog:
|
||||
|
||||
\code
|
||||
"trDescription": "Creates a C++ header and a source file for a new class that you can add to a C++ project.",
|
||||
@@ -194,9 +194,8 @@
|
||||
This information is available in the wizard as
|
||||
\c {%\{trDisplayName\}}.
|
||||
|
||||
\li \c trDisplayCategory appears in the
|
||||
\uicontrol {New File or Project} dialog, under
|
||||
\uicontrol Projects.
|
||||
\li \c trDisplayCategory appears in the \uicontrol {New File}
|
||||
dialog, under \uicontrol {Files and Classes}.
|
||||
|
||||
This information is available in the wizard as
|
||||
\c {%\{trDisplayCategory\}}.
|
||||
@@ -231,9 +230,9 @@
|
||||
\c{false}.
|
||||
|
||||
\li \c enabled is evaluated to determine whether a wizard is
|
||||
listed in \uicontrol Files >
|
||||
\uicontrol {New File or Project}, after \c featuresRequired
|
||||
has been checked.
|
||||
listed in \uicontrol File > \uicontrol {New Project} or
|
||||
\uicontrol {New File}, after \c featuresRequired has been
|
||||
checked.
|
||||
|
||||
The default value is \c true.
|
||||
|
||||
@@ -373,7 +372,8 @@
|
||||
instance of \QC.
|
||||
|
||||
\li \c Platform contains the platform selected in the \uicontrol File >
|
||||
\uicontrol {New File or Project} dialog. This value may be empty.
|
||||
\uicontrol {New Project} or \uicontrol {New File} dialog. This value
|
||||
may be empty.
|
||||
\endlist
|
||||
|
||||
The following information is only available when the wizard was triggered
|
||||
@@ -487,7 +487,7 @@
|
||||
\endcode
|
||||
|
||||
The page evaluates \c {%\{Platform\}} to set the platform selected in
|
||||
\uicontrol File > \uicontrol {New File or Project}.
|
||||
\uicontrol File > \uicontrol {New Project} or \uicontrol {New 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 the Qt Creator documentation.
|
||||
@@ -59,8 +59,8 @@
|
||||
wizard directory and instruct the recipients to extract it into one of the
|
||||
directories \QC searches wizards from.
|
||||
|
||||
\QC displays the wizards that it finds in the
|
||||
\uicontrol {New File} and \uicontrol {New Project} dialogs. For each wizard, an icon (1), a
|
||||
\QC displays the wizards that it finds in the \uicontrol {New Project}
|
||||
and \uicontrol {New File} dialogs. For each wizard, an icon (1), a
|
||||
display name (2), and a description (3) are displayed.
|
||||
|
||||
\image qtcreator-custom-wizard.png
|
||||
|
@@ -45,6 +45,8 @@
|
||||
\uicontrol Environment > \uicontrol System, and then select
|
||||
\uicontrol Change in the \uicontrol Environment field.
|
||||
|
||||
\image qtcreator-options-environment-system.png "Environment options System tab"
|
||||
|
||||
In addition, you can specify custom environment variables in the
|
||||
\uicontrol {Project Settings} > \uicontrol Environment settings.
|
||||
They are added to all build environments. The final build environment
|
||||
|
@@ -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.
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
\list 1
|
||||
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||
\li Select \uicontrol File > \uicontrol {New Project} >
|
||||
\uicontrol {Application (Qt)} > \uicontrol {Qt Quick Application}.
|
||||
|
||||
\li Select \uicontrol Choose to open the
|
||||
|
@@ -63,6 +63,8 @@
|
||||
\li Select the \uicontrol {Auto-save modified files} check box to
|
||||
automatically save changed files at the intervals specified in
|
||||
the \uicontrol Interval field.
|
||||
\li Select the \uicontrol {Auto-save files after refactoring} check
|
||||
box to automatically save \l{Refactoring}{refactored files}.
|
||||
\li Select the \uicontrol {Auto-suspend unmodified files} check
|
||||
box to automatically free the resources of open files after
|
||||
prolonged inactivity. The files are still listed in the
|
||||
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 102 KiB |
@@ -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 Design Studio documentation.
|
||||
@@ -61,7 +61,7 @@
|
||||
To create stylable UI controls:
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||
\li Select \uicontrol File > \uicontrol {New File} >
|
||||
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Controls}.
|
||||
\li Select the control to create, and then select \uicontrol Choose.
|
||||
|
||||
|
@@ -35,20 +35,18 @@
|
||||
\image studio-examples-download.png "Examples for download in Welcome mode"
|
||||
|
||||
To run an example project:
|
||||
|
||||
\list 1
|
||||
\li Select the example.
|
||||
\li Select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button to preview the example.
|
||||
\li Select the example project to open it. \QDS makes all necessary
|
||||
downloads.
|
||||
\li Select \inlineimage icons/run_small.png
|
||||
(\uicontrol {Run}) to run the example.
|
||||
\endlist
|
||||
|
||||
Some of the example projects require that you download them before you can run them, to do this:
|
||||
\list 1
|
||||
\li Select an example.
|
||||
\li Select \uicontrol {Start Download}.
|
||||
\li Select the folder where the source files will be installed.
|
||||
\li Select \uicontrol Continue to install the files.
|
||||
\li Select \uicontrol Open to open the example in \QDS.
|
||||
\endlist
|
||||
If there is an update available for an example project that you have
|
||||
installed, it is indicated by a yellow icon next to the example project name
|
||||
on the \uicontrol Welcome page. Select the icon to download the latest
|
||||
version of the example project.
|
||||
|
||||
\section1 Example Documentation
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "sharedmemory.h"
|
||||
#include <QCache>
|
||||
#include <QDebug>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@@ -36,6 +37,8 @@
|
||||
#define QTC_ASSERT_STRING(cond) qDebug("SOFT ASSERT: \"" cond"\" in file " __FILE__ ", line " QTC_ASSERT_STRINGIFY(__LINE__))
|
||||
#define QTC_ASSERT(cond, action) if (cond) {} else { QTC_ASSERT_STRING(#cond); action; } do {} while (0)
|
||||
|
||||
static Q_LOGGING_CATEGORY(imageContainerDebug, "qtc.imagecontainer.debug", QtDebugMsg)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
// using cache as a container which deletes sharedmemory pointers at process exit
|
||||
@@ -202,7 +205,7 @@ static void readSharedMemory(qint32 key, ImageContainer &container)
|
||||
image.setDevicePixelRatio(pixelRatio);
|
||||
|
||||
if (image.isNull())
|
||||
qDebug() << Q_FUNC_INFO << "Not able to create image:" << imageWidth << imageHeight << imageFormat;
|
||||
qCInfo(imageContainerDebug()) << Q_FUNC_INFO << "Not able to create image:" << imageWidth << imageHeight << imageFormat;
|
||||
else
|
||||
std::memcpy(image.bits(), reinterpret_cast<const qint32*>(sharedMemory.constData()) + 6, byteCount);
|
||||
|
||||
|
@@ -125,6 +125,7 @@ bool startCrashpad()
|
||||
|
||||
// Optional arguments to pass to the handler
|
||||
std::vector<std::string> arguments;
|
||||
arguments.push_back("--no-rate-limit");
|
||||
|
||||
CrashpadClient *client = new CrashpadClient();
|
||||
bool success = client->StartHandler(
|
||||
|
@@ -424,7 +424,7 @@ Item {
|
||||
width: parent.width
|
||||
height: parent.height - y
|
||||
clip: true
|
||||
interactive: assetsView.verticalScrollBarVisible
|
||||
interactive: assetsView.verticalScrollBarVisible && !contextMenu.opened
|
||||
|
||||
Column {
|
||||
Repeater {
|
||||
|
@@ -246,6 +246,7 @@ Item {
|
||||
id: verticalScrollView
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
interactive: !itemContextMenu.opened && !moduleContextMenu.opened
|
||||
|
||||
onContentHeightChanged: {
|
||||
var maxPosition = Math.max(contentHeight - verticalScrollView.height, 0)
|
||||
@@ -362,6 +363,7 @@ Item {
|
||||
width: 270
|
||||
height: parent.height
|
||||
clip: true
|
||||
interactive: !itemContextMenu.opened && !moduleContextMenu.opened
|
||||
|
||||
onContentHeightChanged: {
|
||||
var maxPosition = Math.max(contentHeight - horizontalScrollView.height, 0)
|
||||
|
@@ -99,7 +99,7 @@ PropertyEditorPane {
|
||||
anchors.right: parent.right
|
||||
|
||||
StudioControls.TabButton {
|
||||
text: backendValues.className.value
|
||||
text: backendValues.__classNamePrivateInternal.value
|
||||
}
|
||||
StudioControls.TabButton {
|
||||
text: qsTr("Layout")
|
||||
|
@@ -56,13 +56,13 @@ Section {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: StudioTheme.Values.inputHorizontalPadding
|
||||
anchors.topMargin: StudioTheme.Values.typeLabelVerticalShift
|
||||
text: backendValues.className.value
|
||||
text: backendValues.__classNamePrivateInternal.value
|
||||
}
|
||||
|
||||
ToolTipArea {
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: {
|
||||
typeLineEdit.text = backendValues.className.value
|
||||
typeLineEdit.text = backendValues.__classNamePrivateInternal.value
|
||||
typeLineEdit.visible = !typeLineEdit.visible
|
||||
typeLineEdit.forceActiveFocus()
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ QtObject {
|
||||
property real contextMenuHorizontalPadding: Math.round(6 * values.scaleFactor)
|
||||
|
||||
property real inputHorizontalPadding: Math.round(6 * values.scaleFactor)
|
||||
property real typeLabelVerticalShift: Math.round(5 * values.scaleFactor)
|
||||
property real typeLabelVerticalShift: Math.round(6 * values.scaleFactor)
|
||||
|
||||
property real scrollBarThickness: 10
|
||||
|
||||
|
@@ -1,5 +1,12 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
@@ -1,5 +1,12 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
CheckBox {
|
||||
id: control
|
||||
|
@@ -1,5 +1,12 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Dial {
|
||||
id: control
|
||||
|
@@ -1,5 +1,12 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Slider {
|
||||
id: control
|
||||
|
@@ -1,5 +1,12 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
SpinBox {
|
||||
id: control
|
||||
|
@@ -1,5 +1,12 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Switch {
|
||||
id: control
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
@if %{UseQtQuickControls2}
|
||||
import QtQuick.Controls 2.15
|
||||
@@ -8,6 +15,11 @@ import %{ApplicationImport}
|
||||
import FlowView 1.0
|
||||
|
||||
FlowItem {
|
||||
@if %{UseImport}
|
||||
width: Constants.width
|
||||
height: Constants.height
|
||||
@else
|
||||
width: 800
|
||||
height: 600
|
||||
@endif
|
||||
}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
@if %{UseImport}
|
||||
import %{ApplicationImport}
|
||||
@@ -5,8 +12,13 @@ import %{ApplicationImport}
|
||||
import FlowView 1.0
|
||||
|
||||
FlowView {
|
||||
@if %{UseImport}
|
||||
width: Constants.width
|
||||
height: Constants.height
|
||||
@else
|
||||
width: 800
|
||||
height: 600
|
||||
@endif
|
||||
|
||||
defaultTransition: FlowTransition {
|
||||
id: defaultTransition
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
import %{ApplicationImport}
|
||||
|
||||
Pane {
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
GridView {
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
|
||||
ListView {
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
@if %{UseQtQuickControls2}
|
||||
import QtQuick.Controls 2.15
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
import %{ApplicationImport}
|
||||
|
||||
Item {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
import %{ApplicationImport}
|
||||
|
||||
Item {
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import QtQuick3D %{QtQuick3DVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import Constants 1.0
|
||||
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
|
||||
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
|
||||
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
|
||||
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
|
||||
*/
|
||||
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickVersion}
|
||||
import %{ImportModuleName} %{ImportModuleVersion}
|
||||
|
@@ -438,6 +438,7 @@ bool startCrashpad(const QString &libexecPath, bool crashReportingEnabled)
|
||||
|
||||
// Optional arguments to pass to the handler
|
||||
std::vector<std::string> arguments;
|
||||
arguments.push_back("--no-rate-limit");
|
||||
|
||||
CrashpadClient *client = new CrashpadClient();
|
||||
bool success = client->StartHandler(
|
||||
|
@@ -723,8 +723,10 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
||||
}
|
||||
|
||||
value = pluginMetaData.value(QLatin1String(PLUGIN_METADATA));
|
||||
if (!value.isObject())
|
||||
return reportError(tr("Plugin meta data not found"));
|
||||
if (!value.isObject()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Plugin meta data not found"));
|
||||
}
|
||||
metaData = value.toObject();
|
||||
|
||||
value = metaData.value(QLatin1String(PLUGIN_NAME));
|
||||
@@ -806,10 +808,12 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
||||
const QString platformSpec = value.toString().trimmed();
|
||||
if (!platformSpec.isEmpty()) {
|
||||
platformSpecification.setPattern(platformSpec);
|
||||
if (!platformSpecification.isValid())
|
||||
return reportError(tr("Invalid platform specification \"%1\": %2")
|
||||
if (!platformSpecification.isValid()) {
|
||||
return reportError(::ExtensionSystem::Internal::PluginSpecPrivate::tr(
|
||||
"Invalid platform specification \"%1\": %2")
|
||||
.arg(platformSpec, platformSpecification.errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
value = metaData.value(QLatin1String(DEPENDENCIES));
|
||||
if (!value.isUndefined() && !value.isArray())
|
||||
@@ -822,22 +826,36 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
||||
QJsonObject dependencyObject = v.toObject();
|
||||
PluginDependency dep;
|
||||
value = dependencyObject.value(QLatin1String(DEPENDENCY_NAME));
|
||||
if (value.isUndefined())
|
||||
return reportError(tr("Dependency: %1").arg(msgValueMissing(DEPENDENCY_NAME)));
|
||||
if (!value.isString())
|
||||
return reportError(tr("Dependency: %1").arg(msgValueIsNotAString(DEPENDENCY_NAME)));
|
||||
if (value.isUndefined()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Dependency: %1")
|
||||
.arg(msgValueMissing(DEPENDENCY_NAME)));
|
||||
}
|
||||
if (!value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Dependency: %1")
|
||||
.arg(msgValueIsNotAString(DEPENDENCY_NAME)));
|
||||
}
|
||||
dep.name = value.toString();
|
||||
value = dependencyObject.value(QLatin1String(DEPENDENCY_VERSION));
|
||||
if (!value.isUndefined() && !value.isString())
|
||||
return reportError(tr("Dependency: %1").arg(msgValueIsNotAString(DEPENDENCY_VERSION)));
|
||||
if (!value.isUndefined() && !value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Dependency: %1")
|
||||
.arg(msgValueIsNotAString(DEPENDENCY_VERSION)));
|
||||
}
|
||||
dep.version = value.toString();
|
||||
if (!isValidVersion(dep.version))
|
||||
return reportError(tr("Dependency: %1").arg(msgInvalidFormat(DEPENDENCY_VERSION,
|
||||
dep.version)));
|
||||
if (!isValidVersion(dep.version)) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Dependency: %1")
|
||||
.arg(msgInvalidFormat(DEPENDENCY_VERSION, dep.version)));
|
||||
}
|
||||
dep.type = PluginDependency::Required;
|
||||
value = dependencyObject.value(QLatin1String(DEPENDENCY_TYPE));
|
||||
if (!value.isUndefined() && !value.isString())
|
||||
return reportError(tr("Dependency: %1").arg(msgValueIsNotAString(DEPENDENCY_TYPE)));
|
||||
if (!value.isUndefined() && !value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Dependency: %1")
|
||||
.arg(msgValueIsNotAString(DEPENDENCY_TYPE)));
|
||||
}
|
||||
if (!value.isUndefined()) {
|
||||
const QString typeValue = value.toString();
|
||||
if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_HARD)) {
|
||||
@@ -847,7 +865,9 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
||||
} else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_TEST)) {
|
||||
dep.type = PluginDependency::Test;
|
||||
} else {
|
||||
return reportError(tr("Dependency: \"%1\" must be \"%2\" or \"%3\" (is \"%4\").")
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr(
|
||||
"Dependency: \"%1\" must be \"%2\" or \"%3\" (is \"%4\").")
|
||||
.arg(QLatin1String(DEPENDENCY_TYPE),
|
||||
QLatin1String(DEPENDENCY_TYPE_HARD),
|
||||
QLatin1String(DEPENDENCY_TYPE_SOFT),
|
||||
@@ -869,20 +889,35 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
||||
QJsonObject argumentObject = v.toObject();
|
||||
PluginArgumentDescription arg;
|
||||
value = argumentObject.value(QLatin1String(ARGUMENT_NAME));
|
||||
if (value.isUndefined())
|
||||
return reportError(tr("Argument: %1").arg(msgValueMissing(ARGUMENT_NAME)));
|
||||
if (!value.isString())
|
||||
return reportError(tr("Argument: %1").arg(msgValueIsNotAString(ARGUMENT_NAME)));
|
||||
if (value.isUndefined()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Argument: %1")
|
||||
.arg(msgValueMissing(ARGUMENT_NAME)));
|
||||
}
|
||||
if (!value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Argument: %1")
|
||||
.arg(msgValueIsNotAString(ARGUMENT_NAME)));
|
||||
}
|
||||
arg.name = value.toString();
|
||||
if (arg.name.isEmpty())
|
||||
return reportError(tr("Argument: \"%1\" is empty").arg(QLatin1String(ARGUMENT_NAME)));
|
||||
if (arg.name.isEmpty()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Argument: \"%1\" is empty")
|
||||
.arg(QLatin1String(ARGUMENT_NAME)));
|
||||
}
|
||||
value = argumentObject.value(QLatin1String(ARGUMENT_DESCRIPTION));
|
||||
if (!value.isUndefined() && !value.isString())
|
||||
return reportError(tr("Argument: %1").arg(msgValueIsNotAString(ARGUMENT_DESCRIPTION)));
|
||||
if (!value.isUndefined() && !value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Argument: %1")
|
||||
.arg(msgValueIsNotAString(ARGUMENT_DESCRIPTION)));
|
||||
}
|
||||
arg.description = value.toString();
|
||||
value = argumentObject.value(QLatin1String(ARGUMENT_PARAMETER));
|
||||
if (!value.isUndefined() && !value.isString())
|
||||
return reportError(tr("Argument: %1").arg(msgValueIsNotAString(ARGUMENT_PARAMETER)));
|
||||
if (!value.isUndefined() && !value.isString()) {
|
||||
return reportError(
|
||||
::ExtensionSystem::Internal::PluginSpecPrivate::tr("Argument: %1")
|
||||
.arg(msgValueIsNotAString(ARGUMENT_PARAMETER)));
|
||||
}
|
||||
arg.parameter = value.toString();
|
||||
argumentDescriptions.append(arg);
|
||||
qCDebug(pluginLog) << "Argument:" << arg.name << "Parameter:" << arg.parameter
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <utils/variant.h> // revert when macos minimum target is >= 10.14
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@@ -34,7 +34,6 @@ 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
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
@@ -752,48 +753,6 @@ QString AndroidConfig::getAvdName(const QString &serialnumber)
|
||||
return QString::fromLatin1(name).trimmed();
|
||||
}
|
||||
|
||||
static SdkToolResult emulatorNameAdbCommand(const QString &serialNumber)
|
||||
{
|
||||
QStringList args = AndroidDeviceInfo::adbSelector(serialNumber);
|
||||
args.append({"emu", "avd", "name"});
|
||||
return AndroidManager::runAdbCommand(args);
|
||||
}
|
||||
|
||||
QString AndroidConfig::getRunningAvdsSerialNumber(const QString &name) const
|
||||
{
|
||||
for (const AndroidDeviceInfo &dev : connectedDevices()) {
|
||||
if (!dev.serialNumber.startsWith("emulator"))
|
||||
continue;
|
||||
SdkToolResult result = emulatorNameAdbCommand(dev.serialNumber);
|
||||
const QString stdOut = result.stdOut();
|
||||
if (stdOut.isEmpty())
|
||||
continue; // Not an avd
|
||||
const QStringList outputLines = stdOut.split('\n');
|
||||
if (outputLines.size() > 1 && outputLines.first() == name)
|
||||
return dev.serialNumber;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList AndroidConfig::getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs)
|
||||
{
|
||||
QStringList runningDevs;
|
||||
for (const AndroidDeviceInfo &dev : devs) {
|
||||
if (!dev.serialNumber.startsWith("emulator"))
|
||||
continue;
|
||||
SdkToolResult result = emulatorNameAdbCommand(dev.serialNumber);
|
||||
const QString stdOut = result.stdOut();
|
||||
if (stdOut.isEmpty())
|
||||
continue; // Not an avd
|
||||
const QStringList outputLines = stdOut.split('\n');
|
||||
if (outputLines.size() > 1)
|
||||
runningDevs.append(outputLines.first());
|
||||
}
|
||||
|
||||
return runningDevs;
|
||||
}
|
||||
|
||||
AndroidConfig::OpenGl AndroidConfig::getOpenGLEnabled(const QString &emulator) const
|
||||
{
|
||||
QDir dir = QDir::home();
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
@@ -176,15 +177,12 @@ public:
|
||||
|
||||
static Utils::FilePath getJdkPath();
|
||||
static QStringList getAbis(const QString &device);
|
||||
|
||||
QString getRunningAvdsSerialNumber(const QString &name) const;
|
||||
static QStringList getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs);
|
||||
static int getSDKVersion(const QString &device);
|
||||
|
||||
private:
|
||||
static QString getDeviceProperty(const QString &device, const QString &property);
|
||||
|
||||
Utils::FilePath openJDKBinPath() const;
|
||||
static int getSDKVersion(const QString &device);
|
||||
static QString getAvdName(const QString &serialnumber);
|
||||
|
||||
void parseDependenciesJson();
|
||||
|
@@ -182,7 +182,7 @@ bool AndroidDeployQtStep::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dev->canSupportAbis(selectedAbis)) {
|
||||
if (!selectedAbis.isEmpty() && !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\".")
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
@@ -52,6 +52,10 @@
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
@@ -59,9 +63,6 @@ namespace {
|
||||
static Q_LOGGING_CATEGORY(androidDeviceLog, "qtc.android.androiddevice", QtWarningMsg)
|
||||
}
|
||||
|
||||
// interval for updating the list of connected Android devices and emulators
|
||||
constexpr int deviceUpdaterMsInterval = 30000;
|
||||
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
@@ -328,7 +329,7 @@ QString AndroidDevice::serialNumber() const
|
||||
if (machineType() == Hardware)
|
||||
return serialNumber;
|
||||
|
||||
return AndroidConfigurations::currentConfig().getRunningAvdsSerialNumber(avdName());
|
||||
return AndroidDeviceManager::instance()->getRunningAvdsSerialNumber(avdName());
|
||||
}
|
||||
|
||||
QString AndroidDevice::avdName() const
|
||||
@@ -419,36 +420,28 @@ QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
|
||||
return url;
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::updateDevicesList()
|
||||
void AndroidDeviceManager::updateAvdsList()
|
||||
{
|
||||
// If a non-Android Kit is currently active, skip the device list update
|
||||
const Target *startupTarget = SessionManager::startupTarget();
|
||||
if (!startupTarget)
|
||||
return;
|
||||
|
||||
const Kit *kit = startupTarget->kit();
|
||||
if (!kit)
|
||||
return;
|
||||
|
||||
if (DeviceTypeKitAspect::deviceTypeId(kit) != Constants::ANDROID_DEVICE_TYPE)
|
||||
return;
|
||||
|
||||
updateDevicesListOnce();
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::updateDevicesListOnce()
|
||||
{
|
||||
if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists()) {
|
||||
if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists())
|
||||
m_avdsFutureWatcher.setFuture(m_avdManager.avdList());
|
||||
m_devicesFutureWatcher.setFuture(Utils::runAsync([this]() {
|
||||
return m_androidConfig.connectedDevices();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::updateDeviceState(const ProjectExplorer::IDevice::Ptr &device)
|
||||
IDevice::DeviceState AndroidDeviceManager::getDeviceState(const QString &serial,
|
||||
IDevice::MachineType type) const
|
||||
{
|
||||
const AndroidDevice *dev = static_cast<AndroidDevice *>(device.data());
|
||||
const QStringList args = AndroidDeviceInfo::adbSelector(serial) << "shell" << "echo 1";
|
||||
const SdkToolResult result = AndroidManager::runAdbCommand(args);
|
||||
if (result.success())
|
||||
return IDevice::DeviceReadyToUse;
|
||||
else if (type == IDevice::Emulator || result.stdErr().contains("unauthorized"))
|
||||
return IDevice::DeviceConnected;
|
||||
|
||||
return IDevice::DeviceDisconnected;
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::updateDeviceState(const ProjectExplorer::IDevice::ConstPtr &device)
|
||||
{
|
||||
const AndroidDevice *dev = static_cast<const AndroidDevice *>(device.data());
|
||||
const QString serial = dev->serialNumber();
|
||||
DeviceManager *const devMgr = DeviceManager::instance();
|
||||
const Utils::Id id = dev->id();
|
||||
@@ -457,15 +450,7 @@ void AndroidDeviceManager::updateDeviceState(const ProjectExplorer::IDevice::Ptr
|
||||
return;
|
||||
}
|
||||
|
||||
const QStringList args = AndroidDeviceInfo::adbSelector(serial) << "shell" << "echo" << "1";
|
||||
const SdkToolResult result = AndroidManager::runAdbCommand(args);
|
||||
const int success = result.success();
|
||||
if (success)
|
||||
devMgr->setDeviceState(id, IDevice::DeviceReadyToUse);
|
||||
else if (dev->machineType() == IDevice::Emulator || result.stdErr().contains("unauthorized"))
|
||||
devMgr->setDeviceState(id, IDevice::DeviceConnected);
|
||||
else
|
||||
devMgr->setDeviceState(id, IDevice::DeviceDisconnected);
|
||||
devMgr->setDeviceState(id, getDeviceState(serial, dev->machineType()));
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::startAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent)
|
||||
@@ -523,6 +508,13 @@ void AndroidDeviceManager::handleAvdRemoved()
|
||||
}
|
||||
}
|
||||
|
||||
QString AndroidDeviceManager::emulatorName(const QString &serialNumber) const
|
||||
{
|
||||
QStringList args = AndroidDeviceInfo::adbSelector(serialNumber);
|
||||
args.append({"emu", "avd", "name"});
|
||||
return AndroidManager::runAdbCommand(args).stdOut();
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::setEmulatorArguments(QWidget *parent)
|
||||
{
|
||||
const QString helpUrl =
|
||||
@@ -546,73 +538,122 @@ void AndroidDeviceManager::setEmulatorArguments(QWidget *parent)
|
||||
m_androidConfig.setEmulatorArgs(Utils::ProcessArgs::splitArgs(dialog.textValue()));
|
||||
}
|
||||
|
||||
QString AndroidDeviceManager::getRunningAvdsSerialNumber(const QString &name) const
|
||||
{
|
||||
for (const AndroidDeviceInfo &dev : m_androidConfig.connectedDevices()) {
|
||||
if (!dev.serialNumber.startsWith("emulator"))
|
||||
continue;
|
||||
const QString stdOut = emulatorName(dev.serialNumber);
|
||||
if (stdOut.isEmpty())
|
||||
continue; // Not an avd
|
||||
const QStringList outputLines = stdOut.split('\n');
|
||||
if (outputLines.size() > 1 && outputLines.first() == name)
|
||||
return dev.serialNumber;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::setupDevicesWatcher()
|
||||
{
|
||||
if (!m_devicesUpdaterTimer.isActive()) {
|
||||
// The call to avdmanager is always slower than the call to adb devices,
|
||||
// so connecting the slot to the slower call should be enough.
|
||||
connect(&m_avdsFutureWatcher, &QFutureWatcherBase::finished,
|
||||
this, &AndroidDeviceManager::devicesListUpdated);
|
||||
connect(&m_devicesUpdaterTimer, &QTimer::timeout, this, [this]() {
|
||||
updateDevicesList();
|
||||
if (!m_androidConfig.adbToolPath().exists()) {
|
||||
qCDebug(androidDeviceLog) << "Cannot start ADB device watcher"
|
||||
<< "because adb path does not exist.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_adbDeviceWatcherProcess)
|
||||
m_adbDeviceWatcherProcess.reset(new Utils::QtcProcess(this));
|
||||
|
||||
if (m_adbDeviceWatcherProcess->isRunning()) {
|
||||
qCDebug(androidDeviceLog) << "ADB device watcher is already running.";
|
||||
return;
|
||||
}
|
||||
|
||||
connect(m_adbDeviceWatcherProcess.get(), &Utils::QtcProcess::finished, this,
|
||||
[]() { qCDebug(androidDeviceLog) << "ADB device watcher finished."; });
|
||||
|
||||
connect(m_adbDeviceWatcherProcess.get(), &Utils::QtcProcess::errorOccurred, this,
|
||||
[this](QProcess::ProcessError) {
|
||||
qCDebug(androidDeviceLog) << "ADB device watcher encountered an error:"
|
||||
<< m_adbDeviceWatcherProcess->errorString();
|
||||
if (!m_adbDeviceWatcherProcess->isRunning()) {
|
||||
qCDebug(androidDeviceLog) << "Restarting the ADB device watcher now.";
|
||||
QTimer::singleShot(0, m_adbDeviceWatcherProcess.get(), &Utils::QtcProcess::start);
|
||||
}
|
||||
});
|
||||
m_devicesUpdaterTimer.start(deviceUpdaterMsInterval);
|
||||
|
||||
m_adbDeviceWatcherProcess->setStdErrLineCallback([](const QString &error) {
|
||||
qCDebug(androidDeviceLog) << "ADB device watcher error" << error; });
|
||||
m_adbDeviceWatcherProcess->setStdOutLineCallback([this](const QString &output) {
|
||||
HandleDevicesListChange(output);
|
||||
});
|
||||
|
||||
const Utils::CommandLine command = Utils::CommandLine(m_androidConfig.adbToolPath(),
|
||||
{"track-devices"});
|
||||
m_adbDeviceWatcherProcess->setCommand(command);
|
||||
m_adbDeviceWatcherProcess->setEnvironment(AndroidConfigurations::toolsEnvironment(m_androidConfig));
|
||||
m_adbDeviceWatcherProcess->start();
|
||||
|
||||
// Setup AVD filesystem watcher to listen for changes when an avd is created/deleted,
|
||||
// or started/stopped
|
||||
QString avdEnvVar = qEnvironmentVariable("ANDROID_AVD_HOME");
|
||||
if (avdEnvVar.isEmpty()) {
|
||||
avdEnvVar = qEnvironmentVariable("ANDROID_SDK_HOME");
|
||||
if (avdEnvVar.isEmpty())
|
||||
avdEnvVar = qEnvironmentVariable("HOME");
|
||||
avdEnvVar.append("/.android/avd");
|
||||
}
|
||||
updateDevicesListOnce();
|
||||
const Utils::FilePath avdPath = Utils::FilePath::fromUserInput(avdEnvVar);
|
||||
m_avdFileSystemWatcher.addPath(avdPath.toString());
|
||||
connect(&m_avdsFutureWatcher, &QFutureWatcherBase::finished,
|
||||
this, &AndroidDeviceManager::HandleAvdsListChange);
|
||||
connect(&m_avdFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, [this]() {
|
||||
// If the avd list upate command is running no need to call it again.
|
||||
if (!m_avdsFutureWatcher.isRunning())
|
||||
updateAvdsList();
|
||||
});
|
||||
// Call initial update
|
||||
updateAvdsList();
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::devicesListUpdated()
|
||||
void AndroidDeviceManager::HandleAvdsListChange()
|
||||
{
|
||||
QVector<AndroidDeviceInfo> connectedDevicesInfos;
|
||||
connectedDevicesInfos = m_devicesFutureWatcher.result();
|
||||
|
||||
// For checking the state of avds, since running avds are assigned a serial number of
|
||||
// the form emulator-xxxx, thus we have to manually check for the names.
|
||||
const QStringList runningAvds = m_androidConfig.getRunningAvdsFromDevices(connectedDevicesInfos);
|
||||
|
||||
AndroidDeviceInfoList devices = m_avdsFutureWatcher.result();
|
||||
const QSet<QString> startedAvds = Utils::transform<QSet>(connectedDevicesInfos,
|
||||
&AndroidDeviceInfo::avdname);
|
||||
for (const AndroidDeviceInfo &dev : devices)
|
||||
if (!startedAvds.contains(dev.avdname))
|
||||
connectedDevicesInfos << dev;
|
||||
|
||||
DeviceManager *const devMgr = DeviceManager::instance();
|
||||
|
||||
QVector<IDevice::ConstPtr> existingDevs;
|
||||
QVector<IDevice::ConstPtr> connectedDevs;
|
||||
|
||||
QVector<IDevice::ConstPtr> existingAvds;
|
||||
for (int i = 0; i < devMgr->deviceCount(); ++i) {
|
||||
const IDevice::ConstPtr dev = devMgr->deviceAt(i);
|
||||
if (dev->id().toString().startsWith(Constants::ANDROID_DEVICE_ID)) {
|
||||
existingDevs.append(dev);
|
||||
}
|
||||
const bool isEmulator = dev->machineType() == IDevice::Emulator;
|
||||
if (isEmulator && dev->type() == Constants::ANDROID_DEVICE_TYPE)
|
||||
existingAvds.append(dev);
|
||||
}
|
||||
|
||||
for (auto item : connectedDevicesInfos) {
|
||||
QVector<IDevice::ConstPtr> connectedDevs;
|
||||
for (auto item : m_avdsFutureWatcher.result()) {
|
||||
const Utils::Id deviceId = AndroidDevice::idFromDeviceInfo(item);
|
||||
const QString displayName = AndroidDevice::displayNameFromInfo(item);
|
||||
IDevice::ConstPtr dev = devMgr->find(deviceId);
|
||||
if (!dev.isNull()) {
|
||||
if (dev->displayName() == displayName) {
|
||||
IDevice::DeviceState newState;
|
||||
// If an AVD is not already running set its state to Connected instead of
|
||||
// ReadyToUse.
|
||||
if (dev->machineType() == IDevice::Emulator && !runningAvds.contains(displayName))
|
||||
newState = IDevice::DeviceConnected;
|
||||
else
|
||||
newState = item.state;
|
||||
if (dev->deviceState() != newState) {
|
||||
const auto androidDev = static_cast<const AndroidDevice *>(dev.data());
|
||||
// DeviceManager doens't seem to hav a way to directly update the name, if the name
|
||||
// of the device has changed, remove it and register it again with the new name.
|
||||
// Also account for the case of an AVD registered through old QC which might have
|
||||
// invalid data by checking the sdcard size value.
|
||||
if (dev->displayName() != displayName
|
||||
|| androidDev->sdcardSize() == AndroidDevice::tr("Unknown")) {
|
||||
devMgr->removeDevice(dev->id());
|
||||
} else {
|
||||
// Find the state of the AVD retrieved from the AVD watcher
|
||||
const QString serial = getRunningAvdsSerialNumber(item.avdname);
|
||||
const IDevice::DeviceState state = getDeviceState(serial, IDevice::Emulator);
|
||||
if (dev->deviceState() != state) {
|
||||
devMgr->setDeviceState(dev->id(), state);
|
||||
qCDebug(androidDeviceLog, "Device id \"%s\" changed its state.",
|
||||
dev->id().toString().toUtf8().data());
|
||||
devMgr->setDeviceState(dev->id(), newState);
|
||||
}
|
||||
connectedDevs.append(dev);
|
||||
continue;
|
||||
} else {
|
||||
// DeviceManager doens't seem to hav a way to directly update the name, if the name
|
||||
// of the device has changed, remove it and register it again with the new name.
|
||||
devMgr->removeDevice(dev->id());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,17 +666,86 @@ void AndroidDeviceManager::devicesListUpdated()
|
||||
qCDebug(androidDeviceLog, "Registering new Android device id \"%s\".",
|
||||
newDev->id().toString().toUtf8().data());
|
||||
const IDevice::ConstPtr constNewDev = IDevice::ConstPtr(newDev);
|
||||
devMgr->addDevice(constNewDev);
|
||||
devMgr->addDevice(IDevice::ConstPtr(constNewDev));
|
||||
connectedDevs.append(constNewDev);
|
||||
}
|
||||
|
||||
// Set devices no longer connected to disconnected state.
|
||||
for (const IDevice::ConstPtr &dev : existingDevs) {
|
||||
if (dev->id() != Constants::ANDROID_DEVICE_ID && !connectedDevs.contains(dev)
|
||||
&& dev->deviceState() != IDevice::DeviceDisconnected) {
|
||||
qCDebug(androidDeviceLog, "Device id \"%s\" is no longer connected.",
|
||||
for (const IDevice::ConstPtr &dev : existingAvds) {
|
||||
if (!connectedDevs.contains(dev)) {
|
||||
qCDebug(androidDeviceLog, "Removing AVD id \"%s\" because it no longer exists.",
|
||||
dev->id().toString().toUtf8().data());
|
||||
devMgr->setDeviceState(dev->id(), IDevice::DeviceDisconnected);
|
||||
devMgr->removeDevice(dev->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidDeviceManager::HandleDevicesListChange(const QString &serialNumber)
|
||||
{
|
||||
DeviceManager *const devMgr = DeviceManager::instance();
|
||||
const QStringList serialBits = serialNumber.split('\t');
|
||||
if (serialBits.size() < 2)
|
||||
return;
|
||||
|
||||
// Sample output of adb track-devices, the first 4 digits are for state type
|
||||
// and sometimes 4 zeros are reported as part for the serial number.
|
||||
// 00546db0e8d7 authorizing
|
||||
// 00546db0e8d7 device
|
||||
// 0000001711201JEC207789 offline
|
||||
// emulator-5554 device
|
||||
QString dirtySerial = serialBits.first().trimmed();
|
||||
if (dirtySerial.startsWith("0000"))
|
||||
dirtySerial = dirtySerial.mid(4);
|
||||
if (dirtySerial.startsWith("00"))
|
||||
dirtySerial = dirtySerial.mid(4);
|
||||
const bool isEmulator = dirtySerial.startsWith("emulator");
|
||||
|
||||
const QString &serial = dirtySerial;
|
||||
const QString stateStr = serialBits.at(1).trimmed();
|
||||
|
||||
IDevice::DeviceState state;
|
||||
if (stateStr == "device")
|
||||
state = IDevice::DeviceReadyToUse;
|
||||
else if (stateStr == "offline")
|
||||
state = IDevice::DeviceDisconnected;
|
||||
else
|
||||
state = IDevice::DeviceConnected;
|
||||
|
||||
if (isEmulator) {
|
||||
const QString avdName = emulatorName(serial);
|
||||
const Utils::Id avdId = Utils::Id(Constants::ANDROID_DEVICE_ID).withSuffix(':' + avdName);
|
||||
devMgr->setDeviceState(avdId, state);
|
||||
} else {
|
||||
const Utils::Id id = Utils::Id(Constants::ANDROID_DEVICE_ID).withSuffix(':' + serial);
|
||||
QString displayName = AndroidConfigurations::currentConfig().getProductModel(serial);
|
||||
// Check if the device is connected via WiFi. A sample serial of such devices can be
|
||||
// like: "192.168.1.190:5555"
|
||||
const QRegularExpression wifiSerialRegExp(
|
||||
QLatin1String("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d{1,5})"));
|
||||
if (wifiSerialRegExp.match(serial).hasMatch())
|
||||
displayName += QLatin1String(" (WiFi)");
|
||||
|
||||
if (IDevice::ConstPtr dev = devMgr->find(id)) {
|
||||
// DeviceManager doens't seem to have a way to directly update the name, if the name
|
||||
// of the device has changed, remove it and register it again with the new name.
|
||||
if (dev->displayName() == displayName)
|
||||
devMgr->setDeviceState(id, state);
|
||||
else
|
||||
devMgr->removeDevice(id);
|
||||
} else {
|
||||
AndroidDevice *newDev = new AndroidDevice();
|
||||
newDev->setupId(IDevice::AutoDetected, id);
|
||||
newDev->setDisplayName(displayName);
|
||||
newDev->setMachineType(IDevice::Hardware);
|
||||
newDev->setDeviceState(state);
|
||||
|
||||
newDev->setExtraData(Constants::AndroidSerialNumber, serial);
|
||||
newDev->setExtraData(Constants::AndroidCpuAbi, m_androidConfig.getAbis(serial));
|
||||
newDev->setExtraData(Constants::AndroidSdk, m_androidConfig.getSDKVersion(serial));
|
||||
|
||||
qCDebug(androidDeviceLog, "Registering new Android device id \"%s\".",
|
||||
newDev->id().toString().toUtf8().data());
|
||||
devMgr->addDevice(IDevice::ConstPtr(newDev));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -652,9 +762,12 @@ AndroidDeviceManager::AndroidDeviceManager(QObject *parent)
|
||||
m_avdManager(m_androidConfig)
|
||||
{
|
||||
connect(qApp, &QCoreApplication::aboutToQuit, this, [this]() {
|
||||
m_devicesUpdaterTimer.stop();
|
||||
if (m_adbDeviceWatcherProcess) {
|
||||
m_adbDeviceWatcherProcess->terminate();
|
||||
m_adbDeviceWatcherProcess->waitForFinished();
|
||||
m_adbDeviceWatcherProcess.reset();
|
||||
}
|
||||
m_avdsFutureWatcher.waitForFinished();
|
||||
m_devicesFutureWatcher.waitForFinished();
|
||||
m_removeAvdFutureWatcher.waitForFinished();
|
||||
});
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
@@ -33,8 +33,10 @@
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/devicesupport/idevicefactory.h>
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QTimer>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
@@ -70,6 +72,7 @@ public:
|
||||
QString androidTargetName() const;
|
||||
QString sdcardSize() const;
|
||||
QString openGlStatusString() const;
|
||||
// TODO: remove not used
|
||||
AndroidConfig::OpenGl openGlStatus() const;
|
||||
|
||||
protected:
|
||||
@@ -98,24 +101,29 @@ class AndroidDeviceManager : public QObject
|
||||
public:
|
||||
static AndroidDeviceManager *instance();
|
||||
void setupDevicesWatcher();
|
||||
void updateDevicesList();
|
||||
void updateDevicesListOnce();
|
||||
void updateDeviceState(const ProjectExplorer::IDevice::Ptr &device);
|
||||
void updateAvdsList();
|
||||
IDevice::DeviceState getDeviceState(const QString &serial, IDevice::MachineType type) const;
|
||||
void updateDeviceState(const ProjectExplorer::IDevice::ConstPtr &device);
|
||||
|
||||
void startAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent = nullptr);
|
||||
void eraseAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent = nullptr);
|
||||
|
||||
void setEmulatorArguments(QWidget *parent = nullptr);
|
||||
|
||||
QString getRunningAvdsSerialNumber(const QString &name) const;
|
||||
|
||||
private:
|
||||
AndroidDeviceManager(QObject *parent = nullptr);
|
||||
void devicesListUpdated();
|
||||
void HandleDevicesListChange(const QString &serialNumber);
|
||||
void HandleAvdsListChange();
|
||||
void handleAvdRemoved();
|
||||
|
||||
QString emulatorName(const QString &serialNumber) const;
|
||||
|
||||
QFutureWatcher<AndroidDeviceInfoList> m_avdsFutureWatcher;
|
||||
QFutureWatcher<QVector<AndroidDeviceInfo>> m_devicesFutureWatcher;
|
||||
QFutureWatcher<QPair<ProjectExplorer::IDevice::ConstPtr, bool>> m_removeAvdFutureWatcher;
|
||||
QTimer m_devicesUpdaterTimer;
|
||||
QFileSystemWatcher m_avdFileSystemWatcher;
|
||||
std::unique_ptr<Utils::QtcProcess> m_adbDeviceWatcherProcess;
|
||||
AndroidConfig &m_androidConfig;
|
||||
AndroidAvdManager m_avdManager;
|
||||
};
|
||||
|
@@ -2779,6 +2779,8 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
||||
|| path.rbegin()->kind() == "CXXConstruct")) {
|
||||
return false;
|
||||
}
|
||||
if (path.rbegin()->hasConstType())
|
||||
return false;
|
||||
for (auto it = path.rbegin() + 1; it != path.rend(); ++it) {
|
||||
if (it->kind() == "Call" || it->kind() == "CXXConstruct"
|
||||
|| it->kind() == "MemberInitializer") {
|
||||
@@ -2810,8 +2812,9 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
||||
const AstNode n = firstChildTree.takeFirst();
|
||||
const QString detail = n.detail().value_or(QString());
|
||||
if (detail.startsWith("operator")) {
|
||||
return !detail.contains('=') && !detail.contains("++")
|
||||
&& !detail.contains("--");
|
||||
return !detail.contains('=')
|
||||
&& !detail.contains("++") && !detail.contains("--")
|
||||
&& !detail.contains("<<") && !detail.contains(">>");
|
||||
}
|
||||
firstChildTree << n.children().value_or(QList<AstNode>());
|
||||
}
|
||||
@@ -4122,7 +4125,7 @@ class MemoryTreeModel : public Utils::BaseTreeModel
|
||||
public:
|
||||
MemoryTreeModel(QObject *parent) : BaseTreeModel(parent)
|
||||
{
|
||||
setHeader({tr("Component"), tr("Total Memory")});
|
||||
setHeader({MemoryUsageWidget::tr("Component"), MemoryUsageWidget::tr("Total Memory")});
|
||||
}
|
||||
|
||||
void update(const MemoryTree &tree)
|
||||
|
@@ -1295,6 +1295,13 @@ void ClangdTestHighlighting::test_data()
|
||||
QTest::newRow("keywords: true") << 920 << 15 << 920 << 19 << QList<int>{C_KEYWORD} << 0;
|
||||
QTest::newRow("keywords: false") << 921 << 15 << 921 << 20 << QList<int>{C_KEYWORD} << 0;
|
||||
QTest::newRow("keywords: nullptr") << 922 << 15 << 922 << 22 << QList<int>{C_KEYWORD} << 0;
|
||||
QTest::newRow("operator<<") << 934 << 10 << 934 << 14 << QList<int>{C_GLOBAL} << 0;
|
||||
QTest::newRow("operator>>") << 936 << 10 << 936 << 13 << QList<int>{C_GLOBAL} << 0;
|
||||
QTest::newRow("operator>>") << 936 << 17 << 936 << 18 << QList<int>{C_LOCAL} << 0;
|
||||
QTest::newRow("input arg from passed object") << 945 << 17 << 945 << 18
|
||||
<< QList<int>{C_FIELD} << 0;
|
||||
QTest::newRow("output arg") << 945 << 20 << 945 << 23
|
||||
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
|
||||
}
|
||||
|
||||
void ClangdTestHighlighting::test()
|
||||
|
@@ -921,3 +921,26 @@ void keywords()
|
||||
bool b2 = false;
|
||||
void *p = nullptr;
|
||||
}
|
||||
|
||||
namespace std {
|
||||
struct Debug {};
|
||||
Debug& operator<<(Debug &dbg, int) { return dbg; }
|
||||
Debug& operator>>(Debug &dbg, int&) { return dbg; }
|
||||
static Debug cout;
|
||||
static Debug cin;
|
||||
}
|
||||
void outputOperator()
|
||||
{
|
||||
std::cout << 0;
|
||||
int i;
|
||||
std::cin >> i;
|
||||
}
|
||||
|
||||
template <typename To, typename From, typename Op>
|
||||
void transform(const From &from, To &&to, Op op) {}
|
||||
struct WithVector { std::vector<int> v; };
|
||||
void inputsAndOutputsFromObject(const WithVector &s)
|
||||
{
|
||||
std::vector<int> out;
|
||||
transform(s.v, out, [] {});
|
||||
}
|
||||
|
@@ -268,7 +268,7 @@ bool ConfigModel::hasChanges(bool initialParameters) const
|
||||
return initialParameters ? i.isInitial : !i.isInitial;
|
||||
});
|
||||
|
||||
return Utils::contains(filtered, [initialParameters](const InternalDataItem &i) {
|
||||
return Utils::contains(filtered, [](const InternalDataItem &i) {
|
||||
return i.isUserChanged || i.isUserNew || i.isUnset;
|
||||
});
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/settingsutils.h>
|
||||
|
||||
static const char groupPostfix[] = "IndentSettings";
|
||||
static const char indentBlockBracesKey[] = "IndentBlockBraces";
|
||||
static const char indentBlockBodyKey[] = "IndentBlockBody";
|
||||
static const char indentClassBracesKey[] = "IndentClassBraces";
|
||||
|
@@ -276,8 +276,6 @@ void ImageView::doScale(qreal factor)
|
||||
void ImageView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
qreal factor = qPow(Constants::DEFAULT_SCALE_FACTOR, event->angleDelta().y() / 240.0);
|
||||
qreal currentScale = transform().m11();
|
||||
qreal newScale = currentScale * factor;
|
||||
// cap to 0.001 - 1000
|
||||
qreal actualFactor = qBound(0.001, factor, 1000.0);
|
||||
doScale(actualFactor);
|
||||
|
@@ -622,7 +622,7 @@ void Client::activateDocument(TextEditor::TextDocument *document)
|
||||
|
||||
void Client::deactivateDocument(TextEditor::TextDocument *document)
|
||||
{
|
||||
m_diagnosticManager.hideDiagnostics(document);
|
||||
m_diagnosticManager.hideDiagnostics(document->filePath());
|
||||
resetAssistProviders(document);
|
||||
document->setFormatter(nullptr);
|
||||
m_tokenSupport.clearHighlight(document);
|
||||
@@ -1628,12 +1628,8 @@ 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();
|
||||
if (errorValue.has_value()) {
|
||||
ShutdownRequest::Response::Error error = errorValue.value();
|
||||
qDebug() << error;
|
||||
return;
|
||||
}
|
||||
if (optional<ShutdownRequest::Response::Error> error = shutdownResponse.error())
|
||||
log(*error);
|
||||
// directly send message otherwise the state check of sendContent would fail
|
||||
sendMessage(ExitNotification().toBaseMessage());
|
||||
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
|
||||
|
@@ -88,26 +88,19 @@ void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
|
||||
const Utils::optional<int> &version)
|
||||
{
|
||||
removeDiagnostics(uri);
|
||||
hideDiagnostics(uri.toFilePath());
|
||||
m_diagnostics[uri] = {version, diagnostics};
|
||||
}
|
||||
|
||||
void DiagnosticManager::hideDiagnostics(TextDocument *doc)
|
||||
void DiagnosticManager::hideDiagnostics(const Utils::FilePath &filePath)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
if (m_hideHandler)
|
||||
m_hideHandler();
|
||||
if (auto doc = TextDocument::textDocumentForFilePath(filePath)) {
|
||||
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc))
|
||||
editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, {});
|
||||
qDeleteAll(Utils::filtered(doc->marks(), Utils::equal(&TextMark::category, m_client->id())));
|
||||
}
|
||||
|
||||
void DiagnosticManager::removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri)
|
||||
{
|
||||
hideDiagnostics(TextDocument::textDocumentForFilePath(uri.toFilePath()));
|
||||
m_diagnostics.remove(uri);
|
||||
qDeleteAll(m_marks.take(filePath));
|
||||
}
|
||||
|
||||
static QTextEdit::ExtraSelection toDiagnosticsSelections(const Diagnostic &diagnostic,
|
||||
@@ -134,7 +127,7 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
|
||||
if (versionedDiagnostics.version.value_or(version) == version) {
|
||||
for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) {
|
||||
extraSelections << toDiagnosticsSelections(diagnostic, doc->document());
|
||||
doc->addMark(m_textMarkCreator(filePath, diagnostic));
|
||||
m_marks[filePath].append(m_textMarkCreator(filePath, diagnostic));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +157,13 @@ TextEditor::TextMark *DiagnosticManager::createTextMark(const FilePath &filePath
|
||||
void DiagnosticManager::clearDiagnostics()
|
||||
{
|
||||
for (const DocumentUri &uri : m_diagnostics.keys())
|
||||
removeDiagnostics(uri);
|
||||
hideDiagnostics(uri.toFilePath());
|
||||
m_diagnostics.clear();
|
||||
if (!QTC_GUARD(m_marks.isEmpty())) {
|
||||
for (const QList<TextEditor::TextMark *> &marks : qAsConst(m_marks))
|
||||
qDeleteAll(marks);
|
||||
m_marks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri,
|
||||
|
@@ -56,10 +56,9 @@ public:
|
||||
void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri,
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
|
||||
const Utils::optional<int> &version);
|
||||
void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
|
||||
|
||||
void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri, int version);
|
||||
void hideDiagnostics(TextEditor::TextDocument *doc);
|
||||
void hideDiagnostics(const Utils::FilePath &filePath);
|
||||
|
||||
void clearDiagnostics();
|
||||
|
||||
@@ -81,6 +80,7 @@ private:
|
||||
QList<LanguageServerProtocol::Diagnostic> diagnostics;
|
||||
};
|
||||
QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics;
|
||||
QMap<Utils::FilePath, QList<TextEditor::TextMark *>> m_marks;
|
||||
TextMarkCreator m_textMarkCreator;
|
||||
HideDiagnosticsHandler m_hideHandler;
|
||||
Client *m_client;
|
||||
|
@@ -427,7 +427,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
|
||||
items = Utils::get<QList<CompletionItem>>(*result);
|
||||
}
|
||||
auto proposalItems = generateCompletionItems(items);
|
||||
if (!proposalItems.isEmpty() && !m_snippetsGroup.isEmpty()) {
|
||||
if (!m_snippetsGroup.isEmpty()) {
|
||||
proposalItems << TextEditor::SnippetAssistCollector(
|
||||
m_snippetsGroup, QIcon(":/texteditor/images/snippet.png")).collect();
|
||||
}
|
||||
|
@@ -45,22 +45,22 @@ public:
|
||||
ValidPackage
|
||||
};
|
||||
|
||||
virtual QString label() const = 0;
|
||||
virtual const QString &environmentVariableName() const = 0;
|
||||
virtual bool isAddToSystemPath() const = 0;
|
||||
virtual void setVersions(const QStringList &) = 0;
|
||||
|
||||
virtual Utils::FilePath basePath() const = 0;
|
||||
virtual Utils::FilePath path() const = 0;
|
||||
virtual QString label() const = 0;
|
||||
virtual Utils::FilePath defaultPath() const = 0;
|
||||
virtual QString detectionPath() const = 0;
|
||||
virtual QString statusText() const = 0;
|
||||
virtual void updateStatus() = 0;
|
||||
virtual Utils::FilePath detectionPath() const = 0;
|
||||
|
||||
virtual void updateStatus() = 0;
|
||||
virtual Status status() const = 0;
|
||||
virtual bool validStatus() const = 0;
|
||||
virtual const QString &environmentVariableName() const = 0;
|
||||
virtual void setAddToPath(bool) = 0;
|
||||
virtual bool addToPath() const = 0;
|
||||
virtual QString statusText() const = 0;
|
||||
virtual bool isValidStatus() const = 0;
|
||||
|
||||
virtual bool writeToSettings() const = 0;
|
||||
virtual void setRelativePathModifier(const QString &) = 0;
|
||||
virtual void setVersions(const QStringList &) = 0;
|
||||
|
||||
virtual QWidget *widget() = 0;
|
||||
|
||||
|
@@ -57,30 +57,21 @@ 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:
|
||||
switch (tcPackage->toolchainType()) {
|
||||
case McuToolChainPackage::ToolChainType::Unsupported:
|
||||
return;
|
||||
|
||||
case McuToolChainPackage::Type::GHS:
|
||||
case McuToolChainPackage::Type::GHSArm:
|
||||
case McuToolChainPackage::ToolChainType::GHS:
|
||||
case McuToolChainPackage::ToolChainType::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:
|
||||
case McuToolChainPackage::ToolChainType::IAR:
|
||||
case McuToolChainPackage::ToolChainType::KEIL:
|
||||
case McuToolChainPackage::ToolChainType::MSVC:
|
||||
case McuToolChainPackage::ToolChainType::GCC:
|
||||
case McuToolChainPackage::ToolChainType::ArmGcc:
|
||||
ToolChainKitAspect::setToolChain(k,
|
||||
tcPackage->toolChain(
|
||||
ProjectExplorer::Constants::C_LANGUAGE_ID));
|
||||
@@ -136,17 +127,17 @@ static void setKitDebugger(Kit *k, const McuToolChainPackage *tcPackage)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tcPackage->type()) {
|
||||
case McuToolChainPackage::Type::Unsupported:
|
||||
case McuToolChainPackage::Type::GHS:
|
||||
case McuToolChainPackage::Type::GHSArm:
|
||||
case McuToolChainPackage::Type::IAR:
|
||||
switch (tcPackage->toolchainType()) {
|
||||
case McuToolChainPackage::ToolChainType::Unsupported:
|
||||
case McuToolChainPackage::ToolChainType::GHS:
|
||||
case McuToolChainPackage::ToolChainType::GHSArm:
|
||||
case McuToolChainPackage::ToolChainType::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: {
|
||||
case McuToolChainPackage::ToolChainType::KEIL:
|
||||
case McuToolChainPackage::ToolChainType::MSVC:
|
||||
case McuToolChainPackage::ToolChainType::GCC:
|
||||
case McuToolChainPackage::ToolChainType::ArmGcc: {
|
||||
const QVariant debuggerId = tcPackage->debuggerId();
|
||||
if (debuggerId.isValid()) {
|
||||
Debugger::DebuggerKitAspect::setDebugger(k, debuggerId);
|
||||
@@ -168,11 +159,6 @@ static void setKitDevice(Kit *k, const McuTarget *mcuTarget)
|
||||
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)
|
||||
@@ -182,7 +168,7 @@ static void setKitDependencies(Kit *k,
|
||||
auto processPackage = [&dependencies](const McuAbstractPackage *package) {
|
||||
if (!package->environmentVariableName().isEmpty())
|
||||
dependencies.append({package->environmentVariableName(),
|
||||
QDir::toNativeSeparators(package->detectionPath())});
|
||||
package->detectionPath().toUserOutput()});
|
||||
};
|
||||
for (auto package : mcuTarget->packages())
|
||||
processPackage(package);
|
||||
@@ -201,8 +187,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
|
||||
|
||||
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) {
|
||||
if (mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHS
|
||||
&& mcuTarget->toolChainPackage()->toolchainType() != McuToolChainPackage::ToolChainType::GHSArm) {
|
||||
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
|
||||
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
|
||||
}
|
||||
@@ -240,8 +226,8 @@ static void setKitCMakeOptions(Kit *k, const McuTarget *mcuTarget, const FilePat
|
||||
CMakeConfigurationKitAspect::setConfiguration(k, config);
|
||||
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
auto type = mcuTarget->toolChainPackage()->type();
|
||||
if (type == McuToolChainPackage::Type::GHS || type == McuToolChainPackage::Type::GHSArm) {
|
||||
auto type = mcuTarget->toolChainPackage()->toolchainType();
|
||||
if (type == McuToolChainPackage::ToolChainType::GHS || type == McuToolChainPackage::ToolChainType::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");
|
||||
@@ -389,13 +375,12 @@ void createAutomaticKits()
|
||||
const auto createKits = [qtForMCUsPackage]() {
|
||||
if (McuSupportOptions::automaticKitCreationFromSettings()) {
|
||||
qtForMCUsPackage->updateStatus();
|
||||
if (!qtForMCUsPackage->validStatus()) {
|
||||
if (!qtForMCUsPackage->isValidStatus()) {
|
||||
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),
|
||||
.arg(qtForMCUsPackage->path().toUserOutput(),
|
||||
qtForMCUsPackage->detectionPath().toUserOutput()),
|
||||
true);
|
||||
break;
|
||||
}
|
||||
@@ -408,7 +393,7 @@ void createAutomaticKits()
|
||||
}
|
||||
case McuAbstractPackage::Status::EmptyPath: {
|
||||
printMessage(McuPackage::tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
|
||||
.arg(qtForMCUsPackage->detectionPath()),
|
||||
.arg(qtForMCUsPackage->detectionPath().toUserOutput()),
|
||||
true);
|
||||
return;
|
||||
}
|
||||
@@ -575,7 +560,7 @@ void fixExistingKits()
|
||||
// Fix kit dependencies for known targets
|
||||
auto qtForMCUsPackage = Sdk::createQtForMCUsPackage();
|
||||
qtForMCUsPackage->updateStatus();
|
||||
if (qtForMCUsPackage->validStatus()) {
|
||||
if (qtForMCUsPackage->isValidStatus()) {
|
||||
FilePath dir = qtForMCUsPackage->path();
|
||||
McuSdkRepository repo;
|
||||
Sdk::targetsAndPackages(dir, &repo);
|
||||
|
@@ -28,37 +28,69 @@
|
||||
#include "mcusupportversiondetection.h"
|
||||
#include "mcusupportsdk.h"
|
||||
|
||||
#include <baremetal/baremetalconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/infolabel.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <projectexplorer/toolchainmanager.h>
|
||||
#include <debugger/debuggeritem.h>
|
||||
#include <debugger/debuggeritemmanager.h>
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QGridLayout>
|
||||
#include <QToolButton>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
McuPackage::McuPackage(const QString &label,
|
||||
const FilePath &defaultPath,
|
||||
const QString &detectionPath,
|
||||
const FilePath &detectionPath,
|
||||
const QString &settingsKey,
|
||||
const QString &envVarName,
|
||||
const QString &downloadUrl,
|
||||
const McuPackageVersionDetector *versionDetector)
|
||||
const McuPackageVersionDetector *versionDetector,
|
||||
const bool addToSystemPath,
|
||||
const FilePath &relativePathModifier)
|
||||
: m_label(label)
|
||||
, m_defaultPath(Sdk::packagePathFromSettings(settingsKey, QSettings::SystemScope, defaultPath))
|
||||
, m_detectionPath(detectionPath)
|
||||
, m_settingsKey(settingsKey)
|
||||
, m_versionDetector(versionDetector)
|
||||
, m_relativePathModifier(relativePathModifier)
|
||||
, m_environmentVariableName(envVarName)
|
||||
, m_downloadUrl(downloadUrl)
|
||||
, m_addToSystemPath(addToSystemPath)
|
||||
{
|
||||
m_path = Sdk::packagePathFromSettings(settingsKey, QSettings::UserScope, m_defaultPath);
|
||||
}
|
||||
|
||||
QString McuPackage::label() const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
||||
const QString &McuPackage::environmentVariableName() const
|
||||
{
|
||||
return m_environmentVariableName;
|
||||
}
|
||||
|
||||
bool McuPackage::isAddToSystemPath() const
|
||||
{
|
||||
return m_addToSystemPath;
|
||||
}
|
||||
|
||||
void McuPackage::setVersions(const QStringList &versions)
|
||||
{
|
||||
m_versions = versions;
|
||||
}
|
||||
|
||||
FilePath McuPackage::basePath() const
|
||||
{
|
||||
return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path;
|
||||
@@ -69,21 +101,131 @@ FilePath McuPackage::path() const
|
||||
return basePath().resolvePath(m_relativePathModifier).absoluteFilePath();
|
||||
}
|
||||
|
||||
QString McuPackage::label() const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
||||
FilePath McuPackage::defaultPath() const
|
||||
{
|
||||
return m_defaultPath;
|
||||
}
|
||||
|
||||
QString McuPackage::detectionPath() const
|
||||
FilePath McuPackage::detectionPath() const
|
||||
{
|
||||
return m_detectionPath;
|
||||
}
|
||||
|
||||
void McuPackage::updatePath()
|
||||
{
|
||||
m_path = m_fileChooser->rawFilePath();
|
||||
m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath);
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void McuPackage::updateStatus()
|
||||
{
|
||||
bool validPath = !m_path.isEmpty() && m_path.exists();
|
||||
const FilePath detectionPath = basePath().resolvePath(m_detectionPath);
|
||||
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
|
||||
m_detectedVersion = validPath && validPackage && m_versionDetector
|
||||
? m_versionDetector->parseVersion(basePath().toString())
|
||||
: QString();
|
||||
const bool validVersion = m_detectedVersion.isEmpty() || m_versions.isEmpty()
|
||||
|| m_versions.contains(m_detectedVersion);
|
||||
|
||||
m_status = validPath ? (validPackage ? (validVersion ? Status::ValidPackage
|
||||
: Status::ValidPackageMismatchedVersion)
|
||||
: Status::ValidPathInvalidPackage)
|
||||
: m_path.isEmpty() ? Status::EmptyPath
|
||||
: Status::InvalidPath;
|
||||
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
McuPackage::Status McuPackage::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
bool McuPackage::isValidStatus() const
|
||||
{
|
||||
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion;
|
||||
}
|
||||
|
||||
|
||||
void McuPackage::updateStatusUi()
|
||||
{
|
||||
switch (m_status) {
|
||||
case Status::ValidPackage:
|
||||
m_infoLabel->setType(InfoLabel::Ok);
|
||||
break;
|
||||
case Status::ValidPackageMismatchedVersion:
|
||||
m_infoLabel->setType(InfoLabel::Warning);
|
||||
break;
|
||||
default:
|
||||
m_infoLabel->setType(InfoLabel::NotOk);
|
||||
break;
|
||||
}
|
||||
m_infoLabel->setText(statusText());
|
||||
}
|
||||
|
||||
QString McuPackage::statusText() const
|
||||
{
|
||||
const QString displayPackagePath = m_path.toUserOutput();
|
||||
const QString displayVersions = m_versions.join(" or ");
|
||||
const QString outDetectionPath = m_detectionPath.toUserOutput();
|
||||
const QString displayRequiredPath = m_versions.empty() ? outDetectionPath
|
||||
: QString("%1 %2").arg(outDetectionPath,
|
||||
displayVersions);
|
||||
const QString displayDetectedPath = m_versions.empty()
|
||||
? outDetectionPath
|
||||
: QString("%1 %2").arg(outDetectionPath,
|
||||
m_detectedVersion);
|
||||
|
||||
QString response;
|
||||
switch (m_status) {
|
||||
case Status::ValidPackage:
|
||||
response = m_detectionPath.isEmpty()
|
||||
? (m_detectedVersion.isEmpty()
|
||||
? tr("Path %1 exists.").arg(displayPackagePath)
|
||||
: tr("Path %1 exists. Version %2 was found.")
|
||||
.arg(displayPackagePath, m_detectedVersion))
|
||||
: tr("Path %1 is valid, %2 was found.")
|
||||
.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);
|
||||
response = tr("Path %1 is valid, %2 was found, %3.")
|
||||
.arg(displayPackagePath, displayDetectedPath, versionWarning);
|
||||
break;
|
||||
}
|
||||
case Status::ValidPathInvalidPackage:
|
||||
response = tr("Path %1 exists, but does not contain %2.")
|
||||
.arg(displayPackagePath, displayRequiredPath);
|
||||
break;
|
||||
case Status::InvalidPath:
|
||||
response = tr("Path %1 does not exist.").arg(displayPackagePath);
|
||||
break;
|
||||
case Status::EmptyPath:
|
||||
response = m_detectionPath.isEmpty()
|
||||
? tr("Path is empty.")
|
||||
: tr("Path is empty, %1 not found.").arg(displayRequiredPath);
|
||||
break;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
bool McuPackage::writeToSettings() const
|
||||
{
|
||||
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
|
||||
QSettings::UserScope,
|
||||
m_defaultPath);
|
||||
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
|
||||
+ QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey;
|
||||
Core::ICore::settings()->setValueWithDefault(key, m_path.toString(), m_defaultPath.toString());
|
||||
|
||||
return savedPath != m_path;
|
||||
}
|
||||
|
||||
QWidget *McuPackage::widget()
|
||||
{
|
||||
if (m_widget)
|
||||
@@ -127,164 +269,201 @@ QWidget *McuPackage::widget()
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
McuPackage::Status McuPackage::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
bool McuPackage::validStatus() const
|
||||
{
|
||||
return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion;
|
||||
}
|
||||
|
||||
const QString &McuPackage::environmentVariableName() const
|
||||
{
|
||||
return m_environmentVariableName;
|
||||
}
|
||||
|
||||
void McuPackage::setAddToPath(bool addToPath)
|
||||
{
|
||||
m_addToPath = addToPath;
|
||||
}
|
||||
|
||||
bool McuPackage::addToPath() const
|
||||
{
|
||||
return m_addToPath;
|
||||
}
|
||||
|
||||
bool McuPackage::writeToSettings() const
|
||||
{
|
||||
const FilePath savedPath = Sdk::packagePathFromSettings(m_settingsKey,
|
||||
QSettings::UserScope,
|
||||
m_defaultPath);
|
||||
const QString key = QLatin1String(Constants::SETTINGS_GROUP) + '/'
|
||||
+ QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey;
|
||||
Core::ICore::settings()->setValueWithDefault(key, m_path.toString(), m_defaultPath.toString());
|
||||
|
||||
return savedPath != m_path;
|
||||
}
|
||||
|
||||
void McuPackage::setRelativePathModifier(const QString &path)
|
||||
{
|
||||
m_relativePathModifier = path;
|
||||
}
|
||||
|
||||
void McuPackage::setVersions(const QStringList &versions)
|
||||
{
|
||||
m_versions = versions;
|
||||
}
|
||||
|
||||
void McuPackage::updatePath()
|
||||
{
|
||||
m_path = m_fileChooser->rawFilePath();
|
||||
m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath);
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void McuPackage::updateStatus()
|
||||
{
|
||||
bool validPath = !m_path.isEmpty() && m_path.exists();
|
||||
const FilePath detectionPath = basePath() / m_detectionPath;
|
||||
const bool validPackage = m_detectionPath.isEmpty() || detectionPath.exists();
|
||||
m_detectedVersion = validPath && validPackage && m_versionDetector
|
||||
? m_versionDetector->parseVersion(basePath().toString())
|
||||
: QString();
|
||||
const bool validVersion = m_detectedVersion.isEmpty() || m_versions.isEmpty()
|
||||
|| m_versions.contains(m_detectedVersion);
|
||||
|
||||
m_status = validPath ? (validPackage ? (validVersion ? Status::ValidPackage
|
||||
: Status::ValidPackageMismatchedVersion)
|
||||
: Status::ValidPathInvalidPackage)
|
||||
: m_path.isEmpty() ? Status::EmptyPath
|
||||
: Status::InvalidPath;
|
||||
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
void McuPackage::updateStatusUi()
|
||||
{
|
||||
switch (m_status) {
|
||||
case Status::ValidPackage:
|
||||
m_infoLabel->setType(InfoLabel::Ok);
|
||||
break;
|
||||
case Status::ValidPackageMismatchedVersion:
|
||||
m_infoLabel->setType(InfoLabel::Warning);
|
||||
break;
|
||||
default:
|
||||
m_infoLabel->setType(InfoLabel::NotOk);
|
||||
break;
|
||||
}
|
||||
m_infoLabel->setText(statusText());
|
||||
}
|
||||
|
||||
QString McuPackage::statusText() const
|
||||
{
|
||||
const QString displayPackagePath = m_path.toUserOutput();
|
||||
const QString displayVersions = m_versions.join(" or ");
|
||||
const QString outDetectionPath = FilePath::fromString(m_detectionPath).toUserOutput();
|
||||
const QString displayRequiredPath = m_versions.empty() ? outDetectionPath
|
||||
: QString("%1 %2").arg(outDetectionPath,
|
||||
displayVersions);
|
||||
const QString displayDetectedPath = m_versions.empty()
|
||||
? outDetectionPath
|
||||
: QString("%1 %2").arg(outDetectionPath,
|
||||
m_detectedVersion);
|
||||
|
||||
QString response;
|
||||
switch (m_status) {
|
||||
case Status::ValidPackage:
|
||||
response = m_detectionPath.isEmpty()
|
||||
? (m_detectedVersion.isEmpty()
|
||||
? tr("Path %1 exists.").arg(displayPackagePath)
|
||||
: tr("Path %1 exists. Version %2 was found.")
|
||||
.arg(displayPackagePath, m_detectedVersion))
|
||||
: tr("Path %1 is valid, %2 was found.")
|
||||
.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);
|
||||
response = tr("Path %1 is valid, %2 was found, %3.")
|
||||
.arg(displayPackagePath, displayDetectedPath, versionWarning);
|
||||
break;
|
||||
}
|
||||
case Status::ValidPathInvalidPackage:
|
||||
response = tr("Path %1 exists, but does not contain %2.")
|
||||
.arg(displayPackagePath, displayRequiredPath);
|
||||
break;
|
||||
case Status::InvalidPath:
|
||||
response = tr("Path %1 does not exist.").arg(displayPackagePath);
|
||||
break;
|
||||
case Status::EmptyPath:
|
||||
response = m_detectionPath.isEmpty()
|
||||
? tr("Path is empty.")
|
||||
: tr("Path is empty, %1 not found.").arg(displayRequiredPath);
|
||||
break;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
McuToolChainPackage::McuToolChainPackage(const QString &label,
|
||||
const FilePath &defaultPath,
|
||||
const QString &detectionPath,
|
||||
const FilePath &detectionPath,
|
||||
const QString &settingsKey,
|
||||
McuToolChainPackage::Type type,
|
||||
McuToolChainPackage::ToolChainType type,
|
||||
const QString &envVarName,
|
||||
const McuPackageVersionDetector *versionDetector)
|
||||
: McuPackage(label, defaultPath, detectionPath, settingsKey, envVarName, {}, versionDetector)
|
||||
, m_type(type)
|
||||
{}
|
||||
|
||||
McuToolChainPackage::Type McuToolChainPackage::type() const
|
||||
McuToolChainPackage::ToolChainType McuToolChainPackage::toolchainType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool McuToolChainPackage::isDesktopToolchain() const
|
||||
{
|
||||
return m_type == Type::MSVC || m_type == Type::GCC;
|
||||
return m_type == ToolChainType::MSVC || m_type == ToolChainType::GCC;
|
||||
}
|
||||
|
||||
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 ToolChainType::MSVC:
|
||||
return msvcToolChain(language);
|
||||
case ToolChainType::GCC:
|
||||
return gccToolChain(language);
|
||||
case ToolChainType::IAR: {
|
||||
const FilePath compiler = path().pathAppended("/bin/iccarm").withExecutableSuffix();
|
||||
return iarToolChain(compiler, language);
|
||||
}
|
||||
case ToolChainType::ArmGcc:
|
||||
case ToolChainType::KEIL:
|
||||
case ToolChainType::GHS:
|
||||
case ToolChainType::GHSArm:
|
||||
case ToolChainType::Unsupported: {
|
||||
const QLatin1String compilerName(
|
||||
language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++");
|
||||
const QString comp = QLatin1String(m_type == ToolChainType::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 ToolChainType::ArmGcc:
|
||||
return QLatin1String("armgcc");
|
||||
case ToolChainType::IAR:
|
||||
return QLatin1String("iar");
|
||||
case ToolChainType::KEIL:
|
||||
return QLatin1String("keil");
|
||||
case ToolChainType::GHS:
|
||||
return QLatin1String("ghs");
|
||||
case ToolChainType::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 ToolChainType::ArmGcc: {
|
||||
sub = QString::fromLatin1("bin/arm-none-eabi-gdb-py");
|
||||
displayName = McuPackage::tr("Arm GDB at %1");
|
||||
engineType = Debugger::GdbEngineType;
|
||||
break;
|
||||
}
|
||||
case ToolChainType::IAR: {
|
||||
sub = QString::fromLatin1("../common/bin/CSpyBat");
|
||||
displayName = QLatin1String("CSpy");
|
||||
engineType = Debugger::NoEngineType; // support for IAR missing
|
||||
break;
|
||||
}
|
||||
case ToolChainType::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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -55,33 +55,35 @@ class McuPackage : public McuAbstractPackage
|
||||
public:
|
||||
McuPackage(const QString &label,
|
||||
const Utils::FilePath &defaultPath,
|
||||
const QString &detectionPath,
|
||||
const Utils::FilePath &detectionPath,
|
||||
const QString &settingsKey,
|
||||
const QString &envVarName = {},
|
||||
const QString &downloadUrl = {},
|
||||
const McuPackageVersionDetector *versionDetector = nullptr);
|
||||
const McuPackageVersionDetector *versionDetector = nullptr,
|
||||
const bool addToPath = false,
|
||||
const Utils::FilePath &relativePathModifier = Utils::FilePath());
|
||||
|
||||
~McuPackage() override = default;
|
||||
|
||||
QString label() const override;
|
||||
const QString &environmentVariableName() const override;
|
||||
bool isAddToSystemPath() const override;
|
||||
void setVersions(const QStringList &versions) override;
|
||||
|
||||
Utils::FilePath basePath() const override;
|
||||
Utils::FilePath path() const override;
|
||||
QString label() const override;
|
||||
Utils::FilePath defaultPath() const override;
|
||||
QString detectionPath() const override;
|
||||
QString statusText() const override;
|
||||
void updateStatus() override;
|
||||
Utils::FilePath detectionPath() const override;
|
||||
|
||||
void updateStatus() override;
|
||||
Status status() const override;
|
||||
bool validStatus() const override;
|
||||
void setAddToPath(bool addToPath) override;
|
||||
bool addToPath() const override;
|
||||
bool isValidStatus() const override;
|
||||
QString statusText() const override;
|
||||
|
||||
bool writeToSettings() const override;
|
||||
void setRelativePathModifier(const QString &path) override;
|
||||
void setVersions(const QStringList &versions) override;
|
||||
|
||||
QWidget *widget() override;
|
||||
|
||||
const QString &environmentVariableName() const override;
|
||||
|
||||
private:
|
||||
void updatePath();
|
||||
void updateStatusUi();
|
||||
@@ -92,17 +94,17 @@ private:
|
||||
|
||||
const QString m_label;
|
||||
const Utils::FilePath m_defaultPath;
|
||||
const QString m_detectionPath;
|
||||
const Utils::FilePath m_detectionPath;
|
||||
const QString m_settingsKey;
|
||||
const McuPackageVersionDetector *m_versionDetector;
|
||||
|
||||
Utils::FilePath m_path;
|
||||
QString m_relativePathModifier; // relative path to m_path to be returned by path()
|
||||
Utils::FilePath m_relativePathModifier; // relative path to m_path to be returned by path()
|
||||
QString m_detectedVersion;
|
||||
QStringList m_versions;
|
||||
const QString m_environmentVariableName;
|
||||
const QString m_downloadUrl;
|
||||
bool m_addToPath = false;
|
||||
const bool m_addToSystemPath;
|
||||
|
||||
Status m_status = Status::InvalidPath;
|
||||
};
|
||||
@@ -110,17 +112,17 @@ private:
|
||||
class McuToolChainPackage : public McuPackage
|
||||
{
|
||||
public:
|
||||
enum class Type { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported };
|
||||
enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported };
|
||||
|
||||
McuToolChainPackage(const QString &label,
|
||||
const Utils::FilePath &defaultPath,
|
||||
const QString &detectionPath,
|
||||
const Utils::FilePath &detectionPath,
|
||||
const QString &settingsKey,
|
||||
Type type,
|
||||
ToolChainType toolchainType,
|
||||
const QString &envVarName = {},
|
||||
const McuPackageVersionDetector *versionDetector = nullptr);
|
||||
|
||||
Type type() const;
|
||||
ToolChainType toolchainType() const;
|
||||
bool isDesktopToolchain() const;
|
||||
ProjectExplorer::ToolChain *toolChain(Utils::Id language) const;
|
||||
QString toolChainName() const;
|
||||
@@ -128,7 +130,7 @@ public:
|
||||
QVariant debuggerId() const;
|
||||
|
||||
private:
|
||||
const Type m_type;
|
||||
const ToolChainType m_type;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -134,7 +134,7 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
|
||||
{
|
||||
deletePackagesAndTargets();
|
||||
qtForMCUsSdkPackage->updateStatus();
|
||||
if (qtForMCUsSdkPackage->validStatus())
|
||||
if (qtForMCUsSdkPackage->isValidStatus())
|
||||
Sdk::targetsAndPackages(dir, &sdkRepository);
|
||||
for (const auto &package : qAsConst(sdkRepository.packages))
|
||||
connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::packagesChanged);
|
||||
@@ -164,73 +164,6 @@ void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &en
|
||||
CMakeConfigurationKitAspect::setConfiguration(kit, config);
|
||||
}
|
||||
|
||||
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 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};
|
||||
@@ -251,7 +184,7 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
|
||||
pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput());
|
||||
|
||||
auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) {
|
||||
if (package->addToPath())
|
||||
if (package->isAddToSystemPath())
|
||||
pathAdditions.append(package->path().toUserOutput());
|
||||
if (!package->environmentVariableName().isEmpty())
|
||||
changes.append({package->environmentVariableName(), package->path().toUserOutput()});
|
||||
@@ -271,34 +204,12 @@ void McuSupportOptions::setKitEnvironment(Kit *k,
|
||||
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void McuSupportOptions::updateKitEnvironment(Kit *k, const McuTarget *mcuTarget)
|
||||
{
|
||||
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k);
|
||||
for (auto package : mcuTarget->packages()) {
|
||||
const QString varName = package->environmentVariableName();
|
||||
if (!varName.isEmpty() && package->validStatus()) {
|
||||
if (!varName.isEmpty() && package->isValidStatus()) {
|
||||
const int index = Utils::indexOf(changes, [varName](const EnvironmentItem &item) {
|
||||
return item.name == varName;
|
||||
});
|
||||
@@ -319,76 +230,6 @@ void McuSupportOptions::updateKitEnvironment(Kit *k, const McuTarget *mcuTarget)
|
||||
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
|
||||
}
|
||||
|
||||
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(McuKitManager::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(McuKitManager::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
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
McuKitManager::UpgradeOption McuSupportOptions::askForKitUpgrades()
|
||||
{
|
||||
QMessageBox upgradePopup(Core::ICore::dialogParent());
|
||||
@@ -417,7 +258,7 @@ void McuSupportOptions::deletePackagesAndTargets()
|
||||
|
||||
void McuSupportOptions::checkUpgradeableKits()
|
||||
{
|
||||
if (!qtForMCUsSdkPackage->validStatus() || sdkRepository.mcuTargets.length() == 0)
|
||||
if (!qtForMCUsSdkPackage->isValidStatus() || sdkRepository.mcuTargets.length() == 0)
|
||||
return;
|
||||
|
||||
if (Utils::anyOf(sdkRepository.mcuTargets, [this](const McuTarget *target) {
|
||||
|
@@ -197,7 +197,7 @@ void McuSupportOptionsWidget::updateStatus()
|
||||
// Page elements
|
||||
{
|
||||
m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable);
|
||||
const bool valid = cMakeAvailable && m_options.qtForMCUsSdkPackage->validStatus();
|
||||
const bool valid = cMakeAvailable && m_options.qtForMCUsSdkPackage->isValidStatus();
|
||||
const bool ready = valid && mcuTarget;
|
||||
m_mcuTargetsGroupBox->setVisible(ready);
|
||||
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());
|
||||
|
@@ -71,24 +71,24 @@ McuPackage *createQtForMCUsPackage()
|
||||
{
|
||||
return new McuPackage(McuPackage::tr("Qt for MCUs SDK"),
|
||||
FileUtils::homePath(), // defaultPath
|
||||
FilePath("bin/qmltocpp").withExecutableSuffix().toString(), // detectionPath
|
||||
FilePath("bin/qmltocpp").withExecutableSuffix(), // detectionPath
|
||||
Constants::SETTINGS_KEY_PACKAGE_QT_FOR_MCUS_SDK, // settingsKey
|
||||
QStringLiteral("Qul_DIR")); // envVarName
|
||||
}
|
||||
|
||||
static McuToolChainPackage *createMsvcToolChainPackage()
|
||||
{
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::MSVC);
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::MSVC);
|
||||
}
|
||||
|
||||
static McuToolChainPackage *createGccToolChainPackage()
|
||||
{
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::GCC);
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::GCC);
|
||||
}
|
||||
|
||||
static McuToolChainPackage *createUnsupportedToolChainPackage()
|
||||
{
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::Type::Unsupported);
|
||||
return new McuToolChainPackage({}, {}, {}, {}, McuToolChainPackage::ToolChainType::Unsupported);
|
||||
}
|
||||
|
||||
static McuToolChainPackage *createArmGccPackage()
|
||||
@@ -109,7 +109,7 @@ static McuToolChainPackage *createArmGccPackage()
|
||||
}
|
||||
}
|
||||
|
||||
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++");
|
||||
const Utils::FilePath detectionPath = FilePath("bin/arm-none-eabi-g++").withExecutableSuffix();
|
||||
const auto versionDetector
|
||||
= new McuPackageExecutableVersionDetector(detectionPath,
|
||||
{"--version"},
|
||||
@@ -119,7 +119,7 @@ static McuToolChainPackage *createArmGccPackage()
|
||||
defaultPath,
|
||||
detectionPath,
|
||||
"GNUArmEmbeddedToolchain", // settingsKey
|
||||
McuToolChainPackage::Type::ArmGcc,
|
||||
McuToolChainPackage::ToolChainType::ArmGcc,
|
||||
envVar,
|
||||
versionDetector);
|
||||
}
|
||||
@@ -131,16 +131,15 @@ static McuToolChainPackage *createGhsToolchainPackage()
|
||||
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
|
||||
const auto versionDetector
|
||||
= new McuPackageExecutableVersionDetector(Utils::HostOsInfo::withExecutableSuffix("as850"),
|
||||
= new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(),
|
||||
{"-V"},
|
||||
"\\bv(\\d+\\.\\d+\\.\\d+)\\b");
|
||||
|
||||
return new McuToolChainPackage("Green Hills Compiler",
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix(
|
||||
"ccv850"), // detectionPath
|
||||
FilePath("ccv850").withExecutableSuffix(), // detectionPath
|
||||
"GHSToolchain", // settingsKey
|
||||
McuToolChainPackage::Type::GHS,
|
||||
McuToolChainPackage::ToolChainType::GHS,
|
||||
envVar,
|
||||
versionDetector);
|
||||
}
|
||||
@@ -152,15 +151,15 @@ static McuToolChainPackage *createGhsArmToolchainPackage()
|
||||
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
|
||||
const auto versionDetector
|
||||
= new McuPackageExecutableVersionDetector(Utils::HostOsInfo::withExecutableSuffix("asarm"),
|
||||
= new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(),
|
||||
{"-V"},
|
||||
"\\bv(\\d+\\.\\d+\\.\\d+)\\b");
|
||||
|
||||
return new McuToolChainPackage("Green Hills Compiler for ARM",
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix("cxarm"), // detectionPath
|
||||
FilePath("cxarm").withExecutableSuffix(), // detectionPath
|
||||
"GHSArmToolchain", // settingsKey
|
||||
McuToolChainPackage::Type::GHSArm,
|
||||
McuToolChainPackage::ToolChainType::GHSArm,
|
||||
envVar,
|
||||
versionDetector);
|
||||
}
|
||||
@@ -183,7 +182,7 @@ static McuToolChainPackage *createIarToolChainPackage()
|
||||
}
|
||||
}
|
||||
|
||||
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm");
|
||||
const FilePath detectionPath = FilePath("bin/iccarm").withExecutableSuffix();
|
||||
const auto versionDetector
|
||||
= new McuPackageExecutableVersionDetector(detectionPath,
|
||||
{"--version"},
|
||||
@@ -193,7 +192,7 @@ static McuToolChainPackage *createIarToolChainPackage()
|
||||
defaultPath,
|
||||
detectionPath,
|
||||
"IARToolchain", // settings key
|
||||
McuToolChainPackage::Type::IAR,
|
||||
McuToolChainPackage::ToolChainType::IAR,
|
||||
envVar,
|
||||
versionDetector);
|
||||
}
|
||||
@@ -237,17 +236,24 @@ static McuPackage *createStm32CubeProgrammerPackage()
|
||||
if (programPath.exists())
|
||||
defaultPath = programPath;
|
||||
}
|
||||
|
||||
const FilePath detectionPath = FilePath::fromString(
|
||||
QLatin1String(Utils::HostOsInfo::isWindowsHost()
|
||||
? "/bin/STM32_Programmer_CLI.exe"
|
||||
: "/bin/STM32_Programmer.sh")
|
||||
);
|
||||
|
||||
auto result
|
||||
= new McuPackage(McuPackage::tr("STM32CubeProgrammer"),
|
||||
defaultPath,
|
||||
QLatin1String(Utils::HostOsInfo::isWindowsHost()
|
||||
? "/bin/STM32_Programmer_CLI.exe"
|
||||
: "/bin/STM32_Programmer.sh"), // detection path
|
||||
detectionPath,
|
||||
"Stm32CubeProgrammer",
|
||||
{}, // env var
|
||||
"https://www.st.com/en/development-tools/stm32cubeprog.html"); // download url
|
||||
result->setRelativePathModifier("/bin");
|
||||
result->setAddToPath(true);
|
||||
"https://www.st.com/en/development-tools/stm32cubeprog.html", // download url
|
||||
nullptr, // version detector
|
||||
true, // add to path
|
||||
"/bin" // relative path modifier
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -276,8 +282,7 @@ static McuPackage *createMcuXpressoIdePackage()
|
||||
|
||||
return new McuPackage("MCUXpresso IDE",
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix(
|
||||
"ide/binaries/crt_emu_cm_redlink"), // detection path
|
||||
FilePath("ide/binaries/crt_emu_cm_redlink").withExecutableSuffix(), // detection path
|
||||
"MCUXpressoIDE", // settings key
|
||||
envVar,
|
||||
"https://www.nxp.com/mcuxpresso/ide"); // download url
|
||||
@@ -303,7 +308,7 @@ static McuPackage *createCypressProgrammerPackage()
|
||||
|
||||
auto result = new McuPackage("Cypress Auto Flash Utility",
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix("/bin/openocd"),
|
||||
FilePath("/bin/openocd").withExecutableSuffix(),
|
||||
"CypressAutoFlashUtil",
|
||||
envVar);
|
||||
return result;
|
||||
@@ -329,7 +334,7 @@ static McuPackage *createRenesasProgrammerPackage()
|
||||
|
||||
auto result = new McuPackage("Renesas Flash Programmer",
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix("rfp-cli"),
|
||||
FilePath("rfp-cli").withExecutableSuffix(),
|
||||
"RenesasFlashProgrammer",
|
||||
envVar);
|
||||
return result;
|
||||
@@ -538,7 +543,7 @@ protected:
|
||||
QVector<McuAbstractPackage *> required3rdPartyPkgs;
|
||||
// Desktop toolchains don't need any additional settings
|
||||
if (tcPkg && !tcPkg->isDesktopToolchain()
|
||||
&& tcPkg->type() != McuToolChainPackage::Type::Unsupported)
|
||||
&& tcPkg->toolchainType() != McuToolChainPackage::ToolChainType::Unsupported)
|
||||
required3rdPartyPkgs.append(tcPkg);
|
||||
|
||||
// Add setting specific to platform IDE
|
||||
|
@@ -46,7 +46,7 @@ QString matchRegExp(const QString &text, const QString ®Exp)
|
||||
McuPackageVersionDetector::McuPackageVersionDetector() {}
|
||||
|
||||
McuPackageExecutableVersionDetector::McuPackageExecutableVersionDetector(
|
||||
const QString &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp)
|
||||
const Utils::FilePath &detectionPath, const QStringList &detectionArgs, const QString &detectionRegExp)
|
||||
: McuPackageVersionDetector()
|
||||
, m_detectionPath(detectionPath)
|
||||
, m_detectionArgs(detectionArgs)
|
||||
@@ -58,7 +58,7 @@ QString McuPackageExecutableVersionDetector::parseVersion(const QString &package
|
||||
if (m_detectionPath.isEmpty() || m_detectionRegExp.isEmpty())
|
||||
return QString();
|
||||
|
||||
const Utils::FilePath binaryPath = Utils::FilePath::fromString(packagePath) / m_detectionPath;
|
||||
const Utils::FilePath binaryPath = Utils::FilePath::fromString(packagePath).resolvePath(m_detectionPath);
|
||||
if (!binaryPath.exists())
|
||||
return QString();
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
namespace McuSupport {
|
||||
namespace Internal {
|
||||
@@ -43,13 +44,13 @@ public:
|
||||
class McuPackageExecutableVersionDetector : public McuPackageVersionDetector
|
||||
{
|
||||
public:
|
||||
McuPackageExecutableVersionDetector(const QString &detectionPath,
|
||||
McuPackageExecutableVersionDetector(const Utils::FilePath &detectionPath,
|
||||
const QStringList &detectionArgs,
|
||||
const QString &detectionRegExp);
|
||||
QString parseVersion(const QString &packagePath) const final;
|
||||
|
||||
private:
|
||||
const QString m_detectionPath;
|
||||
const Utils::FilePath m_detectionPath;
|
||||
const QStringList m_detectionArgs;
|
||||
const QString m_detectionRegExp;
|
||||
};
|
||||
|
@@ -26,196 +26,14 @@
|
||||
#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>
|
||||
#include <utils/algorithm.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,
|
||||
@@ -254,7 +72,7 @@ bool McuTarget::isValid() const
|
||||
{
|
||||
return Utils::allOf(packages(), [](McuAbstractPackage *package) {
|
||||
package->updateStatus();
|
||||
return package->validStatus();
|
||||
return package->isValidStatus();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -262,7 +80,7 @@ void McuTarget::printPackageProblems() const
|
||||
{
|
||||
for (auto package : packages()) {
|
||||
package->updateStatus();
|
||||
if (!package->validStatus())
|
||||
if (!package->isValidStatus())
|
||||
printMessage(tr("Error creating kit for target %1, package %2: %3")
|
||||
.arg(McuKitManager::kitName(this),
|
||||
package->label(),
|
||||
|
@@ -39,17 +39,15 @@ public:
|
||||
MOCK_METHOD(Utils::FilePath, path, (), (const));
|
||||
MOCK_METHOD(QString, label, (), (const));
|
||||
MOCK_METHOD(Utils::FilePath, defaultPath, (), (const));
|
||||
MOCK_METHOD(QString, detectionPath, (), (const));
|
||||
MOCK_METHOD(Utils::FilePath, detectionPath, (), (const));
|
||||
MOCK_METHOD(QString, statusText, (), (const));
|
||||
MOCK_METHOD(void, updateStatus, ());
|
||||
|
||||
MOCK_METHOD(Status, status, (), (const));
|
||||
MOCK_METHOD(bool, validStatus, (), (const));
|
||||
MOCK_METHOD(bool, isValidStatus, (), (const));
|
||||
MOCK_METHOD(const QString &, environmentVariableName, (), (const));
|
||||
MOCK_METHOD(void, setAddToPath, (bool) );
|
||||
MOCK_METHOD(bool, addToPath, (), (const));
|
||||
MOCK_METHOD(bool, isAddToSystemPath, (), (const));
|
||||
MOCK_METHOD(bool, writeToSettings, (), (const));
|
||||
MOCK_METHOD(void, setRelativePathModifier, (const QString &) );
|
||||
MOCK_METHOD(void, setVersions, (const QStringList &) );
|
||||
|
||||
MOCK_METHOD(QWidget *, widget, ());
|
||||
|
@@ -47,7 +47,7 @@ using Utils::FilePath;
|
||||
void McuSupportTest::initTestCase()
|
||||
{
|
||||
EXPECT_CALL(freeRtosPackage, environmentVariableName()).WillRepeatedly(ReturnRef(freeRtosEnvVar));
|
||||
EXPECT_CALL(freeRtosPackage, validStatus()).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(freeRtosPackage, isValidStatus()).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(freeRtosPackage, path())
|
||||
.WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath)));
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ add_qtc_plugin(QmlDesigner
|
||||
cmakegeneratordialogtreemodel.cpp cmakegeneratordialogtreemodel.h
|
||||
cmakeprojectconverter.cpp cmakeprojectconverter.h
|
||||
cmakeprojectconverterdialog.cpp cmakeprojectconverterdialog.h
|
||||
dynamiclicensecheck.h
|
||||
generateresource.cpp generateresource.h
|
||||
generatecmakelists.cpp generatecmakelists.h
|
||||
generatecmakelistsconstants.h
|
||||
|
@@ -29,7 +29,9 @@
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
@@ -63,13 +65,46 @@ void CmakeProjectConverter::generateMenuEntry()
|
||||
Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.ConvertToCmakeProject");
|
||||
menu->addAction(cmd, Core::Constants::G_FILE_EXPORT);
|
||||
|
||||
action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr);
|
||||
action->setEnabled(isProjectConvertable(ProjectExplorer::SessionManager::startupProject()));
|
||||
QObject::connect(ProjectExplorer::SessionManager::instance(),
|
||||
&ProjectExplorer::SessionManager::startupProjectChanged, [action]() {
|
||||
action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr);
|
||||
action->setEnabled(isProjectConvertable(ProjectExplorer::SessionManager::startupProject()));
|
||||
});
|
||||
}
|
||||
|
||||
bool CmakeProjectConverter::isProjectConvertable(const ProjectExplorer::Project *project)
|
||||
{
|
||||
if (!project)
|
||||
return false;
|
||||
|
||||
return !isProjectCurrentFormat(project);
|
||||
}
|
||||
|
||||
const QStringList sanityCheckFiles({FILENAME_CMAKELISTS,
|
||||
FILENAME_MODULES,
|
||||
FILENAME_MAINQML,
|
||||
QString(DIRNAME_CONTENT)+'/'+FILENAME_CMAKELISTS,
|
||||
QString(DIRNAME_IMPORT)+'/'+FILENAME_CMAKELISTS,
|
||||
QString(DIRNAME_CPP)+'/'+FILENAME_MAINCPP,
|
||||
QString(DIRNAME_CPP)+'/'+FILENAME_ENV_HEADER,
|
||||
QString(DIRNAME_CPP)+'/'+FILENAME_MAINCPP_HEADER
|
||||
});
|
||||
|
||||
bool CmakeProjectConverter::isProjectCurrentFormat(const ProjectExplorer::Project *project)
|
||||
{
|
||||
const QmlProjectManager::QmlProject *qmlprj = qobject_cast<const QmlProjectManager::QmlProject*>(project);
|
||||
|
||||
if (!qmlprj)
|
||||
return false;
|
||||
|
||||
FilePath rootDir = qmlprj->rootProjectDirectory();
|
||||
for (const QString &file : sanityCheckFiles)
|
||||
if (!rootDir.pathAppended(file).exists())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CmakeProjectConverter::onConvertProject()
|
||||
{
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||
@@ -100,10 +135,16 @@ bool CmakeProjectConverter::convertProject(const QmlProjectManager::QmlProject *
|
||||
|
||||
bool retVal = prepareAndExecute();
|
||||
|
||||
if (retVal)
|
||||
QMessageBox::information(nullptr, SUCCESS_TITLE, SUCCESS_TEXT);
|
||||
else
|
||||
QMessageBox::critical(nullptr, ERROR_TITLE, ERROR_TEXT.arg(m_errorText));
|
||||
if (retVal) {
|
||||
QMessageBox::information(Core::ICore::dialogParent(), SUCCESS_TITLE, SUCCESS_TEXT);
|
||||
ProjectExplorer::ProjectExplorerPlugin::OpenProjectResult result
|
||||
= ProjectExplorer::ProjectExplorerPlugin::openProject(newProjectFile());
|
||||
if (!result)
|
||||
ProjectExplorer::ProjectExplorerPlugin::showOpenProjectError(result);
|
||||
}
|
||||
else {
|
||||
QMessageBox::critical(Core::ICore::dialogParent(), ERROR_TITLE, ERROR_TEXT.arg(m_errorText));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
@@ -298,31 +339,36 @@ bool CmakeProjectConverter::createPreparedProject()
|
||||
return true;
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::contentDir()
|
||||
const FilePath CmakeProjectConverter::contentDir() const
|
||||
{
|
||||
return m_newProjectDir.pathAppended(DIRNAME_CONTENT);
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::sourceDir()
|
||||
const FilePath CmakeProjectConverter::sourceDir() const
|
||||
{
|
||||
return m_newProjectDir.pathAppended(DIRNAME_CPP);
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::importDir()
|
||||
const FilePath CmakeProjectConverter::importDir() const
|
||||
{
|
||||
return m_newProjectDir.pathAppended(DIRNAME_IMPORT);
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::assetDir()
|
||||
const FilePath CmakeProjectConverter::assetDir() const
|
||||
{
|
||||
return contentDir().pathAppended(DIRNAME_ASSET);
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::assetImportDir()
|
||||
const FilePath CmakeProjectConverter::assetImportDir() const
|
||||
{
|
||||
return m_newProjectDir.pathAppended(DIRNAME_ASSETIMPORT);
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::newProjectFile() const
|
||||
{
|
||||
return m_newProjectDir.pathAppended(m_project->projectFilePath().fileName());
|
||||
}
|
||||
|
||||
const FilePath CmakeProjectConverter::projectMainFile() const
|
||||
{
|
||||
auto *target = m_project->activeTarget();
|
||||
@@ -370,17 +416,20 @@ bool CmakeProjectConverter::modifyProjectFile()
|
||||
QString projectFileName = m_project->projectFilePath().fileName();
|
||||
FilePath projectFilePath = m_newProjectDir.pathAppended(projectFileName);
|
||||
QFile projectFile(projectFilePath.toString());
|
||||
projectFile.open(QIODevice::ReadWrite);
|
||||
projectFile.open(QIODevice::ReadOnly);
|
||||
if (!projectFile.isOpen())
|
||||
return false;
|
||||
|
||||
QString projectFileContent = QString::fromUtf8(projectFile.readAll());
|
||||
projectFile.close();
|
||||
|
||||
const QRegularExpression mainFilePattern("^\\s*mainFile:\\s*\".*\"", QRegularExpression::MultilineOption);
|
||||
const QString mainFileString(" mainFile: \"content/App.qml\"");
|
||||
|
||||
projectFileContent.replace(mainFilePattern, mainFileString);
|
||||
|
||||
projectFile.reset();
|
||||
projectFile.open(QIODevice::WriteOnly|QIODevice::Truncate);
|
||||
if (!projectFile.isOpen())
|
||||
return false;
|
||||
projectFile.write(projectFileContent.toUtf8());
|
||||
projectFile.close();
|
||||
|
||||
|
@@ -51,6 +51,8 @@ public:
|
||||
const Utils::FilePath &targetDir);
|
||||
static void generateMenuEntry();
|
||||
static void onConvertProject();
|
||||
static bool isProjectConvertable(const ProjectExplorer::Project *project);
|
||||
static bool isProjectCurrentFormat(const ProjectExplorer::Project *project);
|
||||
|
||||
private:
|
||||
bool prepareAndExecute();
|
||||
@@ -68,11 +70,12 @@ private:
|
||||
const Utils::FilePath &original, const Utils::FilePath &target);
|
||||
bool createPreparedProject();
|
||||
|
||||
const Utils::FilePath contentDir();
|
||||
const Utils::FilePath sourceDir();
|
||||
const Utils::FilePath importDir();
|
||||
const Utils::FilePath assetDir();
|
||||
const Utils::FilePath assetImportDir();
|
||||
const Utils::FilePath contentDir() const;
|
||||
const Utils::FilePath sourceDir() const;
|
||||
const Utils::FilePath importDir() const;
|
||||
const Utils::FilePath assetDir() const;
|
||||
const Utils::FilePath assetImportDir() const;
|
||||
const Utils::FilePath newProjectFile() const;
|
||||
|
||||
const QString environmentVariable(const QString &key) const;
|
||||
const Utils::FilePath projectMainFile() const;
|
||||
|
@@ -121,6 +121,12 @@ void AssetsLibraryView::modelAboutToBeDetached(Model *model)
|
||||
|
||||
void AssetsLibraryView::setResourcePath(const QString &resourcePath)
|
||||
{
|
||||
|
||||
if (resourcePath == m_lastResourcePath)
|
||||
return;
|
||||
|
||||
m_lastResourcePath = resourcePath;
|
||||
|
||||
if (m_widget.isNull()) {
|
||||
m_widget = new AssetsLibraryWidget{m_imageCacheData->cache,
|
||||
m_imageCacheData->asynchronousFontImageCache,
|
||||
|
@@ -62,6 +62,7 @@ private:
|
||||
std::once_flag imageCacheFlag;
|
||||
std::unique_ptr<ImageCacheData> m_imageCacheData;
|
||||
QPointer<AssetsLibraryWidget> m_widget;
|
||||
QString m_lastResourcePath;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -321,6 +321,8 @@ static QHash<QByteArray, QStringList> allImageFormats()
|
||||
|
||||
void AssetsLibraryWidget::addResources(const QStringList &files)
|
||||
{
|
||||
clearSearchFilter();
|
||||
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
|
||||
QTC_ASSERT(document, return);
|
||||
|
@@ -141,12 +141,6 @@ void DesignerActionManagerView::bindingPropertiesChanged(const QList<BindingProp
|
||||
setupContext(SelectionContext::UpdateMode::Properties);
|
||||
}
|
||||
|
||||
void DesignerActionManagerView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &)
|
||||
{
|
||||
if (hasSingleSelectedModelNode())
|
||||
setupContext(SelectionContext::UpdateMode::Properties);
|
||||
}
|
||||
|
||||
void DesignerActionManagerView::customNotification(const AbstractView * /*view*/,
|
||||
const QString &identifier,
|
||||
const QList<ModelNode> & /* nodeList */,
|
||||
|
@@ -64,8 +64,6 @@ public:
|
||||
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||
void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||
|
||||
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
||||
|
||||
DesignerActionManager &designerActionManager();
|
||||
const DesignerActionManager &designerActionManager() const;
|
||||
void emitSelectionChanged();
|
||||
|
@@ -69,8 +69,7 @@ bool CurveEditorView::hasWidget() const
|
||||
|
||||
WidgetInfo CurveEditorView::widgetInfo()
|
||||
{
|
||||
return createWidgetInfo(
|
||||
m_editor, "CurveEditorId", WidgetInfo::BottomPane, 0, tr("CurveEditor"));
|
||||
return createWidgetInfo(m_editor, "CurveEditorId", WidgetInfo::BottomPane, 0, tr("Curve Editor"));
|
||||
}
|
||||
|
||||
void CurveEditorView::modelAttached(Model *model)
|
||||
|
@@ -2246,6 +2246,9 @@ void FormEditor3dPreview::paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
if (!painter->isActive())
|
||||
return;
|
||||
|
||||
|
@@ -357,6 +357,8 @@ void FormEditorWidget::initialize()
|
||||
defaultZoom = m_formEditorView->rootModelNode().auxiliaryData("formeditorZoom").toDouble();
|
||||
}
|
||||
m_graphicsView->setZoomFactor(defaultZoom);
|
||||
if (m_formEditorView->scene() && m_formEditorView->scene()->rootFormEditorItem())
|
||||
m_graphicsView->centerOn(m_formEditorView->scene()->rootFormEditorItem());
|
||||
m_zoomAction->setZoomFactor(defaultZoom);
|
||||
updateActions();
|
||||
}
|
||||
|
@@ -128,11 +128,9 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
||||
importPaths = model->importPaths();
|
||||
}
|
||||
|
||||
QString targetDir = defaulTargetDirectory;
|
||||
|
||||
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(doc->fileName());
|
||||
if (currentProject)
|
||||
targetDir = currentProject->projectDirectory().toString();
|
||||
QString targetDir = QmlDesignerPlugin::instance()->documentManager().currentProjectDirPath().toString();
|
||||
if (targetDir.isEmpty())
|
||||
targetDir = defaulTargetDirectory;
|
||||
|
||||
// Import is always done under known folder. The order of preference for folder is:
|
||||
// 1) An existing QUICK_3D_ASSETS_FOLDER under DEFAULT_ASSET_IMPORT_FOLDER project import path
|
||||
|
@@ -234,11 +234,6 @@ void ItemLibraryModel::showAllHiddenCategories()
|
||||
void ItemLibraryModel::setFlowMode(bool b)
|
||||
{
|
||||
m_flowMode = b;
|
||||
bool changed = false;
|
||||
if (updateVisibility(&changed); changed) {
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
ItemLibraryModel::ItemLibraryModel(QObject *parent)
|
||||
|
@@ -254,6 +254,20 @@ void ItemLibraryWidget::handleSearchfilterChanged(const QString &filterText)
|
||||
}
|
||||
}
|
||||
|
||||
QString ItemLibraryWidget::getDependencyImport(const Import &import)
|
||||
{
|
||||
static QStringList prefixDependencies = {"QtQuick3D"};
|
||||
|
||||
const QStringList splitImport = import.url().split('.');
|
||||
|
||||
if (splitImport.count() > 1) {
|
||||
if (prefixDependencies.contains(splitImport.first()))
|
||||
return splitImport.first();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::handleAddImport(int index)
|
||||
{
|
||||
Import import = m_addModuleModel->getImportAt(index);
|
||||
@@ -263,8 +277,19 @@ void ItemLibraryWidget::handleAddImport(int index)
|
||||
+ import.toImportString());
|
||||
}
|
||||
|
||||
QList<Import> imports;
|
||||
const QString dependency = getDependencyImport(import);
|
||||
|
||||
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
document->documentModel()->changeImports({import}, {});
|
||||
Model *model = document->documentModel();
|
||||
|
||||
if (!dependency.isEmpty()) {
|
||||
Import dependencyImport = m_addModuleModel->getImport(dependency);
|
||||
if (!dependencyImport.isEmpty())
|
||||
imports.append(dependencyImport);
|
||||
}
|
||||
imports.append(import);
|
||||
model->changeImports(imports, {});
|
||||
|
||||
QMetaObject::invokeMethod(m_itemsWidget->rootObject(), "switchToComponentsView");
|
||||
updateSearch();
|
||||
|
@@ -110,6 +110,7 @@ private:
|
||||
|
||||
void updateSearch();
|
||||
void handlePriorityImportsChanged();
|
||||
static QString getDependencyImport(const Import &import);
|
||||
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
@@ -421,14 +421,19 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
|
||||
context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
|
||||
|
||||
// className
|
||||
auto valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className"))));
|
||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
||||
m_backendValuesPropertyMap.value(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)));
|
||||
if (!valueObject)
|
||||
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
|
||||
valueObject->setName("className");
|
||||
valueObject->setName(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY);
|
||||
valueObject->setModelNode(qmlObjectNode.modelNode());
|
||||
valueObject->setValue(m_backendModelNode.simplifiedTypeName());
|
||||
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(QLatin1String("className"), QVariant::fromValue(valueObject));
|
||||
QObject::connect(valueObject,
|
||||
&PropertyEditorValue::valueChanged,
|
||||
&backendValuesPropertyMap(),
|
||||
&DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY,
|
||||
QVariant::fromValue(valueObject));
|
||||
|
||||
// id
|
||||
valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("id"))));
|
||||
@@ -506,14 +511,19 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl
|
||||
foreach (const PropertyName &propertyName, metaInfo.propertyNames())
|
||||
setupPropertyEditorValue(propertyName, propertyEditor, QString::fromUtf8(metaInfo.propertyTypeName(propertyName)));
|
||||
|
||||
auto valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className"))));
|
||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
||||
m_backendValuesPropertyMap.value(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)));
|
||||
if (!valueObject)
|
||||
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
|
||||
valueObject->setName("className");
|
||||
valueObject->setName(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY);
|
||||
|
||||
valueObject->setValue(typeName);
|
||||
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(QLatin1String("className"), QVariant::fromValue(valueObject));
|
||||
QObject::connect(valueObject,
|
||||
&PropertyEditorValue::valueChanged,
|
||||
&backendValuesPropertyMap(),
|
||||
&DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY,
|
||||
QVariant::fromValue(valueObject));
|
||||
|
||||
// id
|
||||
valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("id"))));
|
||||
|
@@ -144,7 +144,7 @@ void PropertyEditorView::changeValue(const QString &name)
|
||||
if (locked())
|
||||
return;
|
||||
|
||||
if (propertyName == "className")
|
||||
if (propertyName == Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)
|
||||
return;
|
||||
|
||||
if (noValidSelection())
|
||||
|
@@ -464,7 +464,8 @@ void RewriterView::auxiliaryDataChanged(const ModelNode &node, const PropertyNam
|
||||
return;
|
||||
|
||||
if (node.isRootNode()) {
|
||||
if (name == "width" || name == "height" || name == "autoSize" || name == "formeditorColor")
|
||||
if (name == "width" || name == "height" || name == "autoSize" || name == "formeditorColor"
|
||||
|| name == "formeditorZoom")
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ class ProjectStorage;
|
||||
|
||||
using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>;
|
||||
|
||||
class FileSystem final : public FileSystemInterface
|
||||
class FileSystem : public FileSystemInterface
|
||||
{
|
||||
public:
|
||||
FileSystem(PathCache &sourcePathCache)
|
||||
|
@@ -1924,6 +1924,8 @@ private:
|
||||
void createTypesAndePropertyDeclarationsTables(Database &database,
|
||||
const Sqlite::Column &foreignModuleIdColumn)
|
||||
{
|
||||
Q_UNUSED(foreignModuleIdColumn)
|
||||
|
||||
Sqlite::Table typesTable;
|
||||
typesTable.setUseIfNotExists(true);
|
||||
typesTable.setName("types");
|
||||
|
@@ -214,11 +214,7 @@ void DesignModeWidget::setup()
|
||||
m_dockManager->setStyleSheet(Theme::replaceCssColors(sheet));
|
||||
|
||||
// Setup icons
|
||||
const QColor iconColor(Theme::getColor(Theme::DStitleBarIcon));
|
||||
|
||||
const QString closeUnicode = Theme::getIconUnicode(Theme::Icon::adsClose);
|
||||
const QString menuUnicode = Theme::getIconUnicode(Theme::Icon::adsDropDown);
|
||||
const QString undockUnicode = Theme::getIconUnicode(Theme::Icon::adsDetach);
|
||||
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
const QSize size = QSize(28, 28);
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#include <QMetaObject>
|
||||
|
||||
namespace Utils {
|
||||
namespace QmlDesigner {
|
||||
|
||||
enum FoundLicense {
|
||||
community,
|
@@ -107,6 +107,8 @@ const char EVENT_TIMELINE_TIME[] = "Timeline";
|
||||
const char EVENT_TRANSITIONEDITOR_TIME[] = "Transition Editor";
|
||||
const char EVENT_CURVEDITOR_TIME[] = "Curve Editor";
|
||||
|
||||
const char PROPERTY_EDITOR_CLASSNAME_PROPERTY[] = "__classNamePrivateInternal";
|
||||
|
||||
namespace Internal {
|
||||
enum { debug = 0 };
|
||||
}
|
||||
|
@@ -312,8 +312,11 @@ bool QmlDesignerPlugin::delayedInitialize()
|
||||
d->viewManager.registerFormEditorTool(std::make_unique<QmlDesigner::PathTool>());
|
||||
d->viewManager.registerFormEditorTool(std::make_unique<QmlDesigner::TransitionTool>());
|
||||
|
||||
if (QmlProjectManager::QmlProject::isQtDesignStudio())
|
||||
if (QmlProjectManager::QmlProject::isQtDesignStudio()) {
|
||||
emitUsageStatistics("StandaloneMode");
|
||||
if (QmlProjectManager::QmlProject::isQtDesignStudioStartedFromQtC())
|
||||
emitUsageStatistics("QDSlaunchedFromQtC");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -135,8 +135,6 @@ QmlProject::QmlProject(const Utils::FilePath &fileName)
|
||||
disconnect(m_openFileConnection);
|
||||
|
||||
if (target && success) {
|
||||
const Utils::FilePath &folder = projectDirectory() + "/content";
|
||||
|
||||
Utils::FilePaths uiFiles = getUiQmlFilesForFolder(projectDirectory()
|
||||
+ "/content");
|
||||
if (uiFiles.isEmpty())
|
||||
@@ -517,6 +515,11 @@ bool QmlProject::isQtDesignStudio()
|
||||
return settings->value(qdsStandaloneEntry, false).toBool();
|
||||
}
|
||||
|
||||
bool QmlProject::isQtDesignStudioStartedFromQtC()
|
||||
{
|
||||
return qEnvironmentVariableIsSet(Constants::enviromentLaunchedQDS);
|
||||
}
|
||||
|
||||
ProjectExplorer::DeploymentKnowledge QmlProject::deploymentKnowledge() const
|
||||
{
|
||||
return DeploymentKnowledge::Perfect;
|
||||
|