diff --git a/doc/qtcreator/images/qtcreator-custom-wizard.png b/doc/qtcreator/images/qtcreator-custom-wizard.png index 818380aac35..73d3b417b83 100644 Binary files a/doc/qtcreator/images/qtcreator-custom-wizard.png and b/doc/qtcreator/images/qtcreator-custom-wizard.png differ diff --git a/doc/qtcreator/images/qtcreator-options-environment-system.png b/doc/qtcreator/images/qtcreator-options-environment-system.png index bc7ccc8ee8c..9d6cb599c12 100644 Binary files a/doc/qtcreator/images/qtcreator-options-environment-system.png and b/doc/qtcreator/images/qtcreator-options-environment-system.png differ diff --git a/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc b/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc index 3211d7d950a..d6f5709c372 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc @@ -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. diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc index 62ef588555b..44fe1cc1f56 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc @@ -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}. diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards.qdoc index 0a4fc154023..c9f5cc6e5a4 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards.qdoc @@ -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 diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc index 6a4dc9bf922..c47b9144e40 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc @@ -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 diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc index 3eb7e5401fb..4462b218139 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc @@ -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 diff --git a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc index ff0fef58ddd..ad53a9912c3 100644 --- a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc +++ b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc @@ -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 diff --git a/doc/qtdesignstudio/images/studio-examples-download.png b/doc/qtdesignstudio/images/studio-examples-download.png index 7902b4ce7c0..c03679db6b6 100644 Binary files a/doc/qtdesignstudio/images/studio-examples-download.png and b/doc/qtdesignstudio/images/studio-examples-download.png differ diff --git a/doc/qtdesignstudio/images/studio-welcome-mode.png b/doc/qtdesignstudio/images/studio-welcome-mode.png index 1518b6706cd..a9be0b021c7 100644 Binary files a/doc/qtdesignstudio/images/studio-welcome-mode.png and b/doc/qtdesignstudio/images/studio-welcome-mode.png differ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc b/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc index e319a0042b9..17701d3328b 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc +++ b/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc @@ -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. diff --git a/doc/qtdesignstudio/src/qtdesignstudio-examples.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-examples.qdoc index 8a0f9fa3983..f7bd979b442 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-examples.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-examples.qdoc @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp index d2a9ee219fc..b556620c54f 100644 --- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp @@ -28,6 +28,7 @@ #include "sharedmemory.h" #include #include +#include #include @@ -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(sharedMemory.constData()) + 6, byteCount); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp index d5371e4b5e4..8b6135c6222 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp @@ -125,6 +125,7 @@ bool startCrashpad() // Optional arguments to pass to the handler std::vector arguments; + arguments.push_back("--no-rate-limit"); CrashpadClient *client = new CrashpadClient(); bool success = client->StartHandler( diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index f254a325508..9ec7d8fcf39 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -424,7 +424,7 @@ Item { width: parent.width height: parent.height - y clip: true - interactive: assetsView.verticalScrollBarVisible + interactive: assetsView.verticalScrollBarVisible && !contextMenu.opened Column { Repeater { diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index e43342d650d..bc0dc79ef25 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -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) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index a55280a0401..da7baf018b1 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -99,7 +99,7 @@ PropertyEditorPane { anchors.right: parent.right StudioControls.TabButton { - text: backendValues.className.value + text: backendValues.__classNamePrivateInternal.value } StudioControls.TabButton { text: qsTr("Layout") diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml index 5d9a121a913..2dae032f37c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml @@ -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() } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index a4541f165ab..29d0edb14db 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl index e1a30300696..80749182e65 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl index 28dcc8c7993..e295083958c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl index c4b60bd1145..7faa6c38be8 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl index f166ec5fd3e..d742e03b5d5 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl index 1067762387f..5031b5bd596 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl index 98d0e3b9f82..69e09a6205f 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl index aa4ff234c9a..c9fa8671cda 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl @@ -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 } diff --git a/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl index 4ff09e0de31..1c8d7f0a075 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl index 96f78daf9fc..55d0f2b37e9 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl index 0f484b8ddbc..513543f0597 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl index 42ef999948a..4a8ea4bc4ac 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl index 61358e38872..6ce5dccccc5 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl index f77f7d99c99..47ca3af2995 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl index ec23bbe684a..d4b196965f3 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl index 45319ec391f..8da593bd703 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl @@ -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 { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl index 730906111be..1da5c8844ba 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl index 0d8148e73e3..600031122e8 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl @@ -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 diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl index 04bef01ff1e..1527710b087 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl index 04bef01ff1e..1527710b087 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl index 189ca84cc97..97f9fdd87c9 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl index baadb452b69..40c91d79f37 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl index ee2006559bc..100fef9bb99 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl index 757dad13e80..3816fb7a001 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl @@ -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} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl index 50aee8af120..9e741b11627 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl @@ -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} diff --git a/src/app/main.cpp b/src/app/main.cpp index 42557c3d2b7..a4ef3eea329 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -438,6 +438,7 @@ bool startCrashpad(const QString &libexecPath, bool crashReportingEnabled) // Optional arguments to pass to the handler std::vector arguments; + arguments.push_back("--no-rate-limit"); CrashpadClient *client = new CrashpadClient(); bool success = client->StartHandler( diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index f4b1b93c861..92c7095efd6 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -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,9 +808,11 @@ 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") - .arg(platformSpec, platformSpecification.errorString())); + if (!platformSpecification.isValid()) { + return reportError(::ExtensionSystem::Internal::PluginSpecPrivate::tr( + "Invalid platform specification \"%1\": %2") + .arg(platformSpec, platformSpecification.errorString())); + } } value = metaData.value(QLatin1String(DEPENDENCIES)); @@ -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,11 +865,13 @@ 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\").") - .arg(QLatin1String(DEPENDENCY_TYPE), - QLatin1String(DEPENDENCY_TYPE_HARD), - QLatin1String(DEPENDENCY_TYPE_SOFT), - typeValue)); + 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), + typeValue)); } } dependencies.append(dep); @@ -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 diff --git a/src/libs/nanotrace/nanotrace.h b/src/libs/nanotrace/nanotrace.h index ea26487e408..e71e6e8c19b 100644 --- a/src/libs/nanotrace/nanotrace.h +++ b/src/libs/nanotrace/nanotrace.h @@ -35,6 +35,7 @@ #include // revert when macos minimum target is >= 10.14 +#include #include #include diff --git a/src/libs/qlitehtml b/src/libs/qlitehtml index 62a1650652f..37c295f4320 160000 --- a/src/libs/qlitehtml +++ b/src/libs/qlitehtml @@ -1 +1 @@ -Subproject commit 62a1650652fe5aa45f3e79e4b1a26f3bf92c6d4b +Subproject commit 37c295f4320840b646e84e1cbda8aa07eafc353a diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index d098dc6f44f..652ec459cf0 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -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 diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 9de48da0ee5..7400020bbb9 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 BogDan Vatra ** 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 &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(); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 7492ae0f2a3..5338845d0d2 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 BogDan Vatra ** 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 &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(); diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 1d76083a6e0..69b57651445 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -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\".") diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index a14b985ad74..fbecdc14033 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 BogDan Vatra ** Contact: https://www.qt.io/licensing/ ** @@ -52,6 +52,10 @@ #include #include #include +#include +#include + +#include 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(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(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())); } -void AndroidDeviceManager::setupDevicesWatcher() +QString AndroidDeviceManager::getRunningAvdsSerialNumber(const QString &name) const { - 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(); - }); - m_devicesUpdaterTimer.start(deviceUpdaterMsInterval); + 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; } - updateDevicesListOnce(); + + return {}; } -void AndroidDeviceManager::devicesListUpdated() +void AndroidDeviceManager::setupDevicesWatcher() { - QVector 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 startedAvds = Utils::transform(connectedDevicesInfos, - &AndroidDeviceInfo::avdname); - for (const AndroidDeviceInfo &dev : devices) - if (!startedAvds.contains(dev.avdname)) - connectedDevicesInfos << dev; - - DeviceManager *const devMgr = DeviceManager::instance(); - - QVector existingDevs; - QVector connectedDevs; - - 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); - } + if (!m_androidConfig.adbToolPath().exists()) { + qCDebug(androidDeviceLog) << "Cannot start ADB device watcher" + << "because adb path does not exist."; + return; } - for (auto item : connectedDevicesInfos) { + 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_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"); + } + 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::HandleAvdsListChange() +{ + DeviceManager *const devMgr = DeviceManager::instance(); + + QVector existingAvds; + for (int i = 0; i < devMgr->deviceCount(); ++i) { + const IDevice::ConstPtr dev = devMgr->deviceAt(i); + const bool isEmulator = dev->machineType() == IDevice::Emulator; + if (isEmulator && dev->type() == Constants::ANDROID_DEVICE_TYPE) + existingAvds.append(dev); + } + + QVector 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(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.", - dev->id().toString().toUtf8().data()); - devMgr->setDeviceState(dev->id(), IDevice::DeviceDisconnected); + // Set devices no longer connected to disconnected state. + 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->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(); }); diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h index 3d08f09315c..8a8abe70ada 100644 --- a/src/plugins/android/androiddevice.h +++ b/src/plugins/android/androiddevice.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2016 BogDan Vatra ** Contact: https://www.qt.io/licensing/ ** @@ -33,8 +33,10 @@ #include #include +#include + #include -#include +#include 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 m_avdsFutureWatcher; - QFutureWatcher> m_devicesFutureWatcher; QFutureWatcher> m_removeAvdFutureWatcher; - QTimer m_devicesUpdaterTimer; + QFileSystemWatcher m_avdFileSystemWatcher; + std::unique_ptr m_adbDeviceWatcherProcess; AndroidConfig &m_androidConfig; AndroidAvdManager m_avdManager; }; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 0b009d9b5c0..b989bba6854 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2779,6 +2779,8 @@ static void semanticHighlighter(QFutureInterface &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 &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()); } @@ -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) diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index d03fcc2c896..98e720ba25c 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1295,6 +1295,13 @@ void ClangdTestHighlighting::test_data() QTest::newRow("keywords: true") << 920 << 15 << 920 << 19 << QList{C_KEYWORD} << 0; QTest::newRow("keywords: false") << 921 << 15 << 921 << 20 << QList{C_KEYWORD} << 0; QTest::newRow("keywords: nullptr") << 922 << 15 << 922 << 22 << QList{C_KEYWORD} << 0; + QTest::newRow("operator<<") << 934 << 10 << 934 << 14 << QList{C_GLOBAL} << 0; + QTest::newRow("operator>>") << 936 << 10 << 936 << 13 << QList{C_GLOBAL} << 0; + QTest::newRow("operator>>") << 936 << 17 << 936 << 18 << QList{C_LOCAL} << 0; + QTest::newRow("input arg from passed object") << 945 << 17 << 945 << 18 + << QList{C_FIELD} << 0; + QTest::newRow("output arg") << 945 << 20 << 945 << 23 + << QList{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index c54dfe13710..6230e7f0392 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -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 +void transform(const From &from, To &&to, Op op) {} +struct WithVector { std::vector v; }; +void inputsAndOutputsFromObject(const WithVector &s) +{ + std::vector out; + transform(s.v, out, [] {}); +} diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp index 73f6f1e2280..e170fc49179 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.cpp +++ b/src/plugins/cmakeprojectmanager/configmodel.cpp @@ -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; }); } diff --git a/src/plugins/cppeditor/cppcodestylesettings.cpp b/src/plugins/cppeditor/cppcodestylesettings.cpp index f5cc2fda8c8..eabaa47a61a 100644 --- a/src/plugins/cppeditor/cppcodestylesettings.cpp +++ b/src/plugins/cppeditor/cppcodestylesettings.cpp @@ -40,7 +40,6 @@ #include #include -static const char groupPostfix[] = "IndentSettings"; static const char indentBlockBracesKey[] = "IndentBlockBraces"; static const char indentBlockBodyKey[] = "IndentBlockBody"; static const char indentClassBracesKey[] = "IndentClassBraces"; diff --git a/src/plugins/imageviewer/imageview.cpp b/src/plugins/imageviewer/imageview.cpp index c5ef478e595..eebf8097bc0 100644 --- a/src/plugins/imageviewer/imageview.cpp +++ b/src/plugins/imageviewer/imageview.cpp @@ -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); diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index ec9bed459e5..f3b94676673 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -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 errorValue = shutdownResponse.error(); - if (errorValue.has_value()) { - ShutdownRequest::Response::Error error = errorValue.value(); - qDebug() << error; - return; - } + if (optional 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"; diff --git a/src/plugins/languageclient/diagnosticmanager.cpp b/src/plugins/languageclient/diagnosticmanager.cpp index 3336726a72f..cdaadb7d4a8 100644 --- a/src/plugins/languageclient/diagnosticmanager.cpp +++ b/src/plugins/languageclient/diagnosticmanager.cpp @@ -88,26 +88,19 @@ void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri const QList &diagnostics, const Utils::optional &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(); - 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); + if (auto doc = TextDocument::textDocumentForFilePath(filePath)) { + for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) + editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, {}); + } + qDeleteAll(m_marks.take(filePath)); } static QTextEdit::ExtraSelection toDiagnosticsSelections(const Diagnostic &diagnostic, @@ -130,11 +123,11 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version) const FilePath &filePath = uri.toFilePath(); if (TextDocument *doc = TextDocument::textDocumentForFilePath(filePath)) { QList extraSelections; - const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri); + const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri); 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 &marks : qAsConst(m_marks)) + qDeleteAll(marks); + m_marks.clear(); + } } QList DiagnosticManager::diagnosticsAt(const DocumentUri &uri, diff --git a/src/plugins/languageclient/diagnosticmanager.h b/src/plugins/languageclient/diagnosticmanager.h index e3a2aefcc8e..a7e2e474852 100644 --- a/src/plugins/languageclient/diagnosticmanager.h +++ b/src/plugins/languageclient/diagnosticmanager.h @@ -56,10 +56,9 @@ public: void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri, const QList &diagnostics, const Utils::optional &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 diagnostics; }; QMap m_diagnostics; + QMap> m_marks; TextMarkCreator m_textMarkCreator; HideDiagnosticsHandler m_hideHandler; Client *m_client; diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index bce818f96a9..3cec5a2e491 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -427,7 +427,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( items = Utils::get>(*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(); } diff --git a/src/plugins/mcusupport/mcuabstractpackage.h b/src/plugins/mcusupport/mcuabstractpackage.h index 9406b474fb9..e0499ef06fa 100644 --- a/src/plugins/mcusupport/mcuabstractpackage.h +++ b/src/plugins/mcusupport/mcuabstractpackage.h @@ -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; diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index 5fffe2b8da3..a563a3828a3 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -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); diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index f108ca67f83..f4ca09355e4 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -28,37 +28,69 @@ #include "mcusupportversiondetection.h" #include "mcusupportsdk.h" +#include #include +#include #include #include #include +#include +#include +#include +#include +#include #include #include #include +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 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); } diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index dcc9917c1ce..5a57fad9658 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -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 diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index f47a3ddf951..47475fb8161 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -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) { diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index a4dfd3a6ceb..9ce33040ca0 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -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()); diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 812f181b97b..cc4aab3ccc5 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -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 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 diff --git a/src/plugins/mcusupport/mcusupportversiondetection.cpp b/src/plugins/mcusupport/mcusupportversiondetection.cpp index e4e944858b2..b5d2dc18a20 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.cpp +++ b/src/plugins/mcusupport/mcusupportversiondetection.cpp @@ -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(); diff --git a/src/plugins/mcusupport/mcusupportversiondetection.h b/src/plugins/mcusupport/mcusupportversiondetection.h index a5599591562..c5f25875d0d 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.h +++ b/src/plugins/mcusupport/mcusupportversiondetection.h @@ -26,6 +26,7 @@ #pragma once #include +#include 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; }; diff --git a/src/plugins/mcusupport/mcutarget.cpp b/src/plugins/mcusupport/mcutarget.cpp index 291b861e221..28628eeca51 100644 --- a/src/plugins/mcusupport/mcutarget.cpp +++ b/src/plugins/mcusupport/mcutarget.cpp @@ -26,196 +26,14 @@ #include "mcutarget.h" #include "mcupackage.h" #include "mcukitmanager.h" - #include "mcusupportplugin.h" -#include -#include -#include -#include -#include -#include +#include -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 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(), diff --git a/src/plugins/mcusupport/test/packagemock.h b/src/plugins/mcusupport/test/packagemock.h index 7f8e98d40f5..2e41ef6550b 100644 --- a/src/plugins/mcusupport/test/packagemock.h +++ b/src/plugins/mcusupport/test/packagemock.h @@ -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, ()); diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 30a6fa8a532..62b8fd9c278 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -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))); } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 742b6f055c0..bee619026ad 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -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 diff --git a/src/plugins/qmldesigner/cmakeprojectconverter.cpp b/src/plugins/qmldesigner/cmakeprojectconverter.cpp index 52448835771..9d1320438db 100644 --- a/src/plugins/qmldesigner/cmakeprojectconverter.cpp +++ b/src/plugins/qmldesigner/cmakeprojectconverter.cpp @@ -29,7 +29,9 @@ #include #include +#include +#include #include #include @@ -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(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(); diff --git a/src/plugins/qmldesigner/cmakeprojectconverter.h b/src/plugins/qmldesigner/cmakeprojectconverter.h index 4b21d65ac8b..c5f4361cb11 100644 --- a/src/plugins/qmldesigner/cmakeprojectconverter.h +++ b/src/plugins/qmldesigner/cmakeprojectconverter.h @@ -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; diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp index 2fc4aacac3c..3bb1f3cb21a 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp @@ -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, diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h index 79fbde852f9..ae623a183b3 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h @@ -62,6 +62,7 @@ private: std::once_flag imageCacheFlag; std::unique_ptr m_imageCacheData; QPointer m_widget; + QString m_lastResourcePath; }; } diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 0ead75ccea3..21478fd39d3 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -321,6 +321,8 @@ static QHash allImageFormats() void AssetsLibraryWidget::addResources(const QStringList &files) { + clearSearchFilter(); + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); QTC_ASSERT(document, return); diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp index 026596b876d..65da49ed6b5 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp @@ -141,12 +141,6 @@ void DesignerActionManagerView::bindingPropertiesChanged(const QList > &) -{ - if (hasSingleSelectedModelNode()) - setupContext(SelectionContext::UpdateMode::Properties); -} - void DesignerActionManagerView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList & /* nodeList */, diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h index f7777bcac1d..5920658857f 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h @@ -64,8 +64,6 @@ public: void variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChangeFlag) override; void bindingPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChangeFlag) override; - void instancePropertyChanged(const QList > &propertyList) override; - DesignerActionManager &designerActionManager(); const DesignerActionManager &designerActionManager() const; void emitSelectionChanged(); diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index a6c228ccbc9..e7bf42aa4ff 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -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) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index 95d92e68fe9..4146b066489 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -2246,6 +2246,9 @@ void FormEditor3dPreview::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + Q_UNUSED(option) + Q_UNUSED(widget) + if (!painter->isActive()) return; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 9f6a88c5962..6991c561414 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -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(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp index 135eaaf5aaf..1f974419c79 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp @@ -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 diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index d15109e61e0..b3d67f5c8ed 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -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) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 7b8c0c2a3f4..516dfa233b1 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -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 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(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 7a3db274f84..500b3f71970 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -110,6 +110,7 @@ private: void updateSearch(); void handlePriorityImportsChanged(); + static QString getDependencyImport(const Import &import); QTimer m_compressionTimer; QSize m_itemIconSize; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index b9c2ce67684..5d6e16670e4 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -421,14 +421,19 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode); // className - auto valueObject = qobject_cast(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className")))); + auto valueObject = qobject_cast(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(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(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className")))); + auto valueObject = qobject_cast(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(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("id")))); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 5ea8e9ec652..7c2b3230a13 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -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()) diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 5f211b86056..39b24186232 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -1576,9 +1576,9 @@ QUrl Model::fileUrl() const QUrl Model::projectUrl() const { #ifndef QMLDESIGNER_TEST -DesignDocument *document = QmlDesignerPlugin::instance()->viewManager().currentDesignDocument(); -if (document) - return QUrl::fromLocalFile(document->projectFolder().toString()); + DesignDocument *document = QmlDesignerPlugin::instance()->viewManager().currentDesignDocument(); + if (document) + return QUrl::fromLocalFile(document->projectFolder().toString()); #endif return {}; } diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index 19f37907b23..ff9f7b196b7 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -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; } diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h index 041090508e4..5c054367c8a 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h @@ -43,7 +43,7 @@ class ProjectStorage; using PathCache = SourcePathCache, NonLockingMutex>; -class FileSystem final : public FileSystemInterface +class FileSystem : public FileSystemInterface { public: FileSystem(PathCache &sourcePathCache) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index e77ba16bad3..c7c182279f1 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -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"); diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 25de59b3c06..140dedc3218 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -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); diff --git a/src/libs/utils/dynamiclicensecheck.h b/src/plugins/qmldesigner/dynamiclicensecheck.h similarity index 98% rename from src/libs/utils/dynamiclicensecheck.h rename to src/plugins/qmldesigner/dynamiclicensecheck.h index 634c6b28d11..8cc7982895c 100644 --- a/src/libs/utils/dynamiclicensecheck.h +++ b/src/plugins/qmldesigner/dynamiclicensecheck.h @@ -34,7 +34,7 @@ #include -namespace Utils { +namespace QmlDesigner { enum FoundLicense { community, diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 1bfdbb8ddbf..03c2f42cca3 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -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 }; } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 3748a2164e0..fafbce3809c 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -312,8 +312,11 @@ bool QmlDesignerPlugin::delayedInitialize() d->viewManager.registerFormEditorTool(std::make_unique()); d->viewManager.registerFormEditorTool(std::make_unique()); - if (QmlProjectManager::QmlProject::isQtDesignStudio()) + if (QmlProjectManager::QmlProject::isQtDesignStudio()) { emitUsageStatistics("StandaloneMode"); + if (QmlProjectManager::QmlProject::isQtDesignStudioStartedFromQtC()) + emitUsageStatistics("QDSlaunchedFromQtC"); + } return true; } diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index e96dadb970b..0864a478280 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -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; diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index a351d394c7d..fed2002912a 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -147,6 +147,7 @@ public: ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final; static bool isQtDesignStudio(); + static bool isQtDesignStudioStartedFromQtC(); bool isEditModePreferred() const override; diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h index 184469f2430..3ba2b101462 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectconstants.h +++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h @@ -41,5 +41,7 @@ const char customQt6Project[] = "CustomQt6Project"; const char mainFilePath[] = "MainFilePath"; const char customImportPaths[] = "CustomImportPaths"; const char canonicalProjectDir[] ="CanonicalProjectDir"; + +const char enviromentLaunchedQDS[] = "QTC_LAUNCHED_QDS"; } // namespace Constants } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 2922c55aea7..17cce6402f8 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -25,6 +25,7 @@ #include "qmlprojectplugin.h" #include "qmlproject.h" +#include "qmlprojectconstants.h" #include "qmlprojectrunconfiguration.h" #include @@ -105,6 +106,7 @@ void QmlProjectPlugin::openQDS(const Utils::FilePath &fileName) { const Utils::FilePath &qdsPath = QmlProjectPlugin::qdsInstallationEntry(); bool qdsStarted = false; + qputenv(Constants::enviromentLaunchedQDS, "true"); //-a and -client arguments help to append project to open design studio application if (Utils::HostOsInfo::isMacHost()) qdsStarted = Utils::QtcProcess::startDetached( diff --git a/src/plugins/studiowelcome/examplecheckout.cpp b/src/plugins/studiowelcome/examplecheckout.cpp index 06d37a39317..267295b1713 100644 --- a/src/plugins/studiowelcome/examplecheckout.cpp +++ b/src/plugins/studiowelcome/examplecheckout.cpp @@ -106,7 +106,7 @@ void FileDownloader::start() emit progressChanged(); }); - QNetworkReply::connect(reply, &QNetworkReply::redirected, [reply](const QUrl &url) { + QNetworkReply::connect(reply, &QNetworkReply::redirected, [reply](const QUrl &) { emit reply->redirectAllowed(); }); @@ -188,7 +188,7 @@ void FileDownloader::probeUrl() QNetworkRequest::UserVerifiedRedirectPolicy); QNetworkReply *reply = Utils::NetworkAccessManager::instance()->head(request); - QNetworkReply::connect(reply, &QNetworkReply::redirected, [reply](const QUrl &url) { + QNetworkReply::connect(reply, &QNetworkReply::redirected, [reply](const QUrl &) { emit reply->redirectAllowed(); }); @@ -217,7 +217,7 @@ void FileDownloader::probeUrl() QNetworkReply::connect(reply, &QNetworkReply::errorOccurred, this, - [this, reply](QNetworkReply::NetworkError code) { + [this](QNetworkReply::NetworkError) { QQmlData *data = QQmlData::get(this, false); if (!data) { qDebug() << Q_FUNC_INFO << "FileDownloader is nullptr."; diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 861695898c9..86dcc2314ec 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -46,8 +46,9 @@ #include -#include #include +#include +#include #include #include @@ -56,7 +57,6 @@ #include #include #include -#include #include #include @@ -274,6 +274,10 @@ public: const QString &tempFile, const QString &completeBaseName) { + Q_UNUSED(url) + Q_UNUSED(explicitQmlproject) + Q_UNUSED(tempFile) + Q_UNUSED(completeBaseName) const Utils::FilePath projectFile = Core::ICore::resourcePath("examples") / example / example + ".qmlproject"; ProjectExplorer::ProjectExplorerPlugin::openProjectWelcomePage(projectFile.toString()); @@ -300,9 +304,9 @@ private: void ProjectModel::setupVersion() { - Utils::FoundLicense license = Utils::checkLicense(); - m_communityVersion = license == Utils::FoundLicense::community; - m_enterpriseVersion = license == Utils::FoundLicense::enterprise; + QmlDesigner::FoundLicense license = QmlDesigner::checkLicense(); + m_communityVersion = license == QmlDesigner::FoundLicense::community; + m_enterpriseVersion = license == QmlDesigner::FoundLicense::enterprise; } ProjectModel::ProjectModel(QObject *parent) @@ -660,8 +664,11 @@ void StudioWelcomePlugin::resumeRemoveSplashTimer() Utils::FilePath StudioWelcomePlugin::defaultExamplesPath() { - return Utils::FilePath::fromString( - QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) + QStandardPaths::StandardLocation location = Utils::HostOsInfo::isMacHost() + ? QStandardPaths::HomeLocation + : QStandardPaths::DocumentsLocation; + + return Utils::FilePath::fromString(QStandardPaths::writableLocation(location)) .pathAppended("QtDesignStudio"); } diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.h b/src/plugins/studiowelcome/studiowelcomeplugin.h index cd6b8ea87f2..1fdc811d37e 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.h +++ b/src/plugins/studiowelcome/studiowelcomeplugin.h @@ -38,6 +38,8 @@ namespace Internal { class StudioSettingsPage : public Core::IOptionsPageWidget { + Q_OBJECT + public: void apply() final; diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp index 353a5d703fe..e2271ad396f 100644 --- a/src/plugins/updateinfo/updateinfoplugin.cpp +++ b/src/plugins/updateinfo/updateinfoplugin.cpp @@ -209,7 +209,7 @@ struct QtPackage QString displayName; QVersionNumber version; bool installed; - bool isPrerelease; + bool isPrerelease = false; }; static QList availableQtPackages(const QDomDocument &document) diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index ef4c969be66..938e776ac87 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -110,6 +110,8 @@ void ResizeSignallingWidget::resizeEvent(QResizeEvent *event) class WelcomeMode : public IMode { + Q_OBJECT + public: WelcomeMode(); ~WelcomeMode(); diff --git a/src/plugins/winrt/WinRt.json.in b/src/plugins/winrt/WinRt.json.in index fef26890bfb..e776ddf9616 100644 --- a/src/plugins/winrt/WinRt.json.in +++ b/src/plugins/winrt/WinRt.json.in @@ -2,7 +2,7 @@ \"Name\" : \"WinRt\", \"Version\" : \"$$QTCREATOR_VERSION\", \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\", - \"Platform\" : \"Windows (8.1|10)\", + \"Platform\" : \"Windows (8.1|10|11)\", \"Vendor\" : \"The Qt Company Ltd\", \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\", \"License\" : [ \"Commercial Usage\", diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71bf9613a5d..3e961231ca5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(auto) add_subdirectory(manual) -# add_subdirectory(tools) +add_subdirectory(tools/qml-ast2dot) add_subdirectory(unit) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 3b2342e97e3..4c6c9919d0c 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1648,7 +1648,7 @@ void tst_Dumpers::dumper() if (data.allProfile.isEmpty()) { // Nim... if (!error.isEmpty()) { - qDebug() << error; QVERIFY(false); + qDebug() << error; QVERIFY(qmake.exitCode() == 0); } } } diff --git a/tests/tests.qbs b/tests/tests.qbs index adabf7a3982..fc634c93d08 100644 --- a/tests/tests.qbs +++ b/tests/tests.qbs @@ -5,6 +5,7 @@ Project { references: [ "auto/auto.qbs", "manual/manual.qbs", + "tools/qml-ast2dot/qml-ast2dot.qbs", "unit/unit.qbs", ] } diff --git a/tests/tools/qml-ast2dot/CMakeLists.txt b/tests/tools/qml-ast2dot/CMakeLists.txt new file mode 100644 index 00000000000..5e4a852243d --- /dev/null +++ b/tests/tools/qml-ast2dot/CMakeLists.txt @@ -0,0 +1,13 @@ +add_qtc_executable(qml_ast2dot + BUILD_DEFAULT OFF + DEPENDS Qt5::Core Qt5::Gui QmlJS + SOURCES main.cpp +) + +extend_qtc_executable(qml_ast2dot + PROPERTIES + OUTPUT_NAME "qml-ast2dot" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/tests/tools/qml-ast2dot/qml-ast2dot.qbs b/tests/tools/qml-ast2dot/qml-ast2dot.qbs new file mode 100644 index 00000000000..2fbf3676c99 --- /dev/null +++ b/tests/tools/qml-ast2dot/qml-ast2dot.qbs @@ -0,0 +1,21 @@ +import qbs.FileInfo + +CppApplication { + Depends { name: "QmlJS" } + Depends { name: "Qt.gui" } + + cpp.cxxLanguageVersion: "c++17" + consoleApplication: true + targetName: "qml-ast2dot" + builtByDefault: false + + files: [ + "main.cpp" + ] + + destinationDirectory: FileInfo.joinPaths( + FileInfo.path(project.buildDirectory + '/' + + FileInfo.relativePath(project.ide_source_tree, + sourceDirectory)), + "qml-ast2dot") +}