diff --git a/dist/changes-8.0.2.md b/dist/changes-8.0.2.md new file mode 100644 index 00000000000..7dc343604d1 --- /dev/null +++ b/dist/changes-8.0.2.md @@ -0,0 +1,91 @@ +Qt Creator 8.0.2 +================ + +Qt Creator version 8.0.2 contains bug fixes. + +The most important changes are listed in this document. For a complete list of +changes, see the Git log for the Qt Creator sources that you can check out from +the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/v8.0.1..v8.0.2 + +Editing +------- + +* Fixed importing color schemes +* Fixed moving text between editors by drag & drop (QTCREATORBUG-28125, + QTCREATORBUG-28126) +* Fixed that the default font could be blurry (QTCREATORBUG-28106, + QTCREATORBUG-28139) + +### C++ + +* Re-added non-Clangd version of `Extract Function` (QTCREATORBUG-28030) + +### Language Client + +* Fixed issues after resetting server (QTCREATORBUG-27596) + +### SCXML + +* Fixed crash when closing document (QTCREATORBUG-28027) + +Version Control +--------------- + +* Fixed handling of `\r` in tool output (QTCREATORBUG-27615) + +Test Integration +---------------- + +* GTest + * Fixed running selected tests (QTCREATORBUG-28153) +* Catch2 + * Fixed crash when running tests (QTCREATORBUG-28269) + +Platforms +--------- + +### Android + +* Fixed deployment in release mode (QTCREATORBUG-28163) + +### Remote Linux + +* Fixed issue with deployment (QTCREATORBUG-28167) +* Fixed key deployment on Windows (QTCREATORBUG-28092) +* Fixed killing remote processes (QTCREATORBUG-28072) + +Credits for these changes go to: +-------------------------------- +Aleksei German +Ali Kianian +André Pönitz +Antti Määttä +Brook Cronin +Christian Kandeler +Christian Stenger +Cristian Adam +David Schulz +Eike Ziller +Fawzi Mohamed +Henning Gruendl +Ivan Komissarov +Jaroslaw Kobus +Knud Dollereder +Leena Miettinen +Mahmoud Badri +Marco Bubke +Marcus Tillmanns +Mats Honkamaa +Miikka Heikkinen +Petri Virkkunen +Pranta Dastider +Robert Löhning +Samuel Ghinet +Sivert Krøvel +Sona Kurazyan +Thomas Hartmann +Tim Jenssen +Vikas Pachdha diff --git a/doc/qtcreator/images/icons/export.png b/doc/qtcreator/images/icons/export.png new file mode 100644 index 00000000000..80d2f3a950e Binary files /dev/null and b/doc/qtcreator/images/icons/export.png differ diff --git a/doc/qtcreator/images/icons/original-size.png b/doc/qtcreator/images/icons/original-size.png new file mode 100644 index 00000000000..8fc4ca3c36d Binary files /dev/null and b/doc/qtcreator/images/icons/original-size.png differ diff --git a/doc/qtcreator/images/icons/switch-outline.png b/doc/qtcreator/images/icons/switch-outline.png new file mode 100644 index 00000000000..564809bbda4 Binary files /dev/null and b/doc/qtcreator/images/icons/switch-outline.png differ diff --git a/doc/qtcreator/images/icons/zoom-in.png b/doc/qtcreator/images/icons/zoom-in.png new file mode 100644 index 00000000000..dae425382d5 Binary files /dev/null and b/doc/qtcreator/images/icons/zoom-in.png differ diff --git a/doc/qtcreator/images/icons/zoom-out.png b/doc/qtcreator/images/icons/zoom-out.png new file mode 100644 index 00000000000..3e889fded1a Binary files /dev/null and b/doc/qtcreator/images/icons/zoom-out.png differ diff --git a/doc/qtcreator/images/qtcreator-build-configurations.png b/doc/qtcreator/images/qtcreator-build-configurations.png index 8ca5f7054df..ce66706c311 100644 Binary files a/doc/qtcreator/images/qtcreator-build-configurations.png and b/doc/qtcreator/images/qtcreator-build-configurations.png differ diff --git a/doc/qtcreator/images/qtcreator-image-viewer.png b/doc/qtcreator/images/qtcreator-image-viewer.png index 81ef75a2ed7..640c0eefbb6 100644 Binary files a/doc/qtcreator/images/qtcreator-image-viewer.png and b/doc/qtcreator/images/qtcreator-image-viewer.png differ diff --git a/doc/qtcreator/images/qtcreator-project-kits.png b/doc/qtcreator/images/qtcreator-project-kits.png index e6c1434c9cc..16bf3a0dad0 100644 Binary files a/doc/qtcreator/images/qtcreator-project-kits.png and b/doc/qtcreator/images/qtcreator-project-kits.png differ diff --git a/doc/qtcreator/src/analyze/creator-coco.qdoc b/doc/qtcreator/src/analyze/creator-coco.qdoc index 64a239aec00..3a714d9bc08 100644 --- a/doc/qtcreator/src/analyze/creator-coco.qdoc +++ b/doc/qtcreator/src/analyze/creator-coco.qdoc @@ -9,7 +9,7 @@ \title Checking Code Coverage \l{https://doc.qt.io/coco/}{Coco} is a complete code coverage tool chain for - Tcl, QML, C# and C/C++ programs that runs on \macOS, Linux, and Windows. + Tcl, QML, C# and C/C++ programs, which runs on \macOS, Linux, and Windows. Coco analyzes the way an application runs, as part of a test suite, for example. The results enable you to make the tests more efficient and @@ -36,7 +36,7 @@ The experimental Coco plugin integrates Coco CoverageBrowser into \QC. It enables you to analyze the test coverage by loading an instrumentation - database (a .csmes file) that was generated by Coco CoverageScanner. + database (a .csmes file), which was generated by Coco CoverageScanner. It is currently supported only on Windows, with Coco version 6.0, or later. diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc index 2e8d893c197..1b675abe6ec 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc @@ -15,6 +15,10 @@ settings and displays it in \uicontrol {Initial Configuration} in the \l{Specifying Build Settings}{Build Settings} of the project. + The \uicontrol Configuration field displays the effective CMake call that + is constructed by using the values of the \uicontrol {Build directory} and + \uicontrol {Build type} fields. + \image qtcreator-cmake-build-settings-initial.png "CMake build settings" \uicontrol {Initial Configuration} lists the variables that are used to @@ -47,7 +51,7 @@ Select \uicontrol {Kit Configuration} to edit the CMake settings for the build and run kit selected for the project. - \section CMake Presets + \section1 CMake Presets You can use CMake presets files to specify common configure, build, and test options and share them with others. \c CMakePresets.json contains options for diff --git a/doc/qtcreator/src/user-interface/creator-ui.qdoc b/doc/qtcreator/src/user-interface/creator-ui.qdoc index baae9e3ec2f..bbf9b13b376 100644 --- a/doc/qtcreator/src/user-interface/creator-ui.qdoc +++ b/doc/qtcreator/src/user-interface/creator-ui.qdoc @@ -196,26 +196,26 @@ \image qtcreator-image-viewer.png "Image viewer" - Use the toolbar buttons (1) or \l{Keyboard Shortcuts}{keyboard shortcuts} - to: + Use the toolbar buttons or \l{Keyboard Shortcuts}{keyboard shortcuts} to: \list - - \li Export SVG images to pixmaps - - \li Copy an image as a data URL, which enables you to include it in web - pages as if it were an external resource - - \li Switch between background and outline modes - - \li Zoom in and out - - \li Fit images to screen - - \li Return to original size - - \li Play and pause animated GIF and MNG images - + \li \inlineimage icons/export.png + - Export SVG images to pixmaps or copy an image as a data URL, which + enables you to include it in web pages as if it were an external + resource + \li \inlineimage icons/original-size.png + - Return images to their original size + \li \inlineimage icons/zoom-in.png + - Zoom in and out (\inlineimage icons/zoom-out.png + ) + \li \inlineimage icons/run_small.png + - Play and pause animated GIF and MNG images + \li \inlineimage icons/qtcreator-desktopdevice-button.png + - Show and hide the image background + \li \inlineimage icons/switch-outline.png + - Show and hide the image outline + \li \inlineimage icons/fittoview.png + - Fit images to screen \endlist Select \uicontrol {Set as Default} to use the current settings for the diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-effects.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-effects.qdoc index a7a91ee8ee1..158932dff8a 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-effects.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-effects.qdoc @@ -11,8 +11,8 @@ \QDS provides a set of 3D effects, which are visible in the \l {2D} view. To apply a visual effect to a scene, drag-and-drop an effect from \uicontrol Components > \uicontrol {Qt Quick 3D} > - \uicontrol {Qt Quick 3D Effects} to a \uicontrol View3D component in - \l Navigator. + \uicontrol {Qt Quick 3D Effects} to a \uicontrol SceneEnvironment component + in \l Navigator. You can use the \l Effect component available in \uicontrol Components > \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D} as the base diff --git a/scripts/generateClangFormatChecksUI.py b/scripts/generateClangFormatChecksUI.py index 5f9f32fe754..a0a9f37e1ac 100755 --- a/scripts/generateClangFormatChecksUI.py +++ b/scripts/generateClangFormatChecksUI.py @@ -141,6 +141,10 @@ def create_checks(variables, enums, structs, offset = ""): checks += combobox_ui("BasedOnStyle", ["LLVM", "Google", "Chromium", "Mozilla", "WebKit", "Microsoft", "GNU"], create_checks_index) for variable in variables: + if "doxygen" in variable.keys(): + if ("**deprecated**" in variable['doxygen']): + continue; + create_checks_index += 1 type = variable["type"] name = variable["name"] diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index f60f4f150b1..e6b978095dc 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0 import QtQuick 2.15 -import QtQuick.Layouts 1.15 import QtQuickDesignerTheme 1.0 import HelperWidgets 2.0 import StudioControls 1.0 as StudioControls @@ -14,12 +13,7 @@ Item { readonly property int cellWidth: 100 readonly property int cellHeight: 120 - property var currentMaterial: null - property int currentMaterialIdx: 0 - property var currentBundleMaterial: null - property int copiedMaterialInternalId: -1 - - property var matSectionsModel: [] + property var currMaterialItem: null // Called also from C++ to close context menu on focus out function closeContextMenu() @@ -54,10 +48,9 @@ Item { var userMatsSecBottom = mapFromItem(userMaterialsSection, 0, userMaterialsSection.y).y + userMaterialsSection.height; - if (!materialBrowserModel.hasMaterialRoot && (!materialBrowserBundleModel.matBundleExists - || mouse.y < userMatsSecBottom)) { - root.currentMaterial = null - ctxMenu.popup() + if (!materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport + && (!materialBrowserBundleModel.matBundleExists || mouse.y < userMatsSecBottom)) { + ctxMenu.popupMenu() } } } @@ -67,11 +60,23 @@ Item { function onSelectedIndexChanged() { // commit rename upon changing selection - var item = gridRepeater.itemAt(currentMaterialIdx); - if (item) - item.commitRename(); + if (root.currMaterialItem) + root.currMaterialItem.commitRename(); - currentMaterialIdx = materialBrowserModel.selectedIndex; + root.currMaterialItem = gridRepeater.itemAt(materialBrowserModel.selectedIndex); + } + } + + MaterialBrowserContextMenu { + id: ctxMenu + } + + MaterialBundleContextMenu { + id: ctxMenuBundle + + onUnimport: (bundleMat) => { + unimportBundleMaterialDialog.targetBundleMaterial = bundleMat + unimportBundleMaterialDialog.open() } } @@ -79,152 +84,6 @@ Item { id: unimportBundleMaterialDialog } - StudioControls.Menu { - id: ctxMenu - - closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside - - StudioControls.MenuItem { - text: qsTr("Apply to selected (replace)") - enabled: root.currentMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, false) - } - - StudioControls.MenuItem { - text: qsTr("Apply to selected (add)") - enabled: root.currentMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, true) - } - - StudioControls.MenuSeparator { - height: StudioTheme.Values.border - } - - StudioControls.Menu { - title: qsTr("Copy properties") - enabled: root.currentMaterial - - width: parent.width - - onAboutToShow: { - if (root.currentMaterial.hasDynamicProperties) - root.matSectionsModel = ["All", "Custom"]; - else - root.matSectionsModel = ["All"]; - - switch (root.currentMaterial.materialType) { - case "DefaultMaterial": - root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.defaultMaterialSections); - break; - - case "PrincipledMaterial": - root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.principledMaterialSections); - break; - - case "CustomMaterial": - root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.customMaterialSections); - break; - } - } - - Repeater { - model: root.matSectionsModel - - StudioControls.MenuItem { - text: modelData - enabled: root.currentMaterial - onTriggered: { - root.copiedMaterialInternalId = root.currentMaterial.materialInternalId - materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData) - } - } - } - } - - StudioControls.MenuItem { - text: qsTr("Paste properties") - enabled: root.currentMaterial - && root.copiedMaterialInternalId !== root.currentMaterial.materialInternalId - && root.currentMaterial.materialType === materialBrowserModel.copiedMaterialType - && materialBrowserModel.isCopiedMaterialValid() - onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx) - } - - StudioControls.MenuSeparator { - height: StudioTheme.Values.border - } - - StudioControls.MenuItem { - text: qsTr("Duplicate") - enabled: root.currentMaterial - onTriggered: materialBrowserModel.duplicateMaterial(root.currentMaterialIdx) - } - - StudioControls.MenuItem { - text: qsTr("Rename") - enabled: root.currentMaterial - onTriggered: { - var item = gridRepeater.itemAt(root.currentMaterialIdx); - if (item) - item.startRename(); - } - } - - StudioControls.MenuItem { - text: qsTr("Delete") - enabled: root.currentMaterial - - onTriggered: materialBrowserModel.deleteMaterial(root.currentMaterialIdx) - } - - StudioControls.MenuSeparator {} - - StudioControls.MenuItem { - text: qsTr("Create New Material") - - onTriggered: materialBrowserModel.addNewMaterial() - } - } - - StudioControls.Menu { - id: ctxMenuBundle - - closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside - - StudioControls.MenuItem { - text: qsTr("Apply to selected (replace)") - enabled: root.currentBundleMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserBundleModel.applyToSelected(root.currentBundleMaterial, false) - } - - StudioControls.MenuItem { - text: qsTr("Apply to selected (add)") - enabled: root.currentBundleMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserBundleModel.applyToSelected(root.currentBundleMaterial, true) - } - - StudioControls.MenuSeparator {} - - StudioControls.MenuItem { - enabled: !materialBrowserBundleModel.importerRunning - text: qsTr("Add an instance to project") - - onTriggered: { - materialBrowserBundleModel.addToProject(root.currentBundleMaterial) - } - } - - StudioControls.MenuItem { - enabled: !materialBrowserBundleModel.importerRunning && root.currentBundleMaterial.bundleMaterialImported - text: qsTr("Remove from project") - - onTriggered: { - unimportBundleMaterialDialog.targetBundleMaterial = root.currentBundleMaterial - unimportBundleMaterialDialog.open() - } - } - } - Column { id: col y: 5 @@ -266,6 +125,7 @@ Item { anchors.verticalCenter: parent.verticalCenter buttonSize: searchBox.height onClicked: materialBrowserModel.addNewMaterial() + enabled: materialBrowserModel.hasQuick3DImport } } @@ -305,6 +165,21 @@ Item { width: root.width caption: qsTr("Materials") hideHeader: !materialBrowserBundleModel.matBundleExists + dropEnabled: true + + onDropEnter: (drag) => { + drag.accepted = rootView.draggedBundleMaterial + userMaterialsSection.highlight = rootView.draggedBundleMaterial + } + + onDropExit: { + userMaterialsSection.highlight = false + } + + onDrop: { + userMaterialsSection.highlight = false + materialBrowserBundleModel.addToProject(rootView.draggedBundleMaterial) + } Grid { id: grid @@ -324,8 +199,7 @@ Item { height: root.cellHeight onShowContextMenu: { - root.currentMaterial = model - ctxMenu.popup() + ctxMenu.popupMenu(this, model) } } } @@ -387,8 +261,7 @@ Item { height: root.cellHeight onShowContextMenu: { - root.currentBundleMaterial = modelData - ctxMenuBundle.popup() + ctxMenuBundle.popupMenu(modelData) } } } diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml new file mode 100644 index 00000000000..d1e9f1ab1f4 --- /dev/null +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +StudioControls.Menu { + id: root + + property var targetMaterial: null + property var targetItem: null + property int copiedMaterialInternalId: -1 + property var matSectionsModel: [] + + function popupMenu(targetItem = null, targetMaterial = null) + { + this.targetItem = targetItem + this.targetMaterial = targetMaterial + popup() + } + + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside + + StudioControls.MenuItem { + text: qsTr("Apply to selected (replace)") + enabled: root.targetMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserModel.applyToSelected(root.targetMaterial.materialInternalId, false) + } + + StudioControls.MenuItem { + text: qsTr("Apply to selected (add)") + enabled: root.targetMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserModel.applyToSelected(root.targetMaterial.materialInternalId, true) + } + + StudioControls.MenuSeparator {} + + StudioControls.Menu { + title: qsTr("Copy properties") + enabled: root.targetMaterial + + width: parent.width + + onAboutToShow: { + if (root.targetMaterial.hasDynamicProperties) + root.matSectionsModel = ["All", "Custom"]; + else + root.matSectionsModel = ["All"]; + + switch (root.targetMaterial.materialType) { + case "DefaultMaterial": + root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.defaultMaterialSections); + break; + + case "PrincipledMaterial": + root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.principledMaterialSections); + break; + + case "CustomMaterial": + root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.customMaterialSections); + break; + } + } + + Repeater { + model: root.matSectionsModel + + StudioControls.MenuItem { + text: modelData + enabled: root.targetMaterial + onTriggered: { + root.copiedMaterialInternalId = root.targetMaterial.materialInternalId + materialBrowserModel.copyMaterialProperties(materialBrowserModel.selectedIndex, modelData) + } + } + } + } + + StudioControls.MenuItem { + text: qsTr("Paste properties") + enabled: root.targetMaterial + && root.copiedMaterialInternalId !== root.targetMaterial.materialInternalId + && root.targetMaterial.materialType === materialBrowserModel.copiedMaterialType + && materialBrowserModel.isCopiedMaterialValid() + onTriggered: materialBrowserModel.pasteMaterialProperties(materialBrowserModel.selectedIndex) + } + + StudioControls.MenuSeparator {} + + StudioControls.MenuItem { + text: qsTr("Duplicate") + enabled: root.targetMaterial + onTriggered: materialBrowserModel.duplicateMaterial(materialBrowserModel.selectedIndex) + } + + StudioControls.MenuItem { + text: qsTr("Rename") + enabled: root.targetItem + onTriggered: root.targetItem.startRename(); + } + + StudioControls.MenuItem { + text: qsTr("Delete") + enabled: root.targetMaterial + + onTriggered: materialBrowserModel.deleteMaterial(materialBrowserModel.selectedIndex) + } + + StudioControls.MenuSeparator {} + + StudioControls.MenuItem { + text: qsTr("Create New Material") + + onTriggered: materialBrowserModel.addNewMaterial() + } +} diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml new file mode 100644 index 00000000000..eb698d69932 --- /dev/null +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBundleContextMenu.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.15 +import HelperWidgets 2.0 +import StudioControls 1.0 as StudioControls +import StudioTheme 1.0 as StudioTheme + +StudioControls.Menu { + id: root + + property var targetMaterial: null + signal unimport(var bundleMat); + + function popupMenu(targetMaterial = null) + { + this.targetMaterial = targetMaterial + popup() + } + + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside + + StudioControls.MenuItem { + text: qsTr("Apply to selected (replace)") + enabled: root.targetMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserBundleModel.applyToSelected(root.targetMaterial, false) + } + + StudioControls.MenuItem { + text: qsTr("Apply to selected (add)") + enabled: root.targetMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserBundleModel.applyToSelected(root.targetMaterial, true) + } + + StudioControls.MenuSeparator {} + + StudioControls.MenuItem { + enabled: !materialBrowserBundleModel.importerRunning + text: qsTr("Add an instance to project") + + onTriggered: { + materialBrowserBundleModel.addToProject(root.targetMaterial) + } + } + + StudioControls.MenuItem { + enabled: !materialBrowserBundleModel.importerRunning && root.targetMaterial.bundleMaterialImported + text: qsTr("Remove from project") + + onTriggered: root.unimport(root.targetMaterial); + } +} diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index 540f70b4857..21385de257e 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -253,6 +253,10 @@ Rectangle { property bool tinyMode: Constants.thumbnailSize <= Constants.thumbnailBreak property int currentStateInternalId: 0 + // Using an int instead of a bool, because when opening a menu on one state and without closing + // opening a menu on another state will first trigger the open of the new popup and afterwards + // the close of the old popup. Using an int keeps track of number of opened popups. + property int menuOpen: 0 // This timer is used to delay the current state animation as it didn't work due to the // repeaters item not being positioned in time resulting in 0 x and y position if the grids @@ -655,7 +659,7 @@ Rectangle { required property var extendString function setPropertyChangesVisible(value) { - stateThumbnail.propertyChangesVisible = value + stateThumbnail.setPropertyChangesVisible(value) } width: Constants.thumbnailSize @@ -797,10 +801,18 @@ Rectangle { hasWhenCondition: delegateRoot.hasWhenCondition - scrollViewActive: horizontalBar.active || verticalBar.active + blockDragHandler: horizontalBar.active || verticalBar.active + || root.menuOpen dragParent: scrollView + onMenuOpenChanged: { + if (stateThumbnail.menuOpen) + root.menuOpen++ + else + root.menuOpen-- + } + // Fix ScrollView taking over the dragging event onGrabbing: { frame.interactive = false diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index ce95aa21983..6d4a84e44c7 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml @@ -46,7 +46,7 @@ Item { property alias menuChecked: menuButton.checked property bool baseState: false property bool isTiny: false - property bool propertyChangesVisible: false + property bool propertyChangesVisible: propertyChangesModel.propertyChangesVisible property bool isChecked: false property bool hasExtend: false @@ -55,7 +55,8 @@ Item { property bool hasWhenCondition: false - property bool scrollViewActive: false + property bool menuOpen: stateMenu.opened + property bool blockDragHandler: false property Item dragParent @@ -79,6 +80,11 @@ Item { return statesEditorModel.hasAnnotation(root.internalNodeId) } + function setPropertyChangesVisible(value) { + root.propertyChangesVisible = value + propertyChangesModel.setPropertyChangesVisible(value) + } + onIsTinyChanged: { if (root.isTiny) { buttonGrid.rows = 2 @@ -91,7 +97,7 @@ Item { DragHandler { id: dragHandler - enabled: !root.baseState && !root.extendedState && !root.scrollViewActive + enabled: !root.baseState && !root.extendedState && !root.blockDragHandler onGrabChanged: function (transition, point) { if (transition === PointerDevice.GrabPassive || transition === PointerDevice.GrabExclusive) @@ -314,6 +320,9 @@ Item { Column { id: column + property bool hoverEnabled: false + onPositioningComplete: column.hoverEnabled = true + // Grid sizes property int gridSpacing: 20 property int gridRowSpacing: 5 @@ -353,7 +362,7 @@ Item { Item { id: section property int animationDuration: 120 - property bool expanded: false + property bool expanded: propertyModel.expanded clip: true width: stateBackground.innerWidth @@ -415,6 +424,7 @@ Item { anchors.fill: parent onClicked: { section.expanded = !section.expanded + propertyModel.setExpanded(section.expanded) if (!section.expanded) section.forceActiveFocus() root.focusSignal() @@ -518,6 +528,8 @@ Item { Repeater { model: propertyModel + onModelChanged: column.hoverEnabled = false + delegate: ItemDelegate { id: propertyDelegate @@ -527,7 +539,7 @@ Item { width: stateBackground.innerWidth - 2 * column.gridPadding height: 26 - hoverEnabled: true + hoverEnabled: column.hoverEnabled onClicked: root.focusSignal() @@ -560,7 +572,7 @@ Item { MouseArea { id: propertyDelegateMouseArea anchors.fill: parent - hoverEnabled: true + hoverEnabled: column.hoverEnabled onClicked: { root.focusSignal() propertyModel.removeProperty( @@ -717,7 +729,7 @@ Item { onClone: root.clone() onExtend: root.extend() onRemove: root.remove() - onToggle: root.propertyChangesVisible = !root.propertyChangesVisible + onToggle: root.setPropertyChangesVisible(!root.propertyChangesVisible) onResetWhenCondition: statesEditorModel.resetWhenCondition(root.internalNodeId) onEditAnnotation: { statesEditorModel.setAnnotation(root.internalNodeId) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml index 585672db47d..e0fdb8ef7b3 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml @@ -19,7 +19,7 @@ Rectangle { anchors.fill: parent Controls.Label { - text: qsTr("Select a component in Form Editor, Navigator, or Text Editor to see its properties.") + text: qsTr("Select a component in the 2D, Navigator, or Code view to see its properties.") font.pixelSize: StudioTheme.Values.myFontSize * 1.5 color: StudioTheme.Values.themeTextColor wrapMode: Text.WordWrap diff --git a/share/qtcreator/translations/qtcreator_cs.ts b/share/qtcreator/translations/qtcreator_cs.ts index 710b67ccb34..7d7350c717c 100644 --- a/share/qtcreator/translations/qtcreator_cs.ts +++ b/share/qtcreator/translations/qtcreator_cs.ts @@ -14817,7 +14817,7 @@ Zdá se, že následující kódování odpovídají souboru: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Písmo @@ -17906,7 +17906,7 @@ Toho se dosáhne vložením této zkratky v zadávacím poli vyhledávače, nás Shellové příkazy nejsou jako terminálové příkazy přípustné. - Cannot start the terminal emulator '%1', change the setting in the Environment options. + Cannot start the terminal emulator '%1', change the setting in the Environment preferences. Emulátor terminálu '%1' se nepodařilo spustit. Změňte hodnotu v nastavení prostředí. @@ -35698,16 +35698,16 @@ Chcete přesto soubor s nastavením nahrát? Základní stav - Invalid state name - Neplatný název stavu + Invalid state name. + Neplatný název stavu. The empty string as a name is reserved for the base state. Prázdný řetězec znaků je vyhrazen jako název základního stavu. - Name already used in another state - Název je již používán jiným stavem + Name already used in another state. + Název je již používán jiným stavem. @@ -44722,7 +44722,7 @@ Tyto předpony se používají dodatečně k nynějšímu názvu souboru na Pře - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Při psaní @@ -44838,7 +44838,7 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. Kódování souborů - Default encoding: + Default encoding: Výchozí kódování: @@ -44970,7 +44970,7 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Zobrazení @@ -45113,7 +45113,7 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form Formulář diff --git a/share/qtcreator/translations/qtcreator_da.ts b/share/qtcreator/translations/qtcreator_da.ts index 4532a3a74dd..f7a3c22c3af 100644 --- a/share/qtcreator/translations/qtcreator_da.ts +++ b/share/qtcreator/translations/qtcreator_da.ts @@ -30154,16 +30154,16 @@ Dette er uafhængigt af visibility-egenskaben i QML. grundlæggende tilstand - Invalid state name - Ugyldig tilstandsnavn + Invalid state name. + Ugyldig tilstandsnavn. The empty string as a name is reserved for the base state. Den tomme streng som et navn er reserveret til den grundlæggende tilstand. - Name already used in another state - Navn allerede brugt i anden tilstand + Name already used in another state. + Navn allerede brugt i anden tilstand. @@ -31402,8 +31402,8 @@ Se "Checking Code Syntax"-dokumentation for mere information.Qt Quick - The type will only be available in the QML editors when the type name is a string literal - Typen er kun tilgængelig i QML-redigeringerne når typenavnet er en streng-literal + The type will only be available in the QML editors when the type name is a string literal. + Typen er kun tilgængelig i QML-redigeringerne når typenavnet er en streng-literal. The module URI cannot be determined by static analysis. The type will be available @@ -35813,7 +35813,7 @@ Ekskludering: %3 - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Skrivning @@ -35929,7 +35929,7 @@ Angiver hvordan backspace interagerer med indrykning. Filkodninger - Default encoding: + Default encoding: Standard kodning: @@ -36336,7 +36336,7 @@ Derudover indsætter Skift+Enter et undvigetegn ved markørens placering og flyt - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Text Wrapping Tekstombrydning @@ -36469,7 +36469,7 @@ Derudover indsætter Skift+Enter et undvigetegn ved markørens placering og flyt - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Skrifttype @@ -36728,7 +36728,7 @@ Derudover indsætter Skift+Enter et undvigetegn ved markørens placering og flyt - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Tabs And Indentation Tabulatorer og indrykning @@ -38429,7 +38429,7 @@ Vil blive anvendt på blanktegn i kommentarer og strenge. Terminal-kommando må ikke være en skalkommando. - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. Kan ikke starte terminalemulatoren "%1", skifte indstillingen i Miljø-valgmulighederne. diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 5f624cbfe13..20361352665 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -7934,7 +7934,7 @@ Rename %2 to %3 anyway? - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Zeichensatz @@ -8099,7 +8099,7 @@ Rename %2 to %3 anyway? Shell-Kommandos sind als Terminal-Kommando nicht zulässig. - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. Der Terminal-Emulator "%1" konnte nicht gestartet werden, ändern Sie den Wert in den Einstellungen zur Umgebung. @@ -12868,16 +12868,16 @@ Soll es noch einmal versucht werden? Grundzustand - Invalid state name - Ungültiger Name des Zustands + Invalid state name. + Ungültiger Name des Zustands. The empty string as a name is reserved for the base state. Eine leere Zeichenkette ist als Name des Basiszustands reserviert. - Name already used in another state - Der Name wird bereits von einem anderen Zustand verwendet + Name already used in another state. + Der Name wird bereits von einem anderen Zustand verwendet. @@ -17346,7 +17346,7 @@ Diese Präfixe werden zusätzlich zum Dateinamen beim Wechseln zwischen Header- - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Beim Tippen @@ -17590,7 +17590,7 @@ Gibt an, wie sich die Rücktaste bezüglich Einrückung verhält. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Anzeige @@ -17783,7 +17783,7 @@ Gibt an, wie sich die Rücktaste bezüglich Einrückung verhält. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Tabs And Indentation Tabulatoren und Einrückung @@ -19756,8 +19756,8 @@ gehören nicht zu den verifizierten Remotes in %3. Anderes Verzeichnis angeben?< QmlJSTools - The type will only be available in the QML editors when the type name is a string literal - Dieser Typ wird im QML Editor nur sichtbar sein, wenn der Typname ein Zeichenketten-Literal ist + The type will only be available in the QML editors when the type name is a string literal. + Dieser Typ wird im QML Editor nur sichtbar sein, wenn der Typname ein Zeichenketten-Literal ist. The module URI cannot be determined by static analysis. The type will be available diff --git a/share/qtcreator/translations/qtcreator_es.ts b/share/qtcreator/translations/qtcreator_es.ts index ca2522fe184..a8d449f2911 100644 --- a/share/qtcreator/translations/qtcreator_es.ts +++ b/share/qtcreator/translations/qtcreator_es.ts @@ -10412,7 +10412,7 @@ The following encodings are likely to fit: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Fuente diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts index 175dd0dbbfa..83b3484f531 100644 --- a/share/qtcreator/translations/qtcreator_fr.ts +++ b/share/qtcreator/translations/qtcreator_fr.ts @@ -2387,7 +2387,7 @@ Voulez vous les écraser ? La commande terminal peut ne pas être une commande shell. - Cannot start the terminal emulator '%1', change the setting in the Environment options. + Cannot start the terminal emulator '%1', change the setting in the Environment preferences. Impossible de démarrer l'émulateur de terminal "%1", modifiez les paramètres dans les options d'environnement. @@ -16077,7 +16077,7 @@ Les encodages suivants pourraient convenir : - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Police @@ -35326,16 +35326,16 @@ Do you want to retry? état de base - Invalid state name - Nom d'état invalide + Invalid state name. + Nom d'état invalide. The empty string as a name is reserved for the base state. La chaîne vide comme nom est réservée à l'état de base. - Name already used in another state - Le nom est déjà utilisé dans un autre état + Name already used in another state. + Le nom est déjà utilisé dans un autre état. @@ -43377,7 +43377,7 @@ Ces chemines sont utilisés en complément au répertoire courant pour basculer - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Frappe @@ -43493,7 +43493,7 @@ Specifie comment retour arrière se comporte avec l'indentation. Encodages de fichier - Default encoding: + Default encoding: Encodage par défaut : @@ -43605,7 +43605,7 @@ Specifie comment retour arrière se comporte avec l'indentation. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Affichage @@ -43744,7 +43744,7 @@ Specifie comment retour arrière se comporte avec l'indentation. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form Formulaire diff --git a/share/qtcreator/translations/qtcreator_hr.ts b/share/qtcreator/translations/qtcreator_hr.ts index 3f7108c4c98..afbd4338121 100644 --- a/share/qtcreator/translations/qtcreator_hr.ts +++ b/share/qtcreator/translations/qtcreator_hr.ts @@ -8056,7 +8056,7 @@ Sigurno želiš nastaviti? - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Tipkanje @@ -8172,7 +8172,7 @@ Specificira način uvlačenja s povratnom tipkom. Kodiranje datoteke - Default encoding: + Default encoding: Standardno kodiranje: @@ -8522,7 +8522,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Text Wrapping Prelamanje teksta @@ -8621,7 +8621,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Font @@ -8718,7 +8718,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Tabs And Indentation Tabulatori i uvlake diff --git a/share/qtcreator/translations/qtcreator_hu.ts b/share/qtcreator/translations/qtcreator_hu.ts index f7c0857fc8c..6ee12b8647c 100644 --- a/share/qtcreator/translations/qtcreator_hu.ts +++ b/share/qtcreator/translations/qtcreator_hu.ts @@ -17194,7 +17194,7 @@ A következő kódolás valószínűleg erre illik: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Betű diff --git a/share/qtcreator/translations/qtcreator_it.ts b/share/qtcreator/translations/qtcreator_it.ts index bbbd0173674..88cfe0fe328 100644 --- a/share/qtcreator/translations/qtcreator_it.ts +++ b/share/qtcreator/translations/qtcreator_it.ts @@ -10310,7 +10310,7 @@ Queste codifiche dovrebbero andare bene: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Tipo di carattere diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 5d84dd74efe..008cfcade68 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -6107,7 +6107,7 @@ Add, modify, and remove document filters, which determine the documentation set - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing タイピング @@ -6211,7 +6211,7 @@ Backspace キーが押された時のインデントの動作を指定します ファイルの文字コード - Default encoding: + Default encoding: 既定の文字コード: @@ -6470,7 +6470,7 @@ Backspace キーが押された時のインデントの動作を指定します - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Text Wrapping 行の折り返し @@ -6585,7 +6585,7 @@ Backspace キーが押された時のインデントの動作を指定します - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font フォント @@ -6795,7 +6795,7 @@ Backspace キーが押された時のインデントの動作を指定します - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form フォーム @@ -10742,7 +10742,7 @@ with a password, which you can enter below. ターミナルコマンドがシェルコマンドではない可能性があります。 - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. ターミナルエミュレータ "%1" が起動できません。環境オプションの設定を変更してください。 @@ -14492,7 +14492,7 @@ Note: This might remove the local file. 以下のファイルをバージョン管理システム (%2) から削除しますか? %1注: これにより、ローカル・ファイルが削除される場合があります。 - Remove the following files from the version control system (%2)?%1Note: This might remove the local file. + Remove the following files from the version control system (%2)? %1Note: This might remove the local file. 以下のファイルをバージョン管理システム (%2) から削除しますか? %1注: これにより、ローカルファイルが削除される場合があります。 @@ -28364,16 +28364,16 @@ Locked items cannot be modified or selected. 初期状態 - Invalid state name - 無効な状態名 + Invalid state name. + 無効な状態名。 The empty string as a name is reserved for the base state. 空文字は初期状態用に予約された名前です。 - Name already used in another state - 名前が他の状態名と重複しています + Name already used in another state. + 名前が他の状態名と重複しています。 @@ -28867,8 +28867,8 @@ Qt Creator know about a likely URI. "// @uri My.Module.Uri" を記述することによって Qt Creator に URI を通知できます。 - The type will only be available in the QML editors when the type name is a string literal - この型は型名が文字列リテラルであるため、QML エディタでのみ利用可能できます + The type will only be available in the QML editors when the type name is a string literal. + この型は型名が文字列リテラルであるため、QML エディタでのみ利用可能できます。 The module URI cannot be determined by static analysis. The type will be available diff --git a/share/qtcreator/translations/qtcreator_pl.ts b/share/qtcreator/translations/qtcreator_pl.ts index 611cdb586c5..fbf2d98a81c 100644 --- a/share/qtcreator/translations/qtcreator_pl.ts +++ b/share/qtcreator/translations/qtcreator_pl.ts @@ -1330,7 +1330,7 @@ - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Czcionka @@ -1785,7 +1785,7 @@ Przyczyna: %3 Komenda terminala nie musi być komendą powłoki. - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. Nie można uruchomić emulatora terminala "%1", zmień ustawienie w opcjach środowiska. @@ -15860,16 +15860,16 @@ Ponowić próbę? Stan bazowy - Invalid state name - Niepoprawna nazwa stanu + Invalid state name. + Niepoprawna nazwa stanu. The empty string as a name is reserved for the base state. Pusta nazwa jest zarezerwowana dla stanu bazowego. - Name already used in another state - Nazwa jest już użyta w innym stanie + Name already used in another state. + Nazwa jest już użyta w innym stanie. @@ -19865,7 +19865,7 @@ Przedrostki te, w dodatku do nazwy bieżącego pliku, używane są do przełącz - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Pisanie @@ -19969,7 +19969,7 @@ Ustala, jak klawisz "Backspace" reaguje na wcięcia. Kodowania plików - Default encoding: + Default encoding: Domyślne kodowanie: @@ -20098,7 +20098,7 @@ Ustala, jak klawisz "Backspace" reaguje na wcięcia. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Wyświetlanie @@ -20257,7 +20257,7 @@ Ustala, jak klawisz "Backspace" reaguje na wcięcia. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form Formularz diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 5bdbc409b9f..be765e3ed3d 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -27671,7 +27671,7 @@ You might find further explanations in the Application Output view. Задержка обработки: %1.%2 сек - Invalid data format. The trace file's identification string is "%1".An acceptable trace file should have "%2". You cannot read trace files generated with older versions of Qt Creator. + Invalid data format. The trace file's identification string is "%1". An acceptable trace file should have "%2". You cannot read trace files generated with older versions of Qt Creator. Неверный формат данных. У файла трассировки задана строка идентификации «%1». А допустимой является «%2». Нельзя читать файлы трассировки, созданные старыми версиями Qt Creator. @@ -38820,16 +38820,16 @@ This is independent of the visibility property in QML. исходное состояние - Invalid state name - Неверное название состояния + Invalid state name. + Неверное название состояния. The empty string as a name is reserved for the base state. Пустая строка зарезервирована как название исходного состояния. - Name already used in another state - Название уже используется другим состоянием + Name already used in another state. + Название уже используется другим состоянием. @@ -40620,8 +40620,8 @@ For more information, see the "Checking Code Syntax" documentation. - The type will only be available in the QML editors when the type name is a string literal - Имя типа должно быть строковым литералом, чтобы он был доступен в редакторах QML + The type will only be available in the QML editors when the type name is a string literal. + Имя типа должно быть строковым литералом, чтобы он был доступен в редакторах QML. The module URI cannot be determined by static analysis. The type will be available @@ -45813,7 +45813,7 @@ Excluding: %3 - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Набор текста @@ -45917,7 +45917,7 @@ Specifies how backspace interacts with indentation. Кодировки файлов - Default encoding: + Default encoding: По умолчанию: @@ -46345,7 +46345,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Отображение @@ -46478,7 +46478,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Шрифт @@ -46775,7 +46775,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Tabs And Indentation Табуляция и отступы @@ -48680,7 +48680,7 @@ in "%2". Терминальная команда, возможно, не является командой оболочки. - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. Не удалось запустить эмулятор терминала «%1», смените настройки в параметрах среды. diff --git a/share/qtcreator/translations/qtcreator_sl.ts b/share/qtcreator/translations/qtcreator_sl.ts index 7f4ef186521..7e0d280feef 100644 --- a/share/qtcreator/translations/qtcreator_sl.ts +++ b/share/qtcreator/translations/qtcreator_sl.ts @@ -9899,7 +9899,7 @@ Naslednji nabori znakov so verjetno ustrezni: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Pisava @@ -20732,7 +20732,7 @@ Potreben je Qt 4.7.4 ali novejši in nabor komponent za vašo različico Qt. - Default encoding: + Default encoding: Privzeto kodiranje: @@ -25066,16 +25066,16 @@ Ali še vedno želite naložiti nastavitveno datoteko? osnovno stanje - Invalid state name - Neveljavno ime stanja + Invalid state name. + Neveljavno ime stanja. The empty string as a name is reserved for the base state. Prazen niz za ime je rezervirano za osnovno stanje. - Name already used in another state - Ime je že uporabljeno v drugem stanju + Name already used in another state. + Ime je že uporabljeno v drugem stanju. diff --git a/share/qtcreator/translations/qtcreator_uk.ts b/share/qtcreator/translations/qtcreator_uk.ts index 7ae1def1d11..52f6f4e26c8 100644 --- a/share/qtcreator/translations/qtcreator_uk.ts +++ b/share/qtcreator/translations/qtcreator_uk.ts @@ -21506,7 +21506,7 @@ The following encodings are likely to fit: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Font Шрифт @@ -22905,7 +22905,7 @@ Will not be applied to whitespace in comments and strings. Термінальна команда, можливо, не є командою оболонки. - Cannot start the terminal emulator "%1", change the setting in the Environment options. + Cannot start the terminal emulator "%1", change the setting in the Environment preferences. Неможливо запустити емулятор терміналу "%1", змініть налаштування в опціях середовища. @@ -25121,7 +25121,7 @@ These prefixes are used in addition to current file name on Switch Header/Source - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing Набір тексту @@ -25237,7 +25237,7 @@ Specifies how backspace interacts with indentation. Кодування файлу - Default encoding: + Default encoding: Типове кодування: @@ -25378,7 +25378,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display Відображення @@ -25521,7 +25521,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form Форма diff --git a/share/qtcreator/translations/qtcreator_zh_CN.ts b/share/qtcreator/translations/qtcreator_zh_CN.ts index 551984479a6..4393ae95118 100644 --- a/share/qtcreator/translations/qtcreator_zh_CN.ts +++ b/share/qtcreator/translations/qtcreator_zh_CN.ts @@ -15138,7 +15138,7 @@ The following encodings are likely to fit: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Family: 字型: @@ -33406,16 +33406,16 @@ Do you want to retry? 基线状态 - Invalid state name - 无效状态名称 + Invalid state name. + 无效状态名称。 The empty string as a name is reserved for the base state. 空字符串是为基线状态保留的名称。 - Name already used in another state - 名称已经被另一个状态使用 + Name already used in another state. + 名称已经被另一个状态使用。 @@ -42255,7 +42255,7 @@ p, li { white-space: pre-wrap; } - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing 打字 @@ -42371,7 +42371,7 @@ Specifies how backspace interacts with indentation. 文件编码 - Default encoding: + Default encoding: 默认编码: @@ -42475,7 +42475,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Text Wrapping 文字折行 @@ -42602,7 +42602,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form 界面 diff --git a/share/qtcreator/translations/qtcreator_zh_TW.ts b/share/qtcreator/translations/qtcreator_zh_TW.ts index 1b0160912b6..0b3293284b6 100644 --- a/share/qtcreator/translations/qtcreator_zh_TW.ts +++ b/share/qtcreator/translations/qtcreator_zh_TW.ts @@ -9136,7 +9136,7 @@ The following encodings are likely to fit: - TextEditor::Internal::FontSettingsPage + TextEditor::FontSettingsPageWidget Family: 家族: @@ -20463,16 +20463,16 @@ Do you want to retry? 基本狀態 - Invalid state name - 無效狀態名稱 + Invalid state name. + 無效狀態名稱。 The empty string as a name is reserved for the base state. 空字串是為基本狀態保留的名稱。 - Name already used in another state - 此名稱已經被其他狀態使用 + Name already used in another state. + 此名稱已經被其他狀態使用。 @@ -26816,7 +26816,7 @@ p, li { white-space: pre-wrap; } - TextEditor::Internal::BehaviorSettingsWidget + TextEditor::BehaviorSettingsWidget Typing 打字 @@ -26932,7 +26932,7 @@ Specifies how backspace interacts with indentation. 檔案編碼 - Default encoding: + Default encoding: 預設編碼: @@ -27036,7 +27036,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::DisplaySettingsPage + TextEditor::DisplaySettingsPage Display 顯示 @@ -27163,7 +27163,7 @@ Specifies how backspace interacts with indentation. - TextEditor::Internal::TabSettingsWidget + TextEditor::TabSettingsWidget Form 表單 diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp index 20a708133d9..2e07d91f22c 100644 --- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp +++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp @@ -251,7 +251,7 @@ protected: _doc->fileName(), line, column, QmlJS::FindExportedCppTypes::tr( - "The type will only be available in the QML editors when the type name is a string literal")); + "The type will only be available in the QML editors when the type name is a string literal.")); return false; } diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp index 62dc52b2605..05c5e05e5ae 100644 --- a/src/libs/utils/environment.cpp +++ b/src/libs/utils/environment.cpp @@ -4,18 +4,18 @@ #include "environment.h" #include "algorithm.h" -#include "fileutils.h" #include "qtcassert.h" #include #include +#include #include namespace Utils { +static QReadWriteLock s_envMutex; Q_GLOBAL_STATIC_WITH_ARGS(Environment, staticSystemEnvironment, (QProcessEnvironment::systemEnvironment().toStringList())) - Q_GLOBAL_STATIC(QVector, environmentProviders) NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepend) const @@ -120,6 +120,7 @@ void Environment::prependOrSetLibrarySearchPaths(const FilePaths &values) Environment Environment::systemEnvironment() { + QReadLocker lock(&s_envMutex); return *staticSystemEnvironment(); } @@ -296,11 +297,13 @@ FilePaths Environment::pathListValue(const QString &varName) const void Environment::modifySystemEnvironment(const EnvironmentItems &list) { + QWriteLocker lock(&s_envMutex); staticSystemEnvironment->modify(list); } void Environment::setSystemEnvironment(const Environment &environment) { + QWriteLocker lock(&s_envMutex); *staticSystemEnvironment = environment; } diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index d52bcdf9d42..55d5ca89a07 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -180,6 +180,11 @@ QString FilePath::encodedHost() const return result; } +QString decodeHost(QString host) +{ + return host.replace("%25", "%").replace("%2f", "/"); +} + /// \returns a QString for passing on to QString based APIs QString FilePath::toString() const { @@ -765,10 +770,10 @@ void FilePath::setFromString(const QString &unnormalizedFileName) const int firstSlash = withoutQtcDeviceRoot.indexOf(slash); if (firstSlash != -1) { - QString scheme = withoutQtcDeviceRoot.left(firstSlash).toString(); + const QString scheme = withoutQtcDeviceRoot.left(firstSlash).toString(); const int secondSlash = withoutQtcDeviceRoot.indexOf(slash, firstSlash + 1); - QString host = withoutQtcDeviceRoot.mid(firstSlash + 1, secondSlash - firstSlash - 1) - .toString(); + const QString host = decodeHost( + withoutQtcDeviceRoot.mid(firstSlash + 1, secondSlash - firstSlash - 1).toString()); if (secondSlash != -1) { QStringView path = withoutQtcDeviceRoot.mid(secondSlash); setParts(scheme, host, path); @@ -787,9 +792,9 @@ void FilePath::setFromString(const QString &unnormalizedFileName) const int schemeEnd = fileName.indexOf(colonSlashSlash); if (schemeEnd != -1 && schemeEnd < firstSlash) { // This is a pseudo Url, we can't use QUrl here sadly. - QString scheme = fileName.left(schemeEnd); + const QString scheme = fileName.left(schemeEnd); const int hostEnd = fileName.indexOf(slash, schemeEnd + 3); - QString host = fileName.mid(schemeEnd + 3, hostEnd - schemeEnd - 3); + const QString host = decodeHost(fileName.mid(schemeEnd + 3, hostEnd - schemeEnd - 3)); setParts(scheme, host, hostEnd != -1 ? QStringView(fileName).mid(hostEnd) : QStringView()); return; } @@ -1259,7 +1264,16 @@ bool FilePath::copyFile(const FilePath &target) const const std::optional ba = fileContents(); if (!ba) return false; - return target.writeFileContents(*ba); + const auto perms = permissions(); + if (!target.writeFileContents(*ba)) + return false; + + if (!target.setPermissions(perms)) { + target.removeFile(); + return false; + } + + return true; } return fileAccess()->copyFile(*this, target); } diff --git a/src/libs/utils/namevaluesdialog.cpp b/src/libs/utils/namevaluesdialog.cpp index 195871e5059..2c9fae7e574 100644 --- a/src/libs/utils/namevaluesdialog.cpp +++ b/src/libs/utils/namevaluesdialog.cpp @@ -74,7 +74,7 @@ NameValuesDialog::NameValuesDialog(const QString &windowTitle, const QString &he auto box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); - box->button(QDialogButtonBox::Ok)->setText(tr("&Ok")); + box->button(QDialogButtonBox::Ok)->setText(tr("&OK")); box->button(QDialogButtonBox::Cancel)->setText(tr("&Cancel")); connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject); diff --git a/src/libs/utils/qtcassert.cpp b/src/libs/utils/qtcassert.cpp index 003311faa28..65e39891f61 100644 --- a/src/libs/utils/qtcassert.cpp +++ b/src/libs/utils/qtcassert.cpp @@ -59,7 +59,7 @@ void dumpBacktrace(int maxdepth) frame.AddrPC.Offset = ctx.Rip; frame.AddrStack.Offset = ctx.Rsp; frame.AddrFrame.Offset = ctx.Rbp; -#elif define(_M_ARM64) +#elif defined(_M_ARM64) frame.AddrPC.Offset = ctx.Pc; frame.AddrStack.Offset = ctx.Sp; frame.AddrFrame.Offset = ctx.Fp; diff --git a/src/libs/utils/removefiledialog.cpp b/src/libs/utils/removefiledialog.cpp index 863b726b0ca..602d5d8c9db 100644 --- a/src/libs/utils/removefiledialog.cpp +++ b/src/libs/utils/removefiledialog.cpp @@ -16,7 +16,8 @@ namespace Utils { RemoveFileDialog::RemoveFileDialog(const FilePath &filePath, QWidget *parent) : QDialog(parent) { - setWindowTitle(tr("Remove File")); + const bool isFile = filePath.isFile(); + setWindowTitle(isFile ? tr("Remove File") : tr("Remove Folder")); resize(514, 159); QFont font; @@ -36,7 +37,7 @@ RemoveFileDialog::RemoveFileDialog(const FilePath &filePath, QWidget *parent) using namespace Layouting; Column { - tr("File to remove:"), + isFile ? tr("File to remove:") : tr("Folder to remove:"), fileNameLabel, Space(10), m_deleteFileCheckBox, diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index 32beff6c35f..575b8562f2e 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -397,7 +397,7 @@ void TerminalImpl::start() d->m_process.start(); if (!d->m_process.waitForStarted()) { const QString msg = QtcProcess::tr("Cannot start the terminal emulator \"%1\", change the " - "setting in the Environment options. (%2)") + "setting in the Environment preferences. (%2)") .arg(terminal.command).arg(d->m_process.errorString()); cleanupAfterStartFailure(msg); return; diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 92953495b5e..0ed3c41f3ed 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -470,10 +470,12 @@ FilePath AndroidConfig::adbToolPath() const FilePath AndroidConfig::emulatorToolPath() const { - QString relativePath = "emulator/emulator"; - if (sdkToolsVersion() < QVersionNumber(25, 3, 0) && preCmdlineSdkToolsInstalled()) - relativePath = "tools/emulator"; - return m_sdkLocation / (relativePath + QTC_HOST_EXE_SUFFIX); + const FilePath emulatorFile = m_sdkLocation.pathAppended("emulator/emulator") + .withExecutableSuffix(); + if (emulatorFile.exists()) + return emulatorFile; + + return m_sdkLocation.pathAppended("tools/emulator").withExecutableSuffix(); } FilePath AndroidConfig::sdkManagerToolPath() const diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 9e5fb9d1e0f..195a3e91104 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -136,7 +136,14 @@ void AndroidDebugSupport::start() setAbi(AndroidManager::androidAbi2Abi(devicePreferredAbi)); if (cppEngineType() == LldbEngineType) { - setRemoteChannel("adb://" + AndroidManager::deviceSerialNumber(target), + QString deviceSerialNumber = AndroidManager::deviceSerialNumber(target); + const int colonPos = deviceSerialNumber.indexOf(QLatin1Char(':')); + if (colonPos > 0) { + // When wireless debugging is used then the device serial number will include a port number + // The port number must be removed to form a valid hostname + deviceSerialNumber.truncate(colonPos); + } + setRemoteChannel("adb://" + deviceSerialNumber, m_runner->debugServerPort().number()); } else { QUrl debugServer; diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 7600c9fd096..c65db2ec181 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -169,7 +169,7 @@ void AndroidDevice::addActionsIfNotFound() static const QString startAvdAction = Tr::tr("Start AVD"); static const QString eraseAvdAction = Tr::tr("Erase AVD"); static const QString avdArgumentsAction = Tr::tr("AVD Arguments"); - static const QString setupWifi = Tr::tr("Setup Wi-Fi"); + static const QString setupWifi = Tr::tr("Set up Wi-Fi"); bool hasStartAction = false; bool hasEraseAction = false; @@ -543,7 +543,7 @@ void AndroidDeviceManager::setupWifiForDevice(const IDevice::Ptr &device, QWidge const SdkToolResult connectRes = AndroidManager::runAdbCommand(args); if (!connectRes.success()) { AndroidDeviceWidget::criticalDialog( - Tr::tr("Connecting to to the device IP \"%1\" failed.").arg(ip), + Tr::tr("Connecting to the device IP \"%1\" failed.").arg(ip), parent); return; } diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 8ff6d34119b..329b91b6318 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -162,6 +162,8 @@ static BaseClientInterface *clientInterface(Project *project, const Utils::FileP cmd.addArg("--background-index-priority=" + ClangdSettings::priorityToString(indexingPriority)); } + if (settings.clangdVersion() >= QVersionNumber(16)) + cmd.addArg("--rename-file-limit=0"); if (!jsonDbDir.isEmpty()) cmd.addArg("--compile-commands-dir=" + jsonDbDir.toString()); if (clangdLogServer().isDebugEnabled()) @@ -470,13 +472,13 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor, if (searchTerm.isEmpty()) return; - // TODO: Fix hard file limit in clangd, then uncomment this with version check. - // Will fix QTCREATORBUG-27978 and QTCREATORBUG-28109. - // if (replacement) { - // symbolSupport().renameSymbol(document, adjustedCursor, *replacement, - // CppEditor::preferLowerCaseFileNames()); - // return; - // } + // Will fix QTCREATORBUG-27978 and QTCREATORBUG-28109 once enabled by default. + if (replacement && versionNumber() >= QVersionNumber(16) + && Utils::qtcEnvironmentVariableIsSet("QTC_CLANGD_RENAMING")) { + symbolSupport().renameSymbol(document, adjustedCursor, *replacement, + CppEditor::preferLowerCaseFileNames()); + return; + } const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences(); diff --git a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp index 6714c91b04a..fbddb0b605a 100644 --- a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp +++ b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp @@ -289,10 +289,9 @@ void doSemanticHighlighting( } } else if (token.type == "class") { styles.mainStyle = C_TYPE; - - // clang hardly ever differentiates between constructors and the associated class, - // whereas we highlight constructors as functions. - if (ast.isValid()) { + if (token.modifiers.contains("constructorOrDestructor")) { + styles.mainStyle = C_FUNCTION; + } else if (ver < 16 && ast.isValid()) { const ClangdAstPath path = getAstPath(ast, tokenRange(token)); if (!path.isEmpty()) { if (path.last().kind() == "CXXConstructor") { diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 4efe2e69f4f..a99dea83db7 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -271,7 +271,7 @@ QJsonArray clangOptionsForFile(const ProjectFile &file, const ProjectPart &proje && projectPart.precompiledHeaders.contains(file.path)) { usePch = UsePrecompiledHeaders::No; } - optionsBuilder.updateFileLanguage(file.kind); + optionsBuilder.updateFileLanguage(fileKind); optionsBuilder.addPrecompiledHeaderOptions(usePch); const QJsonArray specificOptions = QJsonArray::fromStringList(optionsBuilder.options()); QJsonArray fullOptions = generalOptions; diff --git a/src/plugins/clangformat/clangformatchecks.ui b/src/plugins/clangformat/clangformatchecks.ui index 58d0388f321..e24ce37ef79 100644 --- a/src/plugins/clangformat/clangformatchecks.ui +++ b/src/plugins/clangformat/clangformatchecks.ui @@ -451,42 +451,13 @@ - - - AllowAllConstructorInitializersOnNextLine - - - - - - - Qt::StrongFocus - - - - Default - - - - - true - - - - - false - - - - - AllowAllParametersOfDeclarationOnNextLine - + Qt::StrongFocus @@ -508,14 +479,14 @@ - + AllowShortEnumsOnASingleLine - + Qt::StrongFocus @@ -537,14 +508,14 @@ - + AllowShortBlocksOnASingleLine - + Qt::StrongFocus @@ -566,14 +537,14 @@ - + AllowShortCaseLabelsOnASingleLine - + Qt::StrongFocus @@ -595,14 +566,14 @@ - + AllowShortFunctionsOnASingleLine - + Qt::StrongFocus @@ -634,14 +605,14 @@ - + AllowShortIfStatementsOnASingleLine - + Qt::StrongFocus @@ -668,14 +639,14 @@ - + AllowShortLambdasOnASingleLine - + Qt::StrongFocus @@ -702,14 +673,14 @@ - + AllowShortLoopsOnASingleLine - + Qt::StrongFocus @@ -731,43 +702,14 @@ - - - - AlwaysBreakAfterDefinitionReturnType - - - - - - - Qt::StrongFocus - - - - None - - - - - All - - - - - TopLevel - - - - - + AlwaysBreakAfterReturnType - + Qt::StrongFocus @@ -799,14 +741,14 @@ - + AlwaysBreakBeforeMultilineStrings - + Qt::StrongFocus @@ -828,14 +770,14 @@ - + AlwaysBreakTemplateDeclarations - + Qt::StrongFocus @@ -857,14 +799,14 @@ - + AttributeMacros - + @@ -894,14 +836,14 @@ - + BinPackArguments - + Qt::StrongFocus @@ -923,14 +865,14 @@ - + InsertTrailingCommas - + Qt::StrongFocus @@ -947,14 +889,14 @@ - + BinPackParameters - + Qt::StrongFocus @@ -976,14 +918,14 @@ - + BreakBeforeBinaryOperators - + Qt::StrongFocus @@ -1005,14 +947,14 @@ - + BreakBeforeBraces - + Qt::StrongFocus @@ -1064,21 +1006,21 @@ - + BraceWrapping - + AfterCaseLabel - + Qt::StrongFocus @@ -1100,14 +1042,14 @@ - + AfterClass - + Qt::StrongFocus @@ -1129,14 +1071,14 @@ - + AfterControlStatement - + Qt::StrongFocus @@ -1158,14 +1100,14 @@ - + AfterEnum - + Qt::StrongFocus @@ -1187,14 +1129,14 @@ - + AfterFunction - + Qt::StrongFocus @@ -1216,14 +1158,14 @@ - + AfterNamespace - + Qt::StrongFocus @@ -1245,14 +1187,14 @@ - + AfterObjCDeclaration - + Qt::StrongFocus @@ -1274,14 +1216,14 @@ - + AfterStruct - + Qt::StrongFocus @@ -1303,14 +1245,14 @@ - + AfterUnion - + Qt::StrongFocus @@ -1332,14 +1274,14 @@ - + AfterExternBlock - + Qt::StrongFocus @@ -1361,14 +1303,14 @@ - + BeforeCatch - + Qt::StrongFocus @@ -1390,14 +1332,14 @@ - + BeforeElse - + Qt::StrongFocus @@ -1419,14 +1361,14 @@ - + BeforeLambdaBody - + Qt::StrongFocus @@ -1448,14 +1390,14 @@ - + BeforeWhile - + Qt::StrongFocus @@ -1477,14 +1419,14 @@ - + IndentBraces - + Qt::StrongFocus @@ -1506,14 +1448,14 @@ - + SplitEmptyFunction - + Qt::StrongFocus @@ -1535,14 +1477,14 @@ - + SplitEmptyRecord - + Qt::StrongFocus @@ -1564,14 +1506,14 @@ - + SplitEmptyNamespace - + Qt::StrongFocus @@ -1593,14 +1535,14 @@ - + BreakBeforeConceptDeclarations - + Qt::StrongFocus @@ -1622,14 +1564,14 @@ - + BreakBeforeTernaryOperators - + Qt::StrongFocus @@ -1651,14 +1593,14 @@ - + BreakConstructorInitializers - + Qt::StrongFocus @@ -1680,14 +1622,14 @@ - + BreakAfterJavaFieldAnnotations - + Qt::StrongFocus @@ -1709,14 +1651,14 @@ - + BreakStringLiterals - + Qt::StrongFocus @@ -1738,14 +1680,14 @@ - + ColumnLimit - + @@ -1766,14 +1708,14 @@ - + CommentPragmas - + @@ -1794,14 +1736,14 @@ - + QualifierAlignment - + Qt::StrongFocus @@ -1828,14 +1770,14 @@ - + QualifierOrder - + @@ -1865,14 +1807,14 @@ - + BreakInheritanceList - + Qt::StrongFocus @@ -1899,14 +1841,14 @@ - + CompactNamespaces - + Qt::StrongFocus @@ -1928,43 +1870,14 @@ - - - - ConstructorInitializerAllOnOneLineOrOnePerLine - - - - - - - Qt::StrongFocus - - - - Default - - - - - true - - - - - false - - - - - + ConstructorInitializerIndentWidth - + @@ -1985,14 +1898,14 @@ - + ContinuationIndentWidth - + @@ -2013,14 +1926,14 @@ - + Cpp11BracedListStyle - + Qt::StrongFocus @@ -2042,14 +1955,14 @@ - + DeriveLineEnding - + Qt::StrongFocus @@ -2071,14 +1984,14 @@ - + DerivePointerAlignment - + Qt::StrongFocus @@ -2100,14 +2013,14 @@ - + DisableFormat - + Qt::StrongFocus @@ -2129,14 +2042,14 @@ - + EmptyLineAfterAccessModifier - + Qt::StrongFocus @@ -2158,14 +2071,14 @@ - + EmptyLineBeforeAccessModifier - + Qt::StrongFocus @@ -2192,14 +2105,14 @@ - + ExperimentalAutoDetectBinPacking - + Qt::StrongFocus @@ -2221,14 +2134,14 @@ - + PackConstructorInitializers - + Qt::StrongFocus @@ -2255,14 +2168,14 @@ - + FixNamespaceComments - + Qt::StrongFocus @@ -2284,14 +2197,14 @@ - + ForEachMacros - + @@ -2321,14 +2234,14 @@ - + IfMacros - + @@ -2358,14 +2271,14 @@ - + TypenameMacros - + @@ -2395,14 +2308,14 @@ - + StatementMacros - + @@ -2432,14 +2345,14 @@ - + NamespaceMacros - + @@ -2469,14 +2382,14 @@ - + WhitespaceSensitiveMacros - + @@ -2506,14 +2419,14 @@ - + IndentAccessModifiers - + Qt::StrongFocus @@ -2535,14 +2448,14 @@ - + IndentCaseLabels - + Qt::StrongFocus @@ -2564,14 +2477,14 @@ - + IndentCaseBlocks - + Qt::StrongFocus @@ -2593,14 +2506,14 @@ - + IndentGotoLabels - + Qt::StrongFocus @@ -2622,14 +2535,14 @@ - + IndentPPDirectives - + Qt::StrongFocus @@ -2651,14 +2564,14 @@ - + IndentExternBlock - + Qt::StrongFocus @@ -2680,14 +2593,14 @@ - + IndentRequires - + Qt::StrongFocus @@ -2709,14 +2622,14 @@ - + IndentWidth - + @@ -2737,14 +2650,14 @@ - + IndentWrappedFunctionNames - + Qt::StrongFocus @@ -2766,14 +2679,14 @@ - + JavaImportGroups - + @@ -2803,14 +2716,14 @@ - + JavaScriptQuotes - + Qt::StrongFocus @@ -2832,14 +2745,14 @@ - + JavaScriptWrapImports - + Qt::StrongFocus @@ -2861,14 +2774,14 @@ - + KeepEmptyLinesAtTheStartOfBlocks - + Qt::StrongFocus @@ -2890,14 +2803,14 @@ - + Language - + Qt::StrongFocus @@ -2954,14 +2867,14 @@ - + LambdaBodyIndentation - + Qt::StrongFocus @@ -2978,14 +2891,14 @@ - + MacroBlockBegin - + @@ -3006,14 +2919,14 @@ - + MacroBlockEnd - + @@ -3034,14 +2947,14 @@ - + MaxEmptyLinesToKeep - + @@ -3062,14 +2975,14 @@ - + NamespaceIndentation - + Qt::StrongFocus @@ -3091,14 +3004,14 @@ - + ObjCBinPackProtocolList - + Qt::StrongFocus @@ -3120,14 +3033,14 @@ - + ObjCBlockIndentWidth - + @@ -3148,14 +3061,14 @@ - + ObjCSpaceAfterProperty - + Qt::StrongFocus @@ -3177,14 +3090,14 @@ - + ObjCBreakBeforeNestedBlockParam - + Qt::StrongFocus @@ -3206,14 +3119,14 @@ - + ObjCSpaceBeforeProtocolList - + Qt::StrongFocus @@ -3235,14 +3148,14 @@ - + PenaltyBreakAssignment - + @@ -3263,14 +3176,14 @@ - + PenaltyBreakBeforeFirstCallParameter - + @@ -3291,14 +3204,14 @@ - + PenaltyBreakComment - + @@ -3319,14 +3232,14 @@ - + PenaltyBreakFirstLessLess - + @@ -3347,14 +3260,14 @@ - + PenaltyBreakOpenParenthesis - + @@ -3375,14 +3288,14 @@ - + PenaltyBreakString - + @@ -3403,14 +3316,14 @@ - + PenaltyBreakTemplateDeclaration - + @@ -3431,14 +3344,14 @@ - + PenaltyExcessCharacter - + @@ -3459,14 +3372,14 @@ - + PenaltyReturnTypeOnItsOwnLine - + @@ -3487,14 +3400,14 @@ - + PenaltyIndentedWhitespace - + @@ -3515,14 +3428,14 @@ - + PointerAlignment - + Qt::StrongFocus @@ -3544,14 +3457,14 @@ - + PPIndentWidth - + @@ -3572,14 +3485,14 @@ - + ReferenceAlignment - + Qt::StrongFocus @@ -3606,14 +3519,14 @@ - + ReflowComments - + Qt::StrongFocus @@ -3635,14 +3548,14 @@ - + RemoveBracesLLVM - + Qt::StrongFocus @@ -3664,14 +3577,14 @@ - + SeparateDefinitionBlocks - + Qt::StrongFocus @@ -3693,14 +3606,14 @@ - + ShortNamespaceLines - + @@ -3721,14 +3634,14 @@ - + SortIncludes - + Qt::StrongFocus @@ -3750,14 +3663,14 @@ - + SortJavaStaticImport - + Qt::StrongFocus @@ -3774,14 +3687,14 @@ - + SortUsingDeclarations - + Qt::StrongFocus @@ -3803,14 +3716,14 @@ - + SpaceAfterCStyleCast - + Qt::StrongFocus @@ -3832,14 +3745,14 @@ - + SpaceAfterLogicalNot - + Qt::StrongFocus @@ -3861,14 +3774,14 @@ - + SpaceAfterTemplateKeyword - + Qt::StrongFocus @@ -3890,14 +3803,14 @@ - + SpaceAroundPointerQualifiers - + Qt::StrongFocus @@ -3924,14 +3837,14 @@ - + SpaceBeforeAssignmentOperators - + Qt::StrongFocus @@ -3953,14 +3866,14 @@ - + SpaceBeforeCaseColon - + Qt::StrongFocus @@ -3982,14 +3895,14 @@ - + SpaceBeforeCpp11BracedList - + Qt::StrongFocus @@ -4011,14 +3924,14 @@ - + SpaceBeforeCtorInitializerColon - + Qt::StrongFocus @@ -4040,14 +3953,14 @@ - + SpaceBeforeInheritanceColon - + Qt::StrongFocus @@ -4069,14 +3982,14 @@ - + SpaceBeforeParens - + Qt::StrongFocus @@ -4113,21 +4026,21 @@ - + SpaceBeforeParensOptions - + AfterControlStatements - + Qt::StrongFocus @@ -4149,14 +4062,14 @@ - + AfterForeachMacros - + Qt::StrongFocus @@ -4178,14 +4091,14 @@ - + AfterFunctionDeclarationName - + Qt::StrongFocus @@ -4207,14 +4120,14 @@ - + AfterFunctionDefinitionName - + Qt::StrongFocus @@ -4236,14 +4149,14 @@ - + AfterIfMacros - + Qt::StrongFocus @@ -4265,14 +4178,14 @@ - + AfterOverloadedOperator - + Qt::StrongFocus @@ -4294,14 +4207,14 @@ - + BeforeNonEmptyParentheses - + Qt::StrongFocus @@ -4323,14 +4236,14 @@ - + SpaceBeforeRangeBasedForLoopColon - + Qt::StrongFocus @@ -4352,14 +4265,14 @@ - + SpaceInEmptyBlock - + Qt::StrongFocus @@ -4381,14 +4294,14 @@ - + SpaceInEmptyParentheses - + Qt::StrongFocus @@ -4410,14 +4323,14 @@ - + SpacesBeforeTrailingComments - + @@ -4438,14 +4351,14 @@ - + SpacesInAngles - + Qt::StrongFocus @@ -4467,14 +4380,14 @@ - + SpacesInConditionalStatement - + Qt::StrongFocus @@ -4496,14 +4409,14 @@ - + SpacesInContainerLiterals - + Qt::StrongFocus @@ -4525,14 +4438,14 @@ - + SpacesInCStyleCastParentheses - + Qt::StrongFocus @@ -4554,21 +4467,21 @@ - + SpacesInLineCommentPrefix - + Minimum - + @@ -4589,14 +4502,14 @@ - + Maximum - + @@ -4617,14 +4530,14 @@ - + SpacesInParentheses - + Qt::StrongFocus @@ -4646,14 +4559,14 @@ - + SpacesInSquareBrackets - + Qt::StrongFocus @@ -4675,14 +4588,14 @@ - + SpaceBeforeSquareBrackets - + Qt::StrongFocus @@ -4704,14 +4617,14 @@ - + BitFieldColonSpacing - + Qt::StrongFocus @@ -4738,14 +4651,14 @@ - + Standard - + Qt::StrongFocus @@ -4787,14 +4700,14 @@ - + StatementAttributeLikeMacros - + @@ -4824,14 +4737,14 @@ - + TabWidth - + @@ -4852,14 +4765,14 @@ - + UseCRLF - + Qt::StrongFocus @@ -4881,14 +4794,14 @@ - + UseTab - + Qt::StrongFocus diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 4a4a12fada7..826cdb8d352 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -1142,11 +1142,13 @@ void ClangTool::updateForCurrentState() m_diagnosticView->setCursor(isRunning ? Qt::BusyCursor : Qt::ArrowCursor); // Info bar: errors - const bool hasErrorText = !m_infoBarWidget->errorText().isEmpty(); - const bool hasErrors = m_filesFailed > 0; - if (hasErrors && !hasErrorText) { - const QString text = makeLink(tr("Failed to analyze %n file(s).", nullptr, m_filesFailed)); - m_infoBarWidget->setError(InfoBarWidget::Warning, text, [this] { showOutputPane(); }); + if (m_filesFailed > 0) { + const QString currentErrorText = m_infoBarWidget->errorText(); + const QString newErrorText = makeLink(tr("Failed to analyze %n file(s).", nullptr, + m_filesFailed)); + if (newErrorText != currentErrorText) + m_infoBarWidget->setError(InfoBarWidget::Warning, newErrorText, + [this] { showOutputPane(); }); } // Info bar: info diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index c48fdadea6c..b6b0947dd59 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -530,6 +530,11 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildSystem *bs) : CMakeTool::openCMakeHelpUrl(tool, "%1/manual/cmake.1.html#options"); }); + if (HostOsInfo::isMacHost()) + m_configurationStates->setDrawBase(false); + m_configurationStates->setExpanding(false); + m_reconfigureButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + updateSelection(); updateConfigurationStateSelection(); } @@ -1236,6 +1241,7 @@ static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArgume env, project->projectDirectory(), buildDirectory); + CMakePresets::Macros::updateInstallDir(configurePreset, env, project->projectDirectory()); // Merge the presets cache variables CMakeConfig cache; diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp index adf05be72ea..0d6eefe6346 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp +++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp @@ -838,7 +838,7 @@ FileApiData FileApiParser::parseData(QFutureInterface bool { if (fi.isCanceled()) { - errorMessage = Tr::tr("CMake parsing was cancelled."); + errorMessage = Tr::tr("CMake parsing was canceled."); return true; } return false; diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index 1220444cbfb..0e156ab4a47 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -99,13 +99,33 @@ static QString expandMacroEnv(const QString ¯oPrefix, return result; } +static QHash getEnvCombined( + const std::optional> &optPresetEnv, const Utils::Environment &env) +{ + QHash result; + + for (auto it = env.constBegin(); it != env.constEnd(); ++it) { + if (it.value().second) + result.insert(it.key().name, it.value().first); + } + + if (!optPresetEnv) + return result; + + QHash presetEnv = optPresetEnv.value(); + for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { + result[it->first] = it->second; + } + + return result; +} + template void expand(const PresetType &preset, Utils::Environment &env, const Utils::FilePath &sourceDirectory) { - const QHash presetEnv = preset.environment ? preset.environment.value() - : QHash(); + const QHash presetEnv = getEnvCombined(preset.environment, env); for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { const QString key = it->first; QString value = it->second; @@ -143,14 +163,15 @@ void expand(const PresetType &preset, { const QHash presetEnv = preset.environment ? preset.environment.value() : QHash(); - for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { const QString key = it->first; QString value = it->second; expandAllButEnv(preset, sourceDirectory, value); value = expandMacroEnv("env", value, [presetEnv](const QString ¯oName) { - return presetEnv.value(macroName); + if (presetEnv.contains(macroName)) + return presetEnv.value(macroName); + return QString("${%1}").arg(macroName); }); auto operation = Utils::EnvironmentItem::Operation::SetEnabled; @@ -178,9 +199,7 @@ void expand(const PresetType &preset, { expandAllButEnv(preset, sourceDirectory, value); - const QHash presetEnv = preset.environment ? preset.environment.value() - : QHash(); - + const QHash presetEnv = getEnvCombined(preset.environment, env); value = expandMacroEnv("env", value, [presetEnv](const QString ¯oName) { return presetEnv.value(macroName); }); @@ -234,6 +253,44 @@ void updateToolchainFile( configurePreset.cacheVariables = cache; } +void updateInstallDir(PresetsDetails::ConfigurePreset &configurePreset, + const Utils::Environment &env, + const Utils::FilePath &sourceDirectory) +{ + if (!configurePreset.installDir) + return; + + QString installDirString = configurePreset.installDir.value(); + CMakePresets::Macros::expand(configurePreset, env, sourceDirectory, installDirString); + + // Resolve the relative path first to source and afterwards to build directory + Utils::FilePath installDir = Utils::FilePath::fromString(installDirString); + if (installDir.isRelativePath()) { + Utils::FilePath probePath = sourceDirectory.resolvePath(installDir); + if (probePath != sourceDirectory) { + installDir = probePath; + } + } + installDirString = installDir.cleanPath().toString(); + + // installDir takes precedence to CMAKE_INSTALL_PREFIX + CMakeConfig cache = configurePreset.cacheVariables ? configurePreset.cacheVariables.value() + : CMakeConfig(); + + auto it = std::find_if(cache.begin(), cache.end(), [](const CMakeConfigItem &item) { + return item.key == "CMAKE_INSTALL_PREFIX"; + }); + if (it != cache.end()) + it->value = installDirString.toUtf8(); + else + cache << CMakeConfigItem("CMAKE_INSTALL_PREFIX", + CMakeConfigItem::PATH, + installDirString.toUtf8()); + + configurePreset.cacheVariables = cache; +} + + template void expandConditionValues(const PresetType &preset, const Utils::Environment &env, diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.h b/src/plugins/cmakeprojectmanager/presetsmacros.h index 0acf4d37cb6..09083b11fa5 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.h +++ b/src/plugins/cmakeprojectmanager/presetsmacros.h @@ -53,6 +53,13 @@ void updateToolchainFile(PresetsDetails::ConfigurePreset &configurePreset, const Utils::FilePath &sourceDirectory, const Utils::FilePath &buildDirectory); +/** + * Updates the cacheVariables parameter of the configurePreset with the expanded installDir parameter. + * Including macro expansion and relative paths resolving. + */ +void updateInstallDir(PresetsDetails::ConfigurePreset &configurePreset, + const Utils::Environment &env, + const Utils::FilePath &sourceDirectory); /** * Expands the condition values and then evaluates the condition object of the preset and returns * the boolean result. diff --git a/src/plugins/cmakeprojectmanager/presetsparser.cpp b/src/plugins/cmakeprojectmanager/presetsparser.cpp index 441709109db..bd0d17d8cb8 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.cpp +++ b/src/plugins/cmakeprojectmanager/presetsparser.cpp @@ -177,6 +177,8 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, preset.generator = object.value("generator").toString(); if (object.contains("binaryDir")) preset.binaryDir = object.value("binaryDir").toString(); + if (object.contains("installDir")) + preset.installDir = object.value("installDir").toString(); if (object.contains("toolchainFile")) preset.toolchainFile = object.value("toolchainFile").toString(); if (object.contains("cmakeExecutable")) @@ -462,6 +464,9 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other) if (!binaryDir && other.binaryDir) binaryDir = other.binaryDir; + if (!installDir && other.installDir) + installDir = other.installDir; + if (!cmakeExecutable && other.cmakeExecutable) cmakeExecutable = other.cmakeExecutable; diff --git a/src/plugins/cmakeprojectmanager/presetsparser.h b/src/plugins/cmakeprojectmanager/presetsparser.h index 5577620d5d8..7717f19c666 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.h +++ b/src/plugins/cmakeprojectmanager/presetsparser.h @@ -100,6 +100,7 @@ public: std::optional toolset; std::optional toolchainFile; std::optional binaryDir; + std::optional installDir; std::optional cmakeExecutable; std::optional cacheVariables; std::optional> environment; diff --git a/src/plugins/coreplugin/foldernavigationwidget.cpp b/src/plugins/coreplugin/foldernavigationwidget.cpp index 226629386f6..64f96a6be3f 100644 --- a/src/plugins/coreplugin/foldernavigationwidget.cpp +++ b/src/plugins/coreplugin/foldernavigationwidget.cpp @@ -708,13 +708,8 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev) if (m_fileSystemModel->flags(current) & Qt::ItemIsEditable) menu.addAction(Core::ActionManager::command(RENAMEFILE)->action()); newFolder = menu.addAction(tr("New Folder")); - if (isDir) { - QDirIterator it(filePath.toString(), - QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); - // only allow removing folders that are empty - if (!it.hasNext()) - removeFolder = menu.addAction(tr("Remove Folder")); - } + if (isDir) + removeFolder = menu.addAction(tr("Remove Folder")); } menu.addSeparator(); @@ -733,7 +728,14 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev) else createNewFolder(current.parent()); } else if (action == removeFolder) { - QDir().rmdir(filePath.toString()); + RemoveFileDialog dialog(filePath, Core::ICore::dialogParent()); + dialog.setDeleteFileVisible(false); + if (dialog.exec() == QDialog::Accepted) { + QString errorMessage; + filePath.removeRecursively(&errorMessage); + if (!errorMessage.isEmpty()) + QMessageBox::critical(ICore::dialogParent(), tr("Error"), errorMessage); + } } else if (action == collapseAllAction) { m_listView->collapseAll(); } diff --git a/src/plugins/coreplugin/locator/externaltoolsfilter.cpp b/src/plugins/coreplugin/locator/externaltoolsfilter.cpp index db1a35c3dda..df9cb14243a 100644 --- a/src/plugins/coreplugin/locator/externaltoolsfilter.cpp +++ b/src/plugins/coreplugin/locator/externaltoolsfilter.cpp @@ -17,7 +17,7 @@ ExternalToolsFilter::ExternalToolsFilter() { setId("Run external tool"); setDisplayName(tr("Run External Tool")); - setDescription(tr("Runs an external tool that you have set up in the options (Environment > " + setDescription(tr("Runs an external tool that you have set up in the preferences (Environment > " "External Tools).")); setDefaultShortcutString("x"); setPriority(Medium); diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp index 1213812bd4a..49f685d693e 100644 --- a/src/plugins/coreplugin/systemsettings.cpp +++ b/src/plugins/coreplugin/systemsettings.cpp @@ -223,7 +223,7 @@ public: m_autoSaveRefactoringCheckBox->setChecked(EditorManager::autoSaveAfterRefactoring()); m_autoSaveRefactoringCheckBox->setToolTip( tr("Automatically saves all open files " - "affected by a refactoring operation,\n provided they were unmodified before the " + "affected by a refactoring operation,\nprovided they were unmodified before the " "refactoring.")); m_autoSaveInterval->setValue(EditorManagerPrivate::autoSaveInterval()); m_autoSuspendCheckBox->setChecked(EditorManagerPrivate::autoSuspendEnabled()); diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index e547ba8ab64..856d5e7acac 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -336,7 +336,7 @@ FilePaths VcsManager::promptToDelete(IVersionControl *vc, const FilePaths &fileP return fp.toUserOutput(); }).join("
  • ") + "
  • "; const QString title = tr("Version Control"); - const QString msg = tr("Remove the following files from the version control system (%2)?" + const QString msg = tr("Remove the following files from the version control system (%2)? " "%1Note: This might remove the local file.").arg(fileListForUi, vc->displayName()); const QMessageBox::StandardButton button = QMessageBox::question(ICore::dialogParent(), title, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 3bf52d996df..867223e15c1 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -369,7 +369,7 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err contextMenu->addAction(cmd, Constants::G_CONTEXT_FIRST); cppToolsMenu->addAction(cmd); QAction * const followSymbolToTypeInNextSplit = - new QAction(tr("Follow Symbol To Type in Next Split"), this); + new QAction(tr("Follow Symbol to Type in Next Split"), this); cmd = ActionManager::registerAction(followSymbolToTypeInNextSplit, Constants::FOLLOW_SYMBOL_TO_TYPE_IN_NEXT_SPLIT, context, true); cmd->setDefaultKeySequence(QKeySequence(HostOsInfo::isMacHost() diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index b702ebabc01..3a066abcb4e 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -345,19 +345,19 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) .arg(reason)); }; static const auto showFallbackWarning = [](const QString &reason) { - Core::MessageManager::writeSilently(Tr::tr("%1, falling back to built-in preprocessor") + Core::MessageManager::writeSilently(Tr::tr("%1, falling back to built-in preprocessor.") .arg(reason)); }; static const auto saveAndOpen = [](const FilePath &filePath, const QByteArray &contents, bool inNextSplit) { SaveFile f(filePath.toString()); if (!f.open()) { - showError(Tr::tr("Failed to open output file \"%1\"").arg(filePath.toUserOutput())); + showError(Tr::tr("Failed to open output file \"%1\".").arg(filePath.toUserOutput())); return; } f.write(contents); if (!f.commit()) { - showError(Tr::tr("Failed to write output file \"%1\"").arg(filePath.toUserOutput())); + showError(Tr::tr("Failed to write output file \"%1\".").arg(filePath.toUserOutput())); return; } f.close(); @@ -389,7 +389,7 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) const Project * const project = ProjectTree::currentProject(); if (!project || !project->activeTarget() || !project->activeTarget()->activeBuildConfiguration()) { - showFallbackWarning(Tr::tr("Could not determine which compiler to invoke")); + showFallbackWarning(Tr::tr("Could not determine which compiler to invoke.")); useBuiltinPreprocessor(); return; } @@ -401,7 +401,7 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) } else if (classifier.isCxx() || classifier.isHeader()) { tc = ToolChainKitAspect::cxxToolChain(project->activeTarget()->kit()); } else { - showFallbackWarning(Tr::tr("Could not determine which compiler to invoke")); + showFallbackWarning(Tr::tr("Could not determine which compiler to invoke.")); useBuiltinPreprocessor(); return; } @@ -411,7 +411,7 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) && (tc->typeId() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID || tc->typeId() == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID); if (!isGcc && !isMsvc) { - showFallbackWarning(Tr::tr("Could not determine compiler command line")); + showFallbackWarning(Tr::tr("Could not determine compiler command line.")); useBuiltinPreprocessor(); return; } @@ -421,7 +421,7 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) return pp->belongsToProject(ProjectTree::currentProject()); }); if (!projectPart) { - showFallbackWarning(Tr::tr("Could not determine compiler command line")); + showFallbackWarning(Tr::tr("Could not determine compiler command line.")); useBuiltinPreprocessor(); return; } diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index ac08e4c74d3..97e4ed1c77f 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2244,9 +2244,9 @@ void CdbEngine::checkQtSdkPdbFiles(const QString &module) const QString message = Tr::tr("The installed %1 is missing debug information files.\n" - "Locals and Expression might not be able to display all Qt Types in a " + "Locals and Expression might not be able to display all Qt types in a " "human readable format.\n\n" - "Please install the \"Qt Debug Information Files\" Package from the " + "Install the \"Qt Debug Information Files\" Package from the " "Maintenance Tool for this Qt installation to get all relevant " "symbols for the debugger.") .arg(qtName); diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 68d9d846b3a..0dec35b3fd4 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -104,7 +104,7 @@ DebuggerSettings::DebuggerSettings() "in system logs.")); fontSizeFollowsEditor.setSettingsKey(debugModeGroup, "FontSizeFollowsEditor"); - fontSizeFollowsEditor.setToolTip(Tr::tr("Changes the font size in the debugger views when" + fontSizeFollowsEditor.setToolTip(Tr::tr("Changes the font size in the debugger views when " "the font size in the main editor changes.")); fontSizeFollowsEditor.setLabelText(Tr::tr("Debugger font size follows main editor")); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 695175bc01d..f8fe0805107 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1369,7 +1369,8 @@ void DebuggerEngine::notifyInferiorStopFailed() void DebuggerEnginePrivate::setInitialActionStates() { - m_returnWindow->setVisible(false); + if (m_returnWindow) + m_returnWindow->setVisible(false); setBusyCursor(false); m_recordForReverseOperationAction.setCheckable(true); @@ -1417,7 +1418,8 @@ void DebuggerEnginePrivate::setInitialActionStates() debuggerSettings()->autoDerefPointers.setEnabled(true); debuggerSettings()->expandStack.setEnabled(false); - m_threadLabel->setEnabled(false); + if (m_threadLabel) + m_threadLabel->setEnabled(false); } void DebuggerEnginePrivate::updateState() diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 190681fa388..e6d3fd20546 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -2200,10 +2200,10 @@ void QmlEnginePrivate::handleScope(const QVariantMap &response) setWatchItemHasChildren(item.get(), localData.hasChildren()); if (localData.value.isValid() || item->wantsChildren || localData.expectedProperties == 0) { - WatchHandler *watchHander = engine->watchHandler(); - if (watchHander->isExpandedIName(item->iname)) + WatchHandler *watchHandler = engine->watchHandler(); + if (watchHandler->isExpandedIName(item->iname)) itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp}); - watchHander->insertItem(item.release()); + watchHandler->insertItem(item.release()); } else { itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp}); } diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp index 92540f6f078..a8286368d88 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -40,6 +40,7 @@ static const char settingsGroupC[] = "DiffEditor"; static const char descriptionVisibleKeyC[] = "DescriptionVisible"; +static const char descriptionHeightKeyC[] = "DescriptionHeight"; static const char horizontalScrollBarSynchronizationKeyC[] = "HorizontalScrollBarSynchronization"; static const char contextLineCountKeyC[] = "ContextLineNumbers"; static const char ignoreWhitespaceKeyC[] = "IgnoreWhitespace"; @@ -134,13 +135,23 @@ DiffEditor::DiffEditor() // Widget: QSplitter *splitter = new MiniSplitter(Qt::Vertical); + connect(splitter, &QSplitter::splitterMoved, this, [this, splitter](int pos) { + if (!m_showDescription) + return; + const int lineSpacing = splitter->widget(0)->fontMetrics().lineSpacing(); + const int descHeight = (pos + lineSpacing - 1) / lineSpacing; // round up + if (m_descriptionHeight == descHeight) + return; + m_descriptionHeight = descHeight; + saveSetting(descriptionHeightKeyC, descHeight); + }); m_descriptionWidget = new DescriptionEditorWidget(splitter); m_descriptionWidget->setReadOnly(true); - connect(m_descriptionWidget, &DescriptionEditorWidget::requestResize, this, [splitter] { + connect(m_descriptionWidget, &DescriptionEditorWidget::requestResize, this, [this, splitter] { if (splitter->count() == 0) return; QList sizes = splitter->sizes(); - const int descHeight = splitter->widget(0)->fontMetrics().lineSpacing() * 8; + const int descHeight = splitter->widget(0)->fontMetrics().lineSpacing() * m_descriptionHeight; const int diff = descHeight - sizes[0]; if (diff > 0) { sizes[0] += diff; @@ -522,6 +533,7 @@ IDiffView *DiffEditor::loadSettings() // Read current settings: s->beginGroup(settingsGroupC); m_showDescription = s->value(descriptionVisibleKeyC, true).toBool(); + m_descriptionHeight = s->value(descriptionHeightKeyC, 8).toInt(); m_sync = s->value(horizontalScrollBarSynchronizationKeyC, true).toBool(); m_document->setIgnoreWhitespace(s->value(ignoreWhitespaceKeyC, false).toBool()); m_document->setContextLineCount(s->value(contextLineCountKeyC, 3).toInt()); diff --git a/src/plugins/diffeditor/diffeditor.h b/src/plugins/diffeditor/diffeditor.h index c4f852c4fc6..b4d636c5106 100644 --- a/src/plugins/diffeditor/diffeditor.h +++ b/src/plugins/diffeditor/diffeditor.h @@ -88,6 +88,7 @@ private: QPair m_currentFileChunk; int m_currentViewIndex = -1; int m_currentDiffFileIndex = -1; + int m_descriptionHeight = 8; Utils::Guard m_ignoreChanges; bool m_sync = false; bool m_showDescription = true; diff --git a/src/plugins/diffeditor/selectabletexteditorwidget.cpp b/src/plugins/diffeditor/selectabletexteditorwidget.cpp index 781b7a8c513..9be6fce913f 100644 --- a/src/plugins/diffeditor/selectabletexteditorwidget.cpp +++ b/src/plugins/diffeditor/selectabletexteditorwidget.cpp @@ -2,12 +2,17 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "selectabletexteditorwidget.h" + +#include #include #include +#include #include #include +using namespace TextEditor; + namespace DiffEditor { namespace Internal { @@ -16,6 +21,15 @@ SelectableTextEditorWidget::SelectableTextEditorWidget(Utils::Id id, QWidget *pa { setFrameStyle(QFrame::NoFrame); setupFallBackEditor(id); + + setReadOnly(true); + + connect(TextEditorSettings::instance(), &TextEditorSettings::displaySettingsChanged, + this, &SelectableTextEditorWidget::setDisplaySettings); + SelectableTextEditorWidget::setDisplaySettings(TextEditorSettings::displaySettings()); + + setCodeStyle(TextEditorSettings::codeStyle()); + setCodeFoldingSupported(true); } SelectableTextEditorWidget::~SelectableTextEditorWidget() = default; @@ -25,6 +39,16 @@ void SelectableTextEditorWidget::setSelections(const DiffSelections &selections) m_diffSelections = selections; } +void SelectableTextEditorWidget::setDisplaySettings(const DisplaySettings &displaySettings) +{ + DisplaySettings settings = displaySettings; + settings.m_textWrapping = false; + settings.m_displayLineNumbers = true; + settings.m_markTextChanges = false; + settings.m_highlightBlocks = false; + TextEditorWidget::setDisplaySettings(settings); +} + static QList subtractSelection( const DiffSelection &minuendSelection, const DiffSelection &subtrahendSelection) @@ -84,7 +108,7 @@ DiffSelections SelectableTextEditorWidget::polishedSelections(const DiffSelectio void SelectableTextEditorWidget::setFoldingIndent(const QTextBlock &block, int indent) { - if (TextEditor::TextBlockUserData *userData = TextEditor::TextDocumentLayout::userData(block)) + if (TextBlockUserData *userData = TextDocumentLayout::userData(block)) userData->setFoldingIndent(indent); } diff --git a/src/plugins/diffeditor/selectabletexteditorwidget.h b/src/plugins/diffeditor/selectabletexteditorwidget.h index eb82b7b5384..97a73c91c14 100644 --- a/src/plugins/diffeditor/selectabletexteditorwidget.h +++ b/src/plugins/diffeditor/selectabletexteditorwidget.h @@ -5,6 +5,8 @@ #include +namespace TextEditor { class DisplaySettings; } + namespace DiffEditor { namespace Internal { @@ -29,6 +31,8 @@ public: ~SelectableTextEditorWidget() override; void setSelections(const DiffSelections &selections); + void setDisplaySettings(const TextEditor::DisplaySettings &displaySettings) override; + static DiffSelections polishedSelections(const DiffSelections &selections); static void setFoldingIndent(const QTextBlock &block, int indent); diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp index 952eea642f9..4fba7076c45 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp @@ -55,7 +55,7 @@ public: void setFolded(int blockNumber, bool folded); - void setDisplaySettings(const DisplaySettings &ds) override; + void setDisplaySettings(const DisplaySettings &displaySettings) override; SideDiffData diffData() const { return m_data; } void setDiffData(const SideDiffData &data) { m_data = data; } @@ -68,7 +68,6 @@ signals: int diffFileIndex, int chunkIndex, const ChunkSelection &selection); - void foldChanged(int blockNumber, bool folded); void gotDisplaySettings(); void gotFocus(); @@ -119,13 +118,6 @@ private: SideDiffEditorWidget::SideDiffEditorWidget(QWidget *parent) : SelectableTextEditorWidget("DiffEditor.SideDiffEditor", parent) { - DisplaySettings settings = displaySettings(); - settings.m_textWrapping = false; - settings.m_displayLineNumbers = true; - settings.m_markTextChanges = false; - settings.m_highlightBlocks = false; - SelectableTextEditorWidget::setDisplaySettings(settings); - connect(this, &TextEditorWidget::tooltipRequested, this, [this](const QPoint &point, int position) { const int block = document()->findBlock(position).blockNumber(); const auto it = m_data.m_fileInfo.constFind(block); @@ -135,11 +127,6 @@ SideDiffEditorWidget::SideDiffEditorWidget(QWidget *parent) ToolTip::hide(); }); - auto documentLayout = qobject_cast(document()->documentLayout()); - if (documentLayout) - connect(documentLayout, &TextDocumentLayout::foldChanged, - this, &SideDiffEditorWidget::foldChanged); - setCodeFoldingSupported(true); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); } @@ -176,14 +163,9 @@ void SideDiffEditorWidget::setFolded(int blockNumber, bool folded) documentLayout->emitDocumentSizeChanged(); } -void SideDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds) +void SideDiffEditorWidget::setDisplaySettings(const DisplaySettings &displaySettings) { - DisplaySettings settings = displaySettings(); - settings.m_visualizeWhitespace = ds.m_visualizeWhitespace; - settings.m_displayFoldingMarkers = ds.m_displayFoldingMarkers; - settings.m_scrollBarHighlights = ds.m_scrollBarHighlights; - settings.m_highlightCurrentLine = ds.m_highlightCurrentLine; - SelectableTextEditorWidget::setDisplaySettings(settings); + SelectableTextEditorWidget::setDisplaySettings(displaySettings); emit gotDisplaySettings(); } @@ -714,8 +696,6 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent) { auto setupEditor = [this](DiffSide side) { m_editor[side] = new SideDiffEditorWidget(this); - m_editor[side]->setReadOnly(true); - m_editor[side]->setCodeStyle(TextEditorSettings::codeStyle()); connect(m_editor[side], &SideDiffEditorWidget::jumpToOriginalFileRequested, this, std::bind(&SideBySideDiffEditorWidget::jumpToOriginalFileRequested, this, @@ -789,11 +769,6 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent) this, &SideBySideDiffEditorWidget::setFontSettings); setFontSettings(TextEditorSettings::fontSettings()); - connect(m_editor[LeftSide], &SideDiffEditorWidget::foldChanged, - m_editor[RightSide], &SideDiffEditorWidget::setFolded); - connect(m_editor[RightSide], &SideDiffEditorWidget::foldChanged, - m_editor[LeftSide], &SideDiffEditorWidget::setFolded); - syncHorizontalScrollBarPolicy(); m_splitter = new MiniSplitter(this); @@ -926,6 +901,16 @@ void SideBySideDiffEditorWidget::showDiff() m_editor[LeftSide]->setReadOnly(true); m_editor[RightSide]->setReadOnly(true); } + auto leftDocumentLayout = qobject_cast( + m_editor[LeftSide]->document()->documentLayout()); + auto rightDocumentLayout = qobject_cast( + m_editor[RightSide]->document()->documentLayout()); + if (leftDocumentLayout && rightDocumentLayout) { + connect(leftDocumentLayout, &TextDocumentLayout::foldChanged, + m_editor[RightSide], &SideDiffEditorWidget::setFolded); + connect(rightDocumentLayout, &TextDocumentLayout::foldChanged, + m_editor[LeftSide], &SideDiffEditorWidget::setFolded); + } m_editor[LeftSide]->setSelections(results[LeftSide].selections); m_editor[RightSide]->setSelections(results[RightSide].selections); setCurrentDiffFileIndex(m_controller.currentDiffFileIndex()); diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index b977c159af2..400e9877551 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -37,19 +36,7 @@ UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent) : SelectableTextEditorWidget("DiffEditor.UnifiedDiffEditor", parent) , m_controller(this) { - setReadOnly(true); - - DisplaySettings settings = displaySettings(); - settings.m_textWrapping = false; - settings.m_displayLineNumbers = true; - settings.m_markTextChanges = false; - settings.m_highlightBlocks = false; - SelectableTextEditorWidget::setDisplaySettings(settings); - connect(TextEditorSettings::instance(), &TextEditorSettings::displaySettingsChanged, - this, &UnifiedDiffEditorWidget::setDisplaySettings); - setDisplaySettings(TextEditorSettings::displaySettings()); - - setCodeStyle(TextEditorSettings::codeStyle()); + setVisualIndentOffset(1); connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged, this, &UnifiedDiffEditorWidget::setFontSettings); @@ -64,7 +51,6 @@ UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent) context->setWidget(this); context->setContext(Core::Context(Constants::UNIFIED_VIEW_ID)); Core::ICore::addContextObject(context); - setCodeFoldingSupported(true); } UnifiedDiffEditorWidget::~UnifiedDiffEditorWidget() @@ -105,16 +91,6 @@ void UnifiedDiffEditorWidget::restoreState() m_state.clear(); } -void UnifiedDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds) -{ - DisplaySettings settings = displaySettings(); - settings.m_visualizeWhitespace = ds.m_visualizeWhitespace; - settings.m_displayFoldingMarkers = ds.m_displayFoldingMarkers; - settings.m_scrollBarHighlights = ds.m_scrollBarHighlights; - settings.m_highlightCurrentLine = ds.m_highlightCurrentLine; - SelectableTextEditorWidget::setDisplaySettings(settings); -} - void UnifiedDiffEditorWidget::setFontSettings(const FontSettings &fontSettings) { m_controller.setFontSettings(fontSettings); diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.h b/src/plugins/diffeditor/unifieddiffeditorwidget.h index 5320e6d0174..4555ac2081f 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.h +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.h @@ -10,10 +10,7 @@ namespace Core { class IContext; } -namespace TextEditor { -class DisplaySettings; -class FontSettings; -} +namespace TextEditor { class FontSettings; } namespace DiffEditor { @@ -80,7 +77,6 @@ public: void restoreState(); void clear(const QString &message = {}); - void setDisplaySettings(const TextEditor::DisplaySettings &ds) override; signals: void currentDiffFileIndexChanged(int index); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 4bf60407d3f..0850abf30eb 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -539,6 +539,9 @@ bool isValidMountInfo(const DockerDevicePrivate::TemporaryMountInfo &mi) if (!mi.path.isAbsolutePath() || !mi.containerPath.isAbsolutePath()) return false; + if (mi.containerPath.isRootPath()) + return false; + if (!mi.path.exists()) return false; diff --git a/src/plugins/docker/dockerdevicewidget.cpp b/src/plugins/docker/dockerdevicewidget.cpp index ce88373306a..6105b107ba2 100644 --- a/src/plugins/docker/dockerdevicewidget.cpp +++ b/src/plugins/docker/dockerdevicewidget.cpp @@ -65,9 +65,9 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) DockerApi::recheckDockerDaemon(); }); - m_keepEntryPoint = new QCheckBox(Tr::tr("Don't modify entry point")); + m_keepEntryPoint = new QCheckBox(Tr::tr("Do not modify entry point")); m_keepEntryPoint->setToolTip( - Tr::tr("If checked, the entry point of the image will not be modified. Only use this if " + Tr::tr("Prevents modifying the entry point of the image. Enable only if " "the image starts into a shell.")); m_keepEntryPoint->setChecked(m_data.keepEntryPoint); m_keepEntryPoint->setEnabled(true); diff --git a/src/plugins/gitlab/gitlabprojectsettings.cpp b/src/plugins/gitlab/gitlabprojectsettings.cpp index 6cc171d5fd0..44e9ba1ee2b 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.cpp +++ b/src/plugins/gitlab/gitlabprojectsettings.cpp @@ -215,12 +215,12 @@ void GitLabProjectSettingsWidget::onConnectionChecked(const Project &project, } else { if (project.accessLevel != -1) { m_infoLabel->setType(Utils::InfoLabel::Ok); - m_infoLabel->setText(tr("Accessible (%1)") + m_infoLabel->setText(tr("Accessible (%1).") .arg(accessLevelString(project.accessLevel))); linkable = true; } else { m_infoLabel->setType(Utils::InfoLabel::Warning); - m_infoLabel->setText(tr("Read only access")); + m_infoLabel->setText(tr("Read only access.")); } } m_infoLabel->setVisible(true); diff --git a/src/plugins/mcusupport/mcuabstractpackage.h b/src/plugins/mcusupport/mcuabstractpackage.h index e4240a41c5b..7f2de3b0514 100644 --- a/src/plugins/mcusupport/mcuabstractpackage.h +++ b/src/plugins/mcusupport/mcuabstractpackage.h @@ -22,6 +22,7 @@ public: InvalidPath, ValidPathInvalidPackage, ValidPackageMismatchedVersion, + ValidPackageVersionNotDetected, ValidPackage }; diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index ef7f9f2ed2a..ce846ffc708 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -80,6 +80,7 @@ public: case McuToolChainPackage::ToolChainType::KEIL: case McuToolChainPackage::ToolChainType::MSVC: case McuToolChainPackage::ToolChainType::GCC: + case McuToolChainPackage::ToolChainType::MinGW: case McuToolChainPackage::ToolChainType::ArmGcc: ToolChainKitAspect::setToolChain(k, tcPackage->toolChain( @@ -142,6 +143,7 @@ public: case McuToolChainPackage::ToolChainType::KEIL: case McuToolChainPackage::ToolChainType::MSVC: case McuToolChainPackage::ToolChainType::GCC: + case McuToolChainPackage::ToolChainType::MinGW: case McuToolChainPackage::ToolChainType::ArmGcc: { const QVariant debuggerId = tcPackage->debuggerId(); if (debuggerId.isValid()) { diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index f4e301354b1..053cbd5d1b6 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -94,7 +94,7 @@ const McuPackageVersionDetector *McuPackage::getVersionDetector() const FilePath McuPackage::basePath() const { - return m_fileChooser != nullptr ? m_fileChooser->filePath() : m_path; + return m_path; } FilePath McuPackage::path() const @@ -114,15 +114,12 @@ FilePath McuPackage::detectionPath() const void McuPackage::setPath(const FilePath &newPath) { + if (m_path == newPath) + return; + m_path = newPath; updateStatus(); -} - -void McuPackage::updatePath() -{ - m_path = m_fileChooser->rawFilePath(); - m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath); - updateStatus(); + emit changed(); } void McuPackage::updateStatus() @@ -133,14 +130,22 @@ void McuPackage::updateStatus() m_detectedVersion = validPath && validPackage && m_versionDetector ? m_versionDetector->parseVersion(basePath()) : 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; + const bool validVersion = m_versions.isEmpty() || m_versions.contains(m_detectedVersion); + + if (m_path.isEmpty()) { + m_status = Status::EmptyPath; + } else if (!validPath) { + m_status = Status::InvalidPath; + } else if (!validPackage) { + m_status = Status::ValidPathInvalidPackage; + } else if (m_versionDetector && m_detectedVersion.isEmpty()) { + m_status = Status::ValidPackageVersionNotDetected; + } else if (!validVersion) { + m_status = Status::ValidPackageMismatchedVersion; + } else { + m_status = Status::ValidPackage; + } emit statusChanged(); } @@ -162,6 +167,7 @@ void McuPackage::updateStatusUi() m_infoLabel->setType(InfoLabel::Ok); break; case Status::ValidPackageMismatchedVersion: + case Status::ValidPackageVersionNotDetected: m_infoLabel->setType(InfoLabel::Warning); break; default: @@ -216,12 +222,21 @@ QString McuPackage::statusText() const ? tr("Path is empty.") : tr("Path is empty, %1 not found.").arg(displayRequiredPath); break; + case Status::ValidPackageVersionNotDetected: + response = tr("Path %1 exists, but version could not be detected.").arg(displayPackagePath); + break; } return response; } bool McuPackage::writeToSettings() const { + if (m_settingsKey.isEmpty()) { + // Writing with an empty settings key will result in multiple packages writing their value + // in the same key "Package_", with the suffix missing, overwriting each other. + return false; + } + return settingsHandler->write(m_settingsKey, m_path, m_defaultPath); } @@ -254,11 +269,15 @@ QWidget *McuPackage::widget() m_fileChooser->setFilePath(m_path); - QObject::connect(this, &McuPackage::statusChanged, this, [this] { updateStatusUi(); }); + QObject::connect(this, &McuPackage::statusChanged, widget, [this] { updateStatusUi(); }); QObject::connect(m_fileChooser, &PathChooser::textChanged, this, [this] { - updatePath(); - emit changed(); + setPath(m_fileChooser->rawFilePath()); + }); + + connect(this, &McuPackage::changed, m_fileChooser, [this] { + m_fileChooser->lineEdit()->button(FancyLineEdit::Right)->setEnabled(m_path != m_defaultPath); + m_fileChooser->setFilePath(m_path); }); updateStatus(); @@ -332,7 +351,8 @@ McuToolChainPackage::ToolChainType McuToolChainPackage::toolchainType() const bool McuToolChainPackage::isDesktopToolchain() const { - return m_type == ToolChainType::MSVC || m_type == ToolChainType::GCC; + return m_type == ToolChainType::MSVC || m_type == ToolChainType::GCC + || m_type == ToolChainType::MinGW; } ToolChain *McuToolChainPackage::msvcToolChain(Id language) @@ -358,6 +378,28 @@ ToolChain *McuToolChainPackage::gccToolChain(Id language) return toolChain; } +static ToolChain *mingwToolChain(const FilePath &path, Id language) +{ + ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) { + // find a MinGW toolchain having the same path from registered toolchains + const Abi abi = t->targetAbi(); + return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID + && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 + && t->language() == language && t->compilerCommand() == path; + }); + if (!toolChain) { + // if there's no MinGW toolchain having the same path, + // a proper MinGW would be selected from the registered toolchains. + toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { + const Abi abi = t->targetAbi(); + return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID + && 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) { @@ -422,6 +464,12 @@ ToolChain *McuToolChainPackage::toolChain(Id language) const return msvcToolChain(language); case ToolChainType::GCC: return gccToolChain(language); + case ToolChainType::MinGW: { + const QLatin1String compilerName( + language == ProjectExplorer::Constants::C_LANGUAGE_ID ? "gcc" : "g++"); + const FilePath compilerPath = (path() / "bin" / compilerName).withExecutableSuffix(); + return mingwToolChain(compilerPath, language); + } case ToolChainType::IAR: { const FilePath compiler = (path() / "/bin/iccarm").withExecutableSuffix(); return iarToolChain(compiler, language); @@ -452,6 +500,8 @@ QString McuToolChainPackage::toolChainName() const return QLatin1String("msvc"); case ToolChainType::GCC: return QLatin1String("gcc"); + case ToolChainType::MinGW: + return QLatin1String("mingw"); case ToolChainType::ArmGcc: return QLatin1String("armgcc"); case ToolChainType::IAR: diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index 84abac0b9cb..67ac7221540 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -100,7 +100,7 @@ class McuToolChainPackage final : public McuPackage { Q_OBJECT public: - enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, Unsupported }; + enum class ToolChainType { IAR, KEIL, MSVC, GCC, ArmGcc, GHS, GHSArm, MinGW, Unsupported }; McuToolChainPackage(const SettingsHandler::Ptr &settingsHandler, const QString &label, diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index 704ca9af5d2..3411b75817a 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -8,6 +8,7 @@ #include "mcusupportoptions.h" #include "mcusupportsdk.h" #include "mcutarget.h" +#include "mcutargetfactory.h" #include "settingshandler.h" #include @@ -286,6 +287,7 @@ void McuSupportOptionsWidget::apply() bool pathsChanged = false; m_settingsHandler->setAutomaticKitCreation(m_options.automaticKitCreationEnabled()); + McuTargetFactory::expandVariables(m_options.sdkRepository.packages); pathsChanged |= m_options.qtForMCUsSdkPackage->writeToSettings(); for (const auto &package : std::as_const(m_options.sdkRepository.packages)) pathsChanged |= package->writeToSettings(); diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index afa1d4d4884..cc72a1a7b4b 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -83,7 +82,7 @@ static McuPackageVersionDetector *generatePackageVersionDetector(const QString & R"(\b(\d+\.\d+\.\d+)\b)"); if (envVar.startsWith("RGL")) - return new McuPackageDirectoryVersionDetector("rgl_*_obj_*", R"(\d+\.\d+\.\w+)", false); + return new McuPackagePathVersionDetector(R"(\d+\.\d+\.\w+)"); return nullptr; } @@ -369,8 +368,8 @@ McuPackagePtr createStm32CubeProgrammerPackage(const SettingsHandler::Ptr &setti FilePath defaultPath = {}; const FilePath detectionPath = FilePath::fromUserInput( - QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe" - : "/bin/STM32_Programmer.sh")); + QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "bin/STM32_Programmer_CLI.exe" + : "bin/STM32_Programmer.sh")); return McuPackagePtr{ new McuPackage(settingsHandler, @@ -614,10 +613,19 @@ VersionDetection parseVersionDetection(const QJsonObject &packageEntry) versioning["executableArgs"].toString(), versioning["xmlElement"].toString(), versioning["xmlAttribute"].toString(), - versioning["isFile"].toBool(true), }; } +QString getOsSpecificValue(const QJsonValue &entry) +{ + if (entry.isObject()) { + //The json entry has os-specific values + return entry[HostOsInfo::isWindowsHost() ? QString("windows") : QString("linux")].toString(); + } + //The entry does not have os-specific values + return entry.toString(); +} + static PackageDescription parsePackage(const QJsonObject &cmakeEntry) { const QVariantList versionsVariantList = cmakeEntry["versions"].toArray().toVariantList(); @@ -627,14 +635,8 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry) }); //Parse the default value depending on the operating system - QString defaultPathString; - if (cmakeEntry["defaultValue"].isObject()) - defaultPathString - = cmakeEntry["defaultValue"] - .toObject()[HostOsInfo::isWindowsHost() ? QString("windows") : QString("unix")] - .toString(""); - else - defaultPathString = cmakeEntry["defaultValue"].toString(); + QString defaultPathString = getOsSpecificValue(cmakeEntry["defaultValue"]); + QString detectionPathString = getOsSpecificValue(cmakeEntry["detectionPath"]); QString label = cmakeEntry["label"].toString(); @@ -647,7 +649,7 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry) cmakeEntry["description"].toString(), cmakeEntry["setting"].toString(), FilePath::fromUserInput(defaultPathString), - FilePath::fromUserInput(cmakeEntry["validation"].toString()), + FilePath::fromUserInput(detectionPathString), versions, parseVersionDetection(cmakeEntry), cmakeEntry["addToSystemPath"].toBool()}; @@ -663,7 +665,7 @@ static QList parsePackages(const QJsonArray &cmakeEntries) return result; } -McuTargetDescription parseDescriptionJson(const QByteArray &data) +McuTargetDescription parseDescriptionJson(const QByteArray &data, const Utils::FilePath &sourceFile) { const QJsonDocument document = QJsonDocument::fromJson(data); const QJsonObject target = document.object(); @@ -697,7 +699,8 @@ McuTargetDescription parseDescriptionJson(const QByteArray &data) }); const QString platformName = platform.value("platformName").toString(); - return {qulVersion, + return {sourceFile, + qulVersion, compatVersion, {platform.value("id").toString(), platformName, @@ -759,7 +762,8 @@ McuSdkRepository targetsAndPackages(const McuPackagePtr &qtForMCUsPackage, if (!filePath.isReadableFile()) continue; const McuTargetDescription desc = parseDescriptionJson( - filePath.fileContents().value_or(QByteArray())); + filePath.fileContents().value_or(QByteArray()), + filePath); bool ok = false; const int compatVersion = desc.compatVersion.toInt(&ok); if (!desc.compatVersion.isEmpty() && ok && compatVersion > MAX_COMPATIBILITY_VERSION) { diff --git a/src/plugins/mcusupport/mcusupportsdk.h b/src/plugins/mcusupport/mcusupportsdk.h index fabbee01c0a..c0f572140bb 100644 --- a/src/plugins/mcusupport/mcusupportsdk.h +++ b/src/plugins/mcusupport/mcusupportsdk.h @@ -5,10 +5,7 @@ #include "mcusupport_global.h" #include "settingshandler.h" - -namespace Utils { -class FilePath; -} // namespace Utils +#include namespace McuSupport::Internal { @@ -28,7 +25,7 @@ bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message); McuSdkRepository targetsAndPackages(const McuPackagePtr &qtForMCUsPackage, const SettingsHandler::Ptr &); -McuTargetDescription parseDescriptionJson(const QByteArray &); +McuTargetDescription parseDescriptionJson(const QByteArray &, const Utils::FilePath &sourceFile = Utils::FilePath()); McuSdkRepository targetsFromDescriptions(const QList &, const SettingsHandler::Ptr &, const McuPackagePtr &qtForMCUsPackage, diff --git a/src/plugins/mcusupport/mcusupportversiondetection.cpp b/src/plugins/mcusupport/mcusupportversiondetection.cpp index f99ca115361..4b084d927ab 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.cpp +++ b/src/plugins/mcusupport/mcusupportversiondetection.cpp @@ -80,18 +80,15 @@ QString McuPackageXmlVersionDetector::parseVersion(const FilePath &packagePath) return QString(); } -McuPackageDirectoryVersionDetector::McuPackageDirectoryVersionDetector(const QString &filePattern, - const QString &versionRegExp, - const bool isFile) +McuPackageDirectoryEntriesVersionDetector::McuPackageDirectoryEntriesVersionDetector( + const QString &filePattern, const QString &versionRegExp) : m_filePattern(filePattern) , m_versionRegExp(versionRegExp) - , m_isFile(isFile) {} -QString McuPackageDirectoryVersionDetector::parseVersion(const FilePath &packagePath) const +QString McuPackageDirectoryEntriesVersionDetector::parseVersion(const FilePath &packagePath) const { - const auto files = QDir(packagePath.toString(), m_filePattern) - .entryInfoList(m_isFile ? QDir::Filter::Files : QDir::Filter::Dirs); + const auto files = QDir(packagePath.toString(), m_filePattern).entryInfoList(); for (const auto &entry : files) { const QString matched = matchRegExp(entry.fileName(), m_versionRegExp); if (!matched.isEmpty()) diff --git a/src/plugins/mcusupport/mcusupportversiondetection.h b/src/plugins/mcusupport/mcusupportversiondetection.h index 68480263d83..cfd878b25b6 100644 --- a/src/plugins/mcusupport/mcusupportversiondetection.h +++ b/src/plugins/mcusupport/mcusupportversiondetection.h @@ -49,18 +49,16 @@ private: }; // Get version from the filename of a given file/dir in the package directory -class McuPackageDirectoryVersionDetector : public McuPackageVersionDetector +class McuPackageDirectoryEntriesVersionDetector : public McuPackageVersionDetector { public: - McuPackageDirectoryVersionDetector(const QString &filePattern, - const QString &versionRegExp, - const bool isFile); + McuPackageDirectoryEntriesVersionDetector(const QString &filePattern, + const QString &versionRegExp); QString parseVersion(const Utils::FilePath &packagePath) const final; private: const QString m_filePattern; const QString m_versionRegExp; - const bool m_isFile; }; // Get version from the path of the package itself diff --git a/src/plugins/mcusupport/mcutargetdescription.h b/src/plugins/mcusupport/mcutargetdescription.h index 7a905accafc..3c8600b6604 100644 --- a/src/plugins/mcusupport/mcutargetdescription.h +++ b/src/plugins/mcusupport/mcutargetdescription.h @@ -18,7 +18,6 @@ struct VersionDetection QString executableArgs; QString xmlElement; QString xmlAttribute; - bool isFile; }; // struct VersionDetection struct PackageDescription @@ -29,7 +28,7 @@ struct PackageDescription QString description; QString setting; Utils::FilePath defaultPath; - Utils::FilePath validationPath; + Utils::FilePath detectionPath; QStringList versions; VersionDetection versionDetection; bool shouldAddToSystemPath; @@ -39,6 +38,7 @@ struct McuTargetDescription { enum class TargetType { MCU, Desktop }; + Utils::FilePath sourceFile; QString qulVersion; QString compatVersion; struct Platform diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index 91229bd2418..ae79aeee359 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -4,6 +4,7 @@ #include "mcutargetfactory.h" #include "mcuhelpers.h" #include "mcupackage.h" +#include "mcusupportplugin.h" #include "mcusupportversiondetection.h" #include "mcutarget.h" #include "mcutargetdescription.h" @@ -16,15 +17,11 @@ namespace McuSupport::Internal { -bool isToolchainDescriptionValid(const McuTargetDescription::Toolchain &t) -{ - return !t.id.isEmpty() && !t.compiler.cmakeVar.isEmpty() && !t.file.cmakeVar.isEmpty(); -} - bool isDesktopToolchain(McuToolChainPackage::ToolChainType type) { return type == McuToolChainPackage::ToolChainType::MSVC - || type == McuToolChainPackage::ToolChainType::GCC; + || type == McuToolChainPackage::ToolChainType::GCC + || type == McuToolChainPackage::ToolChainType::MinGW; } McuPackageVersionDetector *createVersionDetection(const VersionDetection &versionDetection) @@ -39,10 +36,16 @@ McuPackageVersionDetector *createVersionDetection(const VersionDetection &versio versionDetection.filePattern), QStringList{versionDetection.executableArgs}, versionDetection.regex}; - else - return new McuPackageDirectoryVersionDetector(versionDetection.filePattern, - versionDetection.regex, - versionDetection.isFile); + else if (!versionDetection.filePattern.isEmpty() && !versionDetection.regex.isEmpty()) + return new McuPackageDirectoryEntriesVersionDetector(versionDetection.filePattern, + versionDetection.regex); + else if (!versionDetection.regex.isEmpty()) + return new McuPackagePathVersionDetector(versionDetection.regex); + else { + // In this case the JSON entry is either invalid or missing. + // After refactoring, this should raise a JSON error to the user. + return nullptr; + } } static void removeEmptyPackages(Packages &packages) @@ -53,7 +56,7 @@ static void removeEmptyPackages(Packages &packages) } } -static void expandVariables(Packages &packages) +void McuTargetFactory::expandVariables(Packages &packages) { Utils::MacroExpander macroExpander; for (const auto &package : packages) { @@ -79,7 +82,7 @@ QPair McuTargetFactory::createTargets(const McuTargetDescript const McuTarget::Platform platform( {desc.platform.id, desc.platform.name, desc.platform.vendor}); - auto *toolchain = createToolchain(desc.toolchain); + auto *toolchain = createToolchain(desc.toolchain, desc.sourceFile); McuPackagePtr toolchainFile{createPackage(desc.toolchain.file)}; //Skip target with incorrect toolchain dir or toolchain file. if (!toolchain || !toolchainFile) @@ -134,7 +137,7 @@ McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) return McuPackagePtr{new McuPackage{settingsHandler, pkgDesc.label, pkgDesc.defaultPath, - pkgDesc.validationPath, + pkgDesc.detectionPath, pkgDesc.setting, pkgDesc.cmakeVar, pkgDesc.envVar, @@ -145,13 +148,16 @@ McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) } McuToolChainPackage *McuTargetFactory::createToolchain( - const McuTargetDescription::Toolchain &toolchain) + const McuTargetDescription::Toolchain &toolchain, + const Utils::FilePath &sourceFile + ) { const static QMap toolchainTypeMapping{ {"iar", McuToolChainPackage::ToolChainType::IAR}, {"keil", McuToolChainPackage::ToolChainType::KEIL}, {"msvc", McuToolChainPackage::ToolChainType::MSVC}, {"gcc", McuToolChainPackage::ToolChainType::GCC}, + {"mingw", McuToolChainPackage::ToolChainType::MinGW}, {"armgcc", McuToolChainPackage::ToolChainType::ArmGcc}, {"greenhills", McuToolChainPackage::ToolChainType::GHS}, {"arm-greenhills", McuToolChainPackage::ToolChainType::GHSArm}, @@ -166,20 +172,47 @@ McuToolChainPackage *McuTargetFactory::createToolchain( return new McuToolChainPackage{settingsHandler, compilerDescription.label, compilerDescription.defaultPath, - compilerDescription.validationPath, + compilerDescription.detectionPath, {}, toolchainType, toolchain.versions, compilerDescription.cmakeVar, {}, createVersionDetection(compilerDescription.versionDetection)}; - } else if (!isToolchainDescriptionValid(toolchain)) + } + + // Validate toolchain and provide a proper error message + QString errorMessage; + + if (toolchain.id.isEmpty()) { + errorMessage = McuPackage::tr("the toolchain.id JSON entry is empty"); + } else if (!toolchainTypeMapping.contains(toolchain.id)) { + errorMessage = McuPackage::tr("the given toolchain \"%1\" is not supported").arg(toolchain.id); + } else if (toolchain.compiler.cmakeVar.isEmpty()) { + errorMessage = McuPackage::tr("the toolchain.compiler.cmakeVar JSON entry is empty"); + } else if (toolchain.file.cmakeVar.isEmpty()) { + errorMessage = McuPackage::tr("the toolchain.file.cmakeVar JSON entry is empty"); + } + + if (!errorMessage.isEmpty()) { toolchainType = McuToolChainPackage::ToolChainType::Unsupported; + if (toolchain.id.isEmpty()) { + printMessage(McuPackage::tr("Toolchain is invalid because %2 in file \"%3\".") + .arg(errorMessage).arg(sourceFile.toUserOutput()), + true); + } else { + printMessage(McuPackage::tr("Toolchain description for \"%1\" is invalid because %2 in file \"%3\".") + .arg(toolchain.id).arg(errorMessage).arg(sourceFile.toUserOutput()), + true); + } + + } + return new McuToolChainPackage{settingsHandler, compilerDescription.label, compilerDescription.defaultPath, - compilerDescription.validationPath, + compilerDescription.detectionPath, compilerDescription.setting, toolchainType, toolchain.versions, diff --git a/src/plugins/mcusupport/mcutargetfactory.h b/src/plugins/mcusupport/mcutargetfactory.h index 16d09acef56..bb18ea40a39 100644 --- a/src/plugins/mcusupport/mcutargetfactory.h +++ b/src/plugins/mcusupport/mcutargetfactory.h @@ -20,8 +20,9 @@ public: QPair createTargets(const McuTargetDescription &, const McuPackagePtr &qtForMCUsPackage) override; Packages createPackages(const McuTargetDescription &); - McuToolChainPackage *createToolchain(const McuTargetDescription::Toolchain &); + McuToolChainPackage *createToolchain(const McuTargetDescription::Toolchain &, const Utils::FilePath &sourceFile = Utils::FilePath()); McuPackagePtr createPackage(const PackageDescription &); + static void expandVariables(Packages &packages); private: SettingsHandler::Ptr settingsHandler; diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index 92b3c733dab..84e29625de0 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -21,8 +21,8 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "label": "Path to SEGGER J-Link", "type": "path", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/SEGGER/JLink", - "unix": "/opt/SEGGER/JLink" + "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", + "linux": "/opt/SEGGER/JLink" }, "optional": true, "addToSystemPath": true @@ -46,6 +46,10 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h index e347828d093..738cba2f67f 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h @@ -21,8 +21,8 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "label": "Path to SEGGER J-Link", "type": "path", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/SEGGER/JLink", - "unix": "/opt/SEGGER/JLink" + "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", + "linux": "/opt/SEGGER/JLink" }, "optional": true, "addToSystemPath": true @@ -46,6 +46,10 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { @@ -74,7 +78,7 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "label": "FreeRTOS SDK for EK-RA6M3G", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{Qul_ROOT}/platform/boards/renesas/ek-ra6m3g-common/3rdparty/freertos", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "optional": false } diff --git a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h index 0e1bc9ca461..a72af967c6e 100644 --- a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h @@ -31,6 +31,10 @@ constexpr auto armgcc_example_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h index a6a6fc2f796..21e154cbde1 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h @@ -22,10 +22,11 @@ constexpr auto armgcc_mimxrt1050_evk_baremetal_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -49,6 +50,10 @@ constexpr auto armgcc_mimxrt1050_evk_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h index 1d3eb8eeb23..b366a3f0167 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto armgcc_mimxrt1050_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -49,6 +50,10 @@ constexpr auto armgcc_mimxrt1050_evk_freertos_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { @@ -80,7 +85,7 @@ constexpr auto armgcc_mimxrt1050_evk_freertos_json = R"( "freeRTOS": { "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "envVar": "IMXRT1050_FREERTOS_DIR", "label": "FreeRTOS SDK for MIMXRT1050-EVK", "optional": false, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h index f8a164cdf33..efe74d094e7 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h @@ -21,7 +21,11 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "cmakeVar": "MCUXPRESSO_IDE_PATH", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" + }, + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -45,6 +49,10 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h index 21d760fb13e..e8c71e5292d 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h @@ -22,10 +22,11 @@ constexpr auto armgcc_mimxrt1064_evk_baremetal_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -49,6 +50,10 @@ constexpr auto armgcc_mimxrt1064_evk_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h index e0b6ae8db10..138a7a56eb7 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto armgcc_mimxrt1064_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -49,6 +50,10 @@ constexpr auto armgcc_mimxrt1064_evk_freertos_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { @@ -80,7 +85,7 @@ constexpr auto armgcc_mimxrt1064_evk_freertos_json = R"( "freeRTOS": { "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "envVar": "IMXRT1064_FREERTOS_DIR", "label": "FreeRTOS SDK for MIMXRT1064-EVK", "optional": false, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h index 23407137161..5aab5105bcb 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -49,6 +50,10 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { @@ -81,7 +86,7 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "envVar": "EVK_MIMXRT1170_FREERTOS_PATH", "label": "FreeRTOS SDK for MIMXRT1170-EVK", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "optional": false } diff --git a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h index 27f8a85d96d..d67026d9fef 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -45,6 +49,10 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h index 405c25f934a..c6464c10a75 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -45,6 +49,10 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h index c061bd19e8b..34da0c65a43 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h @@ -20,8 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -45,6 +49,10 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { @@ -78,7 +86,7 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "label": "FreeRTOS SDK for STM32F769I-Discovery", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/Middlewares/Third_Party/FreeRTOS/Source", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "setting": "FreeRTOSSourcePackage_STM32F7", "optional": false diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h index 66af227d7b0..99aa4cede3f 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -45,6 +49,10 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"( "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" } }, "file": { diff --git a/src/plugins/mcusupport/test/errors_json.h b/src/plugins/mcusupport/test/errors_json.h index 9ab54ed68a7..92f3dc21b7e 100644 --- a/src/plugins/mcusupport/test/errors_json.h +++ b/src/plugins/mcusupport/test/errors_json.h @@ -90,8 +90,8 @@ constexpr auto mulitple_toolchain_versions = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" }, "optional": false } diff --git a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h index 40127e894f0..2b10ac19b1d 100644 --- a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h @@ -22,8 +22,12 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"( "setting": "RenesasFlashProgrammer", "cmakeVar": "RENESAS_FLASH_PROGRAMMER_PATH", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/Renesas Electronics/Programming Tools/Renesas Flash Programmer V3.09", - "unix": "%{Env:HOME}" + "windows": "%{Env:PROGRAMFILES}/Renesas Electronics/Programming Tools/Renesas Flash Programmer V3.09", + "linux": "%{Env:HOME}" + }, + "detectionPath": { + "windows": "rfp-cli.exe", + "linux": "rfp-cli" }, "envVar": "RENESAS_FLASH_PROGRAMMER_PATH", "optional": true, @@ -62,9 +66,7 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"( "type": "path", "defaultValue": "/Renesas_Electronics/D1x_RGL/rgl_ghs_D1Mx_obj_V.2.0.0a", "versionDetection": { - "filePattern": "rgl_*_obj_*", - "regex": "\\d+\\.\\d+\\.\\w+", - "isFile": false + "regex": "\\d+\\.\\d+\\.\\w+" }, "optional": false } diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h index 3df8455c07d..579e04908dd 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h @@ -21,8 +21,8 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "label": "Path to SEGGER J-Link", "type": "path", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/SEGGER/JLink", - "unix": "/opt/SEGGER/JLink" + "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", + "linux": "/opt/SEGGER/JLink" }, "optional": true, "addToSystemPath": true @@ -45,7 +45,12 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h index 570259672cf..70e49c8c37d 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h @@ -21,8 +21,8 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "label": "Path to SEGGER J-Link", "type": "path", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/SEGGER/JLink", - "unix": "/opt/SEGGER/JLink" + "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", + "linux": "/opt/SEGGER/JLink" }, "optional": true, "addToSystemPath": true @@ -45,7 +45,12 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -73,7 +78,7 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "label": "FreeRTOS SDK for EK-RA6M3G", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{Qul_ROOT}/platform/boards/renesas/ek-ra6m3g-common/3rdparty/freertos", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "optional": false } diff --git a/src/plugins/mcusupport/test/iar_example_baremetal_json.h b/src/plugins/mcusupport/test/iar_example_baremetal_json.h index ca73ea8b422..66e6abde63c 100644 --- a/src/plugins/mcusupport/test/iar_example_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_example_baremetal_json.h @@ -30,7 +30,12 @@ constexpr auto iar_example_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h index 9903abd6c84..5fe5a089842 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1050_evk_baremetal_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1050_evk_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h index c5c0cee2d4c..93d23e305a2 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1050_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1050_evk_freertos_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -79,7 +85,7 @@ constexpr auto iar_mimxrt1050_evk_freertos_json = R"( "freeRTOS": { "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "envVar": "IMXRT1050_FREERTOS_DIR", "label": "FreeRTOS SDK for MIMXRT1050-EVK", "optional": false, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h index 5ad87a16c56..6600150f5d6 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1060_evk_baremetal_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1060_evk_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h index 634d3b92505..83d3c23b1a9 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1064_evk_baremetal_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1064_evk_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h index 8a223c2a6db..2f71e359048 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1064_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1064_evk_freertos_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -79,7 +85,7 @@ constexpr auto iar_mimxrt1064_evk_freertos_json = R"( "freeRTOS": { "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "envVar": "IMXRT1064_FREERTOS_DIR", "label": "FreeRTOS SDK for MIMXRT1064-EVK", "optional": false, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h index c77aa9c3f32..4143e88cd65 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h @@ -22,10 +22,11 @@ constexpr auto iar_mimxrt1170_evk_freertos_json = R"( "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", - "unix": "/usr/local/mcuxpressoide/" + "linux": "/usr/local/mcuxpressoide/" }, - "versionDetection": { - "filePattern": "ide/binaries/crt_emu_cm_redlink" + "detectionPath": { + "windows": "ide/binaries/crt_emu_cm_redlink.exe", + "linux": "ide/binaries/crt_emu_cm_redlink" }, "optional": false, "addToSystemPath": true @@ -48,7 +49,12 @@ constexpr auto iar_mimxrt1170_evk_freertos_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -80,7 +86,7 @@ constexpr auto iar_mimxrt1170_evk_freertos_json = R"( "envVar": "EVK_MIMXRT1170_FREERTOS_PATH", "label": "FreeRTOS SDK for MIMXRT1170-EVK", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "optional": false } diff --git a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h index 6b1edf70b0d..793097d5f6a 100644 --- a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto iar_stm32f469i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -44,7 +48,12 @@ constexpr auto iar_stm32f469i_discovery_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h index 8ff4c748cde..47df7469ab5 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto iar_stm32f769i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -44,7 +48,12 @@ constexpr auto iar_stm32f769i_discovery_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h index 2817aed3a0d..71181fdca5b 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h @@ -20,8 +20,12 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -44,7 +48,12 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", @@ -77,7 +86,7 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"( "label": "FreeRTOS SDK for STM32F769I-Discovery", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{QUL_BOARD_SDK_DIR}/Middlewares/Third_Party/FreeRTOS/Source", - "validation": "tasks.c", + "detectionPath": "tasks.c", "type": "path", "setting": "FreeRTOSSourcePackage_STM32F7", "optional": false diff --git a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h index 836cdde05d0..9c657ab8cc6 100644 --- a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h @@ -20,8 +20,12 @@ constexpr auto iar_stm32h750b_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMSANDFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "unix": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + }, + "detectionPath": { + "windows": "bin/STM32_Programmer_CLI.exe", + "linux": "bin/STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true @@ -44,7 +48,12 @@ constexpr auto iar_stm32h750b_discovery_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h index 2b5ec845bf4..0e4d7442dfb 100644 --- a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h @@ -40,7 +40,9 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "filePattern": "bin/iccarm", "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": "bin/iccarm.exe", + "optional": false }, "file": { "id": "IAR_CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/mingw_desktop_json.h b/src/plugins/mcusupport/test/mingw_desktop_json.h new file mode 100644 index 00000000000..c8c94a4cdc8 --- /dev/null +++ b/src/plugins/mcusupport/test/mingw_desktop_json.h @@ -0,0 +1,29 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +constexpr auto mingw_desktop_json = R"( +{ + "qulVersion": "2.3.0", + "compatVersion": "1", + "platform": { + "id": "Qt", + "platformName": "Desktop", + "vendor": "Qt", + "colorDepths": [ + 32 + ] + }, + "toolchain": { + "id": "mingw", + "versions": [ + "11.2.0" + ], + "compiler": { + "label": "MinGW Toolchain", + "defaultValue": "%{QT_TOOLS_DIR}/mingw1120_64" + } + } +} +)"; diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 016b9eb7805..30c0808e077 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -16,6 +16,7 @@ #include "iar_mimxrt1064_evk_freertos_json.h" #include "iar_stm32f469i_discovery_baremetal_json.h" #include "msvc_desktop_json.h" +#include "mingw_desktop_json.h" #include "mcuhelpers.h" #include "mcukitmanager.h" @@ -131,18 +132,21 @@ const char xpressoIdeLabel[]{"MCUXpresso IDE"}; const char xpressoIdeSetting[]{"MCUXpressoIDE"}; const char xpressoIdeCmakeVar[]{"MCUXPRESSO_IDE_PATH"}; const char xpressoIdeEnvVar[]{"MCUXpressoIDE_PATH"}; -const char xpressoIdeDetectionPath[]{"ide/binaries/crt_emu_cm_redlink"}; +const QString xpressoIdeDetectionPath{ + HostOsInfo::withExecutableSuffix("ide/binaries/crt_emu_cm_redlink")}; const char stmCubeProgrammerSetting[]{"Stm32CubeProgrammer"}; const char stmCubeProgrammerLabel[]{"STM32CubeProgrammer"}; const QString stmCubeProgrammerPath{QString{defaultToolPath} + "/bin"}; -const QString stmCubeProgrammerDetectionPath{"/bin/STM32_Programmer.sh"}; +const QString stmCubeProgrammerDetectionPath{HostOsInfo::isWindowsHost() + ? QString("bin/STM32_Programmer_CLI.exe") + : QString("bin/STM32_Programmer.sh")}; const char renesasProgrammerSetting[]{"RenesasFlashProgrammer"}; const char renesasProgrammerCmakeVar[]{"RENESAS_FLASH_PROGRAMMER_PATH"}; const QString renesasProgrammerEnvVar{renesasProgrammerCmakeVar}; const char renesasProgrammerLabel[]{"Renesas Flash Programmer"}; -const char renesasProgrammerDetectionPath[]{"rfp-cli"}; +const QString renesasProgrammerDetectionPath{HostOsInfo::withExecutableSuffix("rfp-cli")}; const char renesasE2StudioCmakeVar[]{"EK_RA6M3G_E2_PROJECT_PATH"}; const char renesasE2StudioDefaultPath[]{"%{Env:HOME}/e2_studio/workspace"}; @@ -154,7 +158,7 @@ const char cypressProgrammerSetting[]{"CypressAutoFlashUtil"}; const char cypressProgrammerCmakeVar[]{"INFINEON_AUTO_FLASH_UTILITY_DIR"}; const char cypressProgrammerEnvVar[]{"CYPRESS_AUTO_FLASH_UTILITY_DIR"}; const char cypressProgrammerLabel[]{"Cypress Auto Flash Utility"}; -const char cypressProgrammerDetectionPath[]{"/bin/openocd"}; +const QString cypressProgrammerDetectionPath{HostOsInfo::withExecutableSuffix("/bin/openocd")}; const char jlinkPath[]{"/opt/SEGGER/JLink"}; const char jlinkSetting[]{"JLinkPath"}; @@ -260,6 +264,17 @@ void verifyMsvcToolchain(const McuToolChainPackagePtr &msvcPackage, const QStrin QVERIFY(allOf(versions, [&](const QString &v) { return msvcPackage->versions().contains(v); })); } +void verifyMingwToolchain(const McuToolChainPackagePtr &mingwPackage, const QStringList &versions) +{ + QVERIFY(mingwPackage != nullptr); + QCOMPARE(mingwPackage->cmakeVariableName(), ""); + QCOMPARE(mingwPackage->environmentVariableName(), ""); + QCOMPARE(mingwPackage->toolchainType(), McuToolChainPackage::ToolChainType::MinGW); + QCOMPARE(mingwPackage->isDesktopToolchain(), true); + QCOMPARE(mingwPackage->toolChainName(), "mingw"); + QVERIFY(allOf(versions, [&](const QString &v) { return mingwPackage->versions().contains(v); })); +} + void verifyTargetToolchains(const Targets &targets, const QString &toolchainFilePath, const QString &toolchainFileDefaultPath, @@ -340,6 +355,7 @@ McuSupportTest::McuSupportTest() , compilerDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} , toochainFileDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} , targetDescription { + "autotest-sourceFile", "2.0.1", "2", platformDescription, @@ -551,6 +567,13 @@ void McuSupportTest::test_createDesktopMsvcToolchain() verifyMsvcToolchain(msvcPackage, {}); } +void McuSupportTest::test_createDesktopMingwToolchain() +{ + const auto description = parseDescriptionJson(mingw_desktop_json); + McuToolChainPackagePtr mingwPackage{targetFactory.createToolchain(description.toolchain)}; + verifyMingwToolchain(mingwPackage, {"11.2.0"}); +} + void McuSupportTest::test_verifyManuallyCreatedArmGccToolchain() { verifyArmGccToolchain(armGccToolchainPackagePtr, {armGccVersion}); @@ -1334,15 +1357,13 @@ void McuSupportTest::test_passDirectoryVersionDetectorToRenesasBoardSdkPackage() { const McuTargetDescription description = parseDescriptionJson(ghs_rh850_d1m1a_baremetal_json); - QCOMPARE(description.boardSdk.versionDetection.filePattern, "rgl_*_obj_*"); QCOMPARE(description.boardSdk.versionDetection.regex, R"(\d+\.\d+\.\w+)"); - QCOMPARE(description.boardSdk.versionDetection.isFile, false); McuPackagePtr boardSdk{targetFactory.createPackage(description.boardSdk)}; const auto *versionDetector{boardSdk->getVersionDetector()}; QVERIFY(versionDetector != nullptr); - QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackageDirectoryVersionDetector).name()); + QCOMPARE(typeid(*versionDetector).name(), typeid(McuPackagePathVersionDetector).name()); } void McuSupportTest::test_resolveEnvironmentVariablesInDefaultPath() @@ -1507,6 +1528,7 @@ void McuSupportTest::test_createThirdPartyPackage() QFETCH(QString, cmakeVar); QFETCH(QString, envVar); QFETCH(QString, label); + QFETCH(QString, detectionPath); McuTargetDescription targetDescription{parseDescriptionJson(json.toLocal8Bit())}; @@ -1524,7 +1546,15 @@ void McuSupportTest::test_createThirdPartyPackage() return (pkg->settingsKey() == setting); }); - verifyPackage(thirdPartyPackage, path, defaultPath, setting, cmakeVar, envVar, label, {}, {}); + verifyPackage(thirdPartyPackage, + path, + defaultPath, + setting, + cmakeVar, + envVar, + label, + detectionPath, + {}); } void McuSupportTest::test_legacy_createCypressProgrammer3rdPartyPackage() @@ -1574,15 +1604,20 @@ void McuSupportTest::test_createJLink3rdPartyPackage() {}); } -void McuSupportTest::test_defaultValueForEachOperationSystem() +void McuSupportTest::test_differentValueForEachOperationSystem() { const auto packageDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); auto default_path_entry = packageDescription.platform.entries[0].defaultPath.toString(); + auto validation_path_entry = packageDescription.platform.entries[0].detectionPath.toString(); - if (HostOsInfo::isWindowsHost()) + //TODO: Revisit whether this test is required and not currently covered by the third party packages + if (HostOsInfo::isWindowsHost()) { QCOMPARE(QString("%{Env:ROOT}/nxp/MCUXpressoIDE*"), default_path_entry); - else + QCOMPARE(QString("ide/binaries/crt_emu_cm_redlink.exe"), validation_path_entry); + } else { QCOMPARE(QString("/usr/local/mcuxpressoide"), default_path_entry); + QCOMPARE(QString("ide/binaries/crt_emu_cm_redlink"), validation_path_entry); + } }; void McuSupportTest::test_addToSystemPathFlag() { @@ -1601,4 +1636,68 @@ void McuSupportTest::test_addToSystemPathFlag() QCOMPARE(freeRtosPackage.shouldAddToSystemPath, false); } +void McuSupportTest::test_nonemptyVersionDetector() +{ + PackageDescription pkgDesc; + pkgDesc.label = "GNU Arm Embedded Toolchain"; + pkgDesc.envVar = "ARMGCC_DIR"; + // pkgDesc.cmakeVar left empty + // pkgDesc.description left empty + pkgDesc.setting = "GNUArmEmbeddedToolchain"; + // pkgDesc.defaultPath left empty + // pkgDesc.validationPath left empty + // pkgDesc.versions left empty + pkgDesc.versionDetection.filePattern = "bin/arm-none-eabi-g++"; + pkgDesc.versionDetection.regex = "\\bv?(\\d+\\.\\d+\\.\\d+)\\b"; + pkgDesc.versionDetection.executableArgs = "--version"; + // pkgDesc.versionDetection.xmlElement left empty + // pkgDesc.versionDetection.xmlAttribute left empty + pkgDesc.shouldAddToSystemPath = false; + + const auto package = targetFactory.createPackage(pkgDesc); + QVERIFY(package->getVersionDetector() != nullptr); + QCOMPARE(typeid(*package->getVersionDetector()).name(), + typeid(McuPackageExecutableVersionDetector).name()); +} + +void McuSupportTest::test_emptyVersionDetector() +{ + PackageDescription pkgDesc; + pkgDesc.label = "GNU Arm Embedded Toolchain"; + pkgDesc.envVar = "ARMGCC_DIR"; + // pkgDesc.cmakeVar left empty + // pkgDesc.description left empty + pkgDesc.setting = "GNUArmEmbeddedToolchain"; + // pkgDesc.defaultPath left empty + // pkgDesc.validationPath left empty + // pkgDesc.versions left empty + // Version detection left completely empty + // pkgDesc.versionDetection.filePattern + // pkgDesc.versionDetection.regex + // pkgDesc.versionDetection.executableArgs + // pkgDesc.versionDetection.xmlElement + // pkgDesc.versionDetection.xmlAttribute + pkgDesc.shouldAddToSystemPath = false; + + const auto package = targetFactory.createPackage(pkgDesc); + QVERIFY(package->getVersionDetector() == nullptr); +} + +void McuSupportTest::test_emptyVersionDetectorFromJson() +{ + const auto targetDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); + auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + + auto freeRtos = findOrDefault(packages, [](const McuPackagePtr &pkg) { + return (pkg->cmakeVariableName() == freeRtosCMakeVar); + }); + + QVERIFY2(!freeRtos->cmakeVariableName().isEmpty(), "The freeRTOS package was not found, but there should be one."); + + // For the FreeRTOS package there used to be no version check defined. Use this package to check if this was + // considered correctly + QVERIFY(freeRtos->getVersionDetector() == nullptr); +} + + } // namespace McuSupport::Internal::Test diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 1752f52f1be..50e823d10b2 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -51,6 +51,7 @@ private slots: void test_createDesktopGccToolchain(); void test_legacy_createDesktopMsvcToolchain(); void test_createDesktopMsvcToolchain(); + void test_createDesktopMingwToolchain(); void test_verifyManuallyCreatedArmGccToolchain(); void test_legacy_createArmGccToolchain(); void test_createArmGccToolchain_data(); @@ -99,9 +100,13 @@ private slots: void test_legacy_createCypressProgrammer3rdPartyPackage(); void test_createJLink3rdPartyPackage(); - void test_defaultValueForEachOperationSystem(); + void test_differentValueForEachOperationSystem(); void test_addToSystemPathFlag(); + void test_nonemptyVersionDetector(); + void test_emptyVersionDetector(); + void test_emptyVersionDetectorFromJson(); + private: QVersionNumber currentQulVersion{2, 0}; PackageMock *freeRtosPackage{new PackageMock}; diff --git a/src/plugins/perfprofiler/perfprofilertracefile.cpp b/src/plugins/perfprofiler/perfprofilertracefile.cpp index 5d35a9cc10f..ca9304fd443 100644 --- a/src/plugins/perfprofiler/perfprofilertracefile.cpp +++ b/src/plugins/perfprofiler/perfprofilertracefile.cpp @@ -247,7 +247,7 @@ void PerfProfilerTraceFile::readFromDevice() } else if (strncmp(magic.data(), Constants::PerfZqfileMagic, magicSize) == 0) { m_compressed = true; } else { - fail(Tr::tr("Invalid data format. The trace file's identification string is \"%1\"." + fail(Tr::tr("Invalid data format. The trace file's identification string is \"%1\". " "An acceptable trace file should have \"%2\". You cannot read trace files " "generated with older versions of %3.") .arg(QString::fromLatin1(magic)) diff --git a/src/plugins/projectexplorer/buildaspects.cpp b/src/plugins/projectexplorer/buildaspects.cpp index 02cc62b69e2..919bd837e6f 100644 --- a/src/plugins/projectexplorer/buildaspects.cpp +++ b/src/plugins/projectexplorer/buildaspects.cpp @@ -5,7 +5,11 @@ #include "buildconfiguration.h" #include "buildpropertiessettings.h" +#include "devicesupport/idevice.h" +#include "kitinformation.h" +#include "projectexplorerconstants.h" #include "projectexplorer.h" +#include "target.h" #include @@ -24,13 +28,17 @@ namespace ProjectExplorer { class BuildDirectoryAspect::Private { public: + Private(Target *target) : target(target) {} + FilePath sourceDir; + Target * const target; FilePath savedShadowBuildDir; QString problem; QPointer problemLabel; }; -BuildDirectoryAspect::BuildDirectoryAspect(const BuildConfiguration *bc) : d(new Private) +BuildDirectoryAspect::BuildDirectoryAspect(const BuildConfiguration *bc) + : d(new Private(bc->target())) { setSettingsKey("ProjectExplorer.BuildConfiguration.BuildDirectory"); setLabelText(tr("Build directory:")); @@ -40,6 +48,16 @@ BuildDirectoryAspect::BuildDirectoryAspect(const BuildConfiguration *bc) : d(new const FilePath fixedDir = fixupDir(FilePath::fromUserInput(edit->text())); if (!fixedDir.isEmpty()) edit->setText(fixedDir.toUserOutput()); + + const FilePath newPath = FilePath::fromUserInput(edit->text()); + const auto buildDevice = DeviceKitAspect::device(d->target->kit()); + + if (buildDevice && buildDevice->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE + && !buildDevice->rootPath().ensureReachable(newPath)) { + *error = tr("The build directory is not reachable from the build device."); + return false; + } + return pathChooser() ? pathChooser()->defaultValidationFunction()(edit, error) : true; }); setOpenTerminalHandler([this, bc] { @@ -109,6 +127,12 @@ void BuildDirectoryAspect::addToLayout(LayoutBuilder &builder) } }); } + + const auto buildDevice = DeviceKitAspect::device(d->target->kit()); + if (buildDevice && buildDevice->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) + pathChooser()->setAllowPathFromDevice(true); + else + pathChooser()->setAllowPathFromDevice(false); } FilePath BuildDirectoryAspect::fixupDir(const FilePath &dir) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 41ec7c6b92b..89a172aae65 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1964,7 +1964,8 @@ Toolchains MingwToolChainFactory::detectForImport(const ToolChainDescription &tc const QString fileName = tcd.compilerPath.completeBaseName(); const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID - && (fileName.startsWith("gcc") || fileName.endsWith("gcc")); + && ((fileName.startsWith("gcc") || fileName.endsWith("gcc")) + || fileName == "cc"); const bool cxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID && ((fileName.startsWith("g++") || fileName.endsWith("g++")) diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp index 1fbf1c21255..56cce46ec73 100644 --- a/src/plugins/projectexplorer/makestep.cpp +++ b/src/plugins/projectexplorer/makestep.cpp @@ -75,7 +75,7 @@ MakeStep::MakeStep(BuildStepList *parent, Id id) m_overrideMakeflagsAspect->setLabel(text, BoolAspect::LabelPlacement::AtCheckBox); m_nonOverrideWarning = addAspect(); - m_nonOverrideWarning->setToolTip("

    " + + m_nonOverrideWarning->setText("

    " + tr("MAKEFLAGS specifies parallel jobs. Check \"%1\" to override.") .arg(text) + "

    "); m_nonOverrideWarning->setIconType(InfoLabel::Warning); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index a77b24bc059..8a598c2624a 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -2085,23 +2085,21 @@ std::optional MsvcToolChain::generateEnvironmentSettings(const Utils::E // Create a batch file to create and save the env settings Utils::TempFileSaver saver(Utils::TemporaryDirectory::masterDirectoryPath() + "/XXXXXX.bat"); - auto makeCall = [](const QString &batchFile, const QString &batchArgs) -> QByteArray { - QByteArray call = "call "; - call += ProcessArgs::quoteArg(batchFile).toLocal8Bit(); - if (!batchArgs.isEmpty()) { - call += ' '; - call += batchArgs.toLocal8Bit(); - } - return call; - }; - QByteArray callCleanEnv = makeCall(batchFile, "/clean_env"); - QByteArray call = makeCall(batchFile, batchArgs); + QByteArray call = "call "; + call += ProcessArgs::quoteArg(batchFile).toLocal8Bit(); + if (!batchArgs.isEmpty()) { + call += ' '; + call += batchArgs.toLocal8Bit(); + } if (Utils::HostOsInfo::isWindowsHost()) saver.write("chcp 65001\r\n"); saver.write("set VSCMD_SKIP_SENDTELEMETRY=1\r\n"); saver.write("set CLINK_NOAUTORUN=1\r\n"); - saver.write(callCleanEnv + "\r\n"); + saver.write("setlocal enableextensions\r\n"); + saver.write("if defined VCINSTALLDIR (\r\n"); + saver.write(" call \"%VCINSTALLDIR%/Auxiliary/Build/vcvarsall.bat\" /clean_env\r\n"); + saver.write(")\r\n"); saver.write(call + "\r\n"); saver.write("@echo " + marker.toLocal8Bit() + "\r\n"); saver.write("set\r\n"); diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp index 5684580d71a..570c44e67b7 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -107,7 +107,6 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) : m_terminalModeComboBox->addItem(tr("Deduced from Project")); m_terminalModeComboBox->setSizePolicy(cbSizePolicy); m_jomCheckbox = new QCheckBox(tr("Use jom instead of nmake")); - m_jomCheckbox->setVisible(HostOsInfo::isWindowsHost()); auto jomLabel = new QLabel("jom is a drop-in replacement for nmake which " "distributes the compilation process to multiple CPU cores. " "The latest binary is available at " @@ -115,7 +114,6 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) : "http://download.qt.io/official_releases/jom/. " "Disable it if you experience problems with your builds."); jomLabel->setWordWrap(true); - jomLabel->setVisible(HostOsInfo::isWindowsHost()); using namespace Utils::Layouting; Column { @@ -155,6 +153,9 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) : st, }.attachTo(this); + m_jomCheckbox->setVisible(HostOsInfo::isWindowsHost()); + jomLabel->setVisible(HostOsInfo::isWindowsHost()); + m_directoryButtonGroup = new QButtonGroup; m_directoryButtonGroup->setExclusive(true); m_directoryButtonGroup->addButton(m_currentDirectoryRadioButton, UseCurrentDirectory); diff --git a/src/plugins/projectexplorer/sessiondialog.cpp b/src/plugins/projectexplorer/sessiondialog.cpp index 285836cab39..568247f7e2c 100644 --- a/src/plugins/projectexplorer/sessiondialog.cpp +++ b/src/plugins/projectexplorer/sessiondialog.cpp @@ -109,17 +109,21 @@ bool SessionNameInputDialog::isSwitchToRequested() const SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent) { + setObjectName("ProjectExplorer.SessionDialog"); resize(550, 400); setWindowTitle(tr("Session Manager")); auto sessionView = new SessionView(this); + sessionView->setObjectName("sessionView"); sessionView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); sessionView->setActivationMode(Utils::DoubleClickActivation); auto createNewButton = new QPushButton(tr("&New")); + createNewButton->setObjectName("btCreateNew"); m_openButton = new QPushButton(tr("&Open")); + m_openButton->setObjectName("btOpen"); m_renameButton = new QPushButton(tr("&Rename")); m_cloneButton = new QPushButton(tr("C&lone")); m_deleteButton = new QPushButton(tr("&Delete")); diff --git a/src/plugins/python/pysidebuildconfiguration.cpp b/src/plugins/python/pysidebuildconfiguration.cpp index 13367f55d9e..6faa194b0bf 100644 --- a/src/plugins/python/pysidebuildconfiguration.cpp +++ b/src/plugins/python/pysidebuildconfiguration.cpp @@ -62,7 +62,9 @@ PySideBuildStep::PySideBuildStep(BuildStepList *bsl, Id id) m_pysideProject->setFilePath(pySideProjectPath); setCommandLineProvider([this] { return CommandLine(m_pysideProject->filePath(), {"build"}); }); - setWorkingDirectoryProvider([this] { return target()->project()->projectDirectory(); }); + setWorkingDirectoryProvider([this] { + return target()->project()->projectDirectory().onDevice(m_pysideProject->filePath()); + }); setEnvironmentModifier([this](Environment &env) { env.prependOrSetPath(m_pysideProject->filePath().parentDir()); }); diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp index 70528b0c997..a255c5ab5c2 100644 --- a/src/plugins/python/pythonproject.cpp +++ b/src/plugins/python/pythonproject.cpp @@ -476,7 +476,7 @@ PythonBuildSystem::PythonBuildSystem(Target *target) : BuildSystem(target) { connect(target->project(), &Project::projectFileIsDirty, this, [this] { triggerParsing(); }); - QTimer::singleShot(0, this, &PythonBuildSystem::triggerParsing); + triggerParsing(); } bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index 7a370f7517e..28937e0813b 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include #include @@ -130,13 +132,23 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Id id) connect(PythonSettings::instance(), &PythonSettings::interpretersChanged, interpreterAspect, &InterpreterAspect::updateInterpreters); - QList interpreters = PythonSettings::detectPythonVenvs( + const QList interpreters = PythonSettings::detectPythonVenvs( project()->projectDirectory()); interpreterAspect->updateInterpreters(PythonSettings::interpreters()); Interpreter defaultInterpreter = interpreters.isEmpty() ? PythonSettings::defaultInterpreter() : interpreters.first(); if (!defaultInterpreter.command.isExecutableFile()) defaultInterpreter = PythonSettings::interpreters().value(0); + if (defaultInterpreter.command.isExecutableFile()) { + const IDeviceConstPtr device = DeviceKitAspect::device(target->kit()); + if (device && !device->handlesFile(defaultInterpreter.command)) { + defaultInterpreter = Utils::findOr(PythonSettings::interpreters(), + defaultInterpreter, + [device](const Interpreter &interpreter) { + return device->handlesFile(interpreter.command); + }); + } + } interpreterAspect->setDefaultInterpreter(defaultInterpreter); auto bufferedAspect = addAspect(); @@ -194,51 +206,56 @@ PythonRunConfiguration::~PythonRunConfiguration() qDeleteAll(m_extraCompilers); } +struct PythonTools +{ + FilePath pySideProjectPath; + FilePath pySideUicPath; +}; + void PythonRunConfiguration::checkForPySide(const FilePath &python) { BuildStepList *buildSteps = target()->activeBuildConfiguration()->buildSteps(); - FilePath pySideProjectPath; - m_pySideUicPath.clear(); - const PipPackage pySide6Package("PySide6"); - const PipPackageInfo info = pySide6Package.info(python); - for (const FilePath &file : std::as_const(info.files)) { - if (file.fileName() == HostOsInfo::withExecutableSuffix("pyside6-project")) { - pySideProjectPath = info.location.resolvePath(file); - pySideProjectPath = pySideProjectPath.cleanPath(); - if (!m_pySideUicPath.isEmpty()) - break; - } else if (file.fileName() == HostOsInfo::withExecutableSuffix("pyside6-uic")) { - m_pySideUicPath = info.location.resolvePath(file); - m_pySideUicPath = m_pySideUicPath.cleanPath(); - if (!pySideProjectPath.isEmpty()) - break; + const auto findPythonTools = [](const FilePaths &files, + const FilePath &location, + const FilePath &python) -> PythonTools { + PythonTools result; + const QString pySide6ProjectName + = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-project"); + const QString pySide6UicName + = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-uic"); + for (const FilePath &file : files) { + if (file.fileName() == pySide6ProjectName) { + result.pySideProjectPath = location.resolvePath(file).onDevice(python); + result.pySideProjectPath = result.pySideProjectPath.cleanPath(); + if (!result.pySideUicPath.isEmpty()) + return result; + } else if (file.fileName() == pySide6UicName) { + result.pySideUicPath = location.resolvePath(file).onDevice(python); + result.pySideUicPath = result.pySideUicPath.cleanPath(); + if (!result.pySideProjectPath.isEmpty()) + return result; + } } + return {}; + }; + + const PipPackage pySide6EssentialPackage("PySide6-Essentials"); + PipPackageInfo info = pySide6EssentialPackage.info(python); + PythonTools pythonTools = findPythonTools(info.files, info.location, python); + if (!pythonTools.pySideProjectPath.isExecutableFile()) { + const PipPackage pySide6Package("PySide6"); + info = pySide6Package.info(python); + pythonTools = findPythonTools(info.files, info.location, python); } - // Workaround that pip might return an incomplete file list on windows - if (HostOsInfo::isWindowsHost() && !python.needsDevice() - && !info.location.isEmpty() && m_pySideUicPath.isEmpty()) { - // Scripts is next to the site-packages install dir for user installations - FilePath scripts = info.location.parentDir().pathAppended("Scripts"); - if (!scripts.exists()) { - // in global/venv installations Scripts is next to Lib/site-packages - scripts = info.location.parentDir().parentDir().pathAppended("Scripts"); - } - auto userInstalledPySideTool = [&](const QString &toolName) { - const FilePath tool = scripts.pathAppended(HostOsInfo::withExecutableSuffix(toolName)); - return tool.isExecutableFile() ? tool : FilePath(); - }; - m_pySideUicPath = userInstalledPySideTool("pyside6-uic"); - if (pySideProjectPath.isEmpty()) - pySideProjectPath = userInstalledPySideTool("pyside6-project"); - } + m_pySideUicPath = pythonTools.pySideUicPath; updateExtraCompilers(); if (auto pySideBuildStep = buildSteps->firstOfType()) - pySideBuildStep->updatePySideProjectPath(pySideProjectPath); + pySideBuildStep->updatePySideProjectPath(pythonTools.pySideProjectPath); } void PythonRunConfiguration::currentInterpreterChanged() diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 2377a8d0e0c..21cbc339e12 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -672,7 +672,7 @@ public: ActionTemplate *removeSignalHandlerAction = new ActionTemplate( (propertyName + "RemoveSignalHandlerId").toLatin1(), - QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove this handler")), + QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove This Handler")), [signalHandler](const SelectionContext &) { signalHandler.parentModelNode().view()->executeInTransaction( "ConnectionsModelNodeActionGroup::" @@ -691,7 +691,7 @@ public: //singular add connection: QMenu *addConnection = new QMenu(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", - "Add signal handler")), + "Add Signal Handler")), menu()); for (const auto &signalStr : signalsList) { @@ -1802,7 +1802,7 @@ void DesignerActionManager::createDefaultDesignerActions() rootCategory, {}, 50, - &mergeWithTemplate, + [&] (const SelectionContext& context) { mergeWithTemplate(context, m_externalDependencies); }, &SelectionContextFunctors::always)); addDesignerAction(new ActionGroup( @@ -1944,8 +1944,9 @@ ActionInterface *DesignerActionManager::actionByMenuId(const QByteArray &id) return nullptr; } -DesignerActionManager::DesignerActionManager(DesignerActionManagerView *designerActionManagerView) +DesignerActionManager::DesignerActionManager(DesignerActionManagerView *designerActionManagerView, ExternalDependenciesInterface &externalDependencies) : m_designerActionManagerView(designerActionManagerView) + , m_externalDependencies(externalDependencies) { } diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h index 416afb86261..099174865fe 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h @@ -81,7 +81,7 @@ private: class QMLDESIGNERCOMPONENTS_EXPORT DesignerActionManager { public: - DesignerActionManager(DesignerActionManagerView *designerActionManagerView); + DesignerActionManager(DesignerActionManagerView *designerActionManagerView, ExternalDependenciesInterface &externalDependencies); ~DesignerActionManager(); void addDesignerAction(ActionInterface *newAction); @@ -127,6 +127,7 @@ private: DesignerActionManagerView *m_designerActionManagerView; QList m_addResourceHandler; QList m_modelNodePreviewImageHandlers; + ExternalDependenciesInterface &m_externalDependencies; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp index 222a425494a..e7390d92955 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp @@ -13,7 +13,7 @@ namespace QmlDesigner { DesignerActionManagerView::DesignerActionManagerView(ExternalDependenciesInterface &externalDependencies) : AbstractView{externalDependencies} - , m_designerActionManager(this) + , m_designerActionManager(this, externalDependencies) , m_isInRewriterTransaction(false) , m_setupContextDirty(false) { diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 7d881145ef6..9d0273c56b1 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1511,78 +1511,14 @@ QString getTemplateDialog(const Utils::FilePath &projectPath) return result; } -void styleMerge(const SelectionContext &selectionContext, const QString &templateFile) -{ - Model *parentModel = selectionContext.view()->model(); - - QTC_ASSERT(parentModel, return); - - auto templateModel(Model::create("QtQuick.Item", 2, 1, parentModel)); - Q_ASSERT(templateModel.get()); - - templateModel->setFileUrl(QUrl::fromLocalFile(templateFile)); - - QPlainTextEdit textEditTemplate; - Utils::FileReader reader; - - QTC_ASSERT(reader.fetch(Utils::FilePath::fromString(templateFile)), return); - QString qmlTemplateString = QString::fromUtf8(reader.data()); - QString imports; - - for (const Import &import : parentModel->imports()) - imports += QStringLiteral("import ") + import.toString(true) + QLatin1Char(';') + QLatin1Char('\n'); - - textEditTemplate.setPlainText(imports + qmlTemplateString); - NotIndentingTextEditModifier textModifierTemplate(&textEditTemplate); - - QScopedPointer templateRewriterView( - new RewriterView(selectionContext.view()->externalDependencies(), RewriterView::Amend)); - templateRewriterView->setTextModifier(&textModifierTemplate); - templateModel->attachView(templateRewriterView.data()); - templateRewriterView->setCheckSemanticErrors(false); - - ModelNode templateRootNode = templateRewriterView->rootModelNode(); - QTC_ASSERT(templateRootNode.isValid(), return); - - auto styleModel(Model::create("QtQuick.Item", 2, 1, parentModel)); - Q_ASSERT(styleModel.get()); - - styleModel->setFileUrl(QUrl::fromLocalFile(templateFile)); - - QPlainTextEdit textEditStyle; - RewriterView *parentRewriterView = selectionContext.view()->model()->rewriterView(); - QTC_ASSERT(parentRewriterView, return); - textEditStyle.setPlainText(parentRewriterView->textModifierContent()); - NotIndentingTextEditModifier textModifierStyle(&textEditStyle); - - QScopedPointer styleRewriterView( - new RewriterView(selectionContext.view()->externalDependencies(), RewriterView::Amend)); - styleRewriterView->setTextModifier(&textModifierStyle); - styleModel->attachView(styleRewriterView.data()); - - StylesheetMerger merger(templateRewriterView.data(), styleRewriterView.data()); - - try { - merger.merge(); - } catch (Exception &e) { - e.showException(); - } - - try { - parentRewriterView->textModifier()->textDocument()->setPlainText(templateRewriterView->textModifierContent()); - } catch (Exception &e) { - e.showException(); - } -} - -void mergeWithTemplate(const SelectionContext &selectionContext) +void mergeWithTemplate(const SelectionContext &selectionContext, ExternalDependenciesInterface &externalDependencies) { const Utils::FilePath projectPath = Utils::FilePath::fromString(baseDirectory(selectionContext.view()->model()->fileUrl())); const QString templateFile = getTemplateDialog(projectPath); if (QFileInfo::exists(templateFile)) - styleMerge(selectionContext, templateFile); + StylesheetMerger::styleMerge(selectionContext.view()->model(), templateFile, externalDependencies); } void removeGroup(const SelectionContext &selectionContext) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index 27a68d55236..6ed4b068d4e 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -68,7 +68,7 @@ void addCustomFlowEffect(const SelectionContext &selectionState); void setFlowStartItem(const SelectionContext &selectionContext); void addToGroupItem(const SelectionContext &selectionContext); void selectFlowEffect(const SelectionContext &selectionContext); -void mergeWithTemplate(const SelectionContext &selectionContext); +void mergeWithTemplate(const SelectionContext &selectionContext, ExternalDependenciesInterface &externalDependencies); void removeGroup(const SelectionContext &selectionContext); void editAnnotation(const SelectionContext &selectionContext); void addMouseAreaFill(const SelectionContext &selectionContext); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 4589594baab..80fd6aa2b16 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -321,7 +321,7 @@ Edit3DAction *Edit3DView::createSelectBackgrounColorAction() QString description = QCoreApplication::translate("SelectBackgroundColorAction", "Select Background Color"); QString tooltip = QCoreApplication::translate("SelectBackgroundColorAction", - "Select a color for the background of the 3D Editor."); + "Select a color for the background of the 3D view."); auto operation = [this](const SelectionContext &) { BackgroundColorSelection::showBackgroundColorSelectionWidget( @@ -348,7 +348,7 @@ Edit3DAction *Edit3DView::createGridColorSelectionAction() { QString description = QCoreApplication::translate("SelectGridColorAction", "Select Grid Color"); QString tooltip = QCoreApplication::translate("SelectGridColorAction", - "Select a color for the grid lines of the 3D Editor."); + "Select a color for the grid lines of the 3D view."); auto operation = [this](const SelectionContext &) { BackgroundColorSelection::showBackgroundColorSelectionWidget( @@ -376,7 +376,7 @@ Edit3DAction *Edit3DView::createResetColorAction() QString description = QCoreApplication::translate("ResetEdit3DColorsAction", "Reset Colors"); QString tooltip = QCoreApplication::translate("ResetEdit3DColorsAction", "Reset the background color and the color of the " - "grid lines of the 3D Editor to the default valus."); + "grid lines of the 3D view to the default values."); auto operation = [&](const SelectionContext &) { QList bgColors = {QRgb(0x222222), QRgb(0x999999)}; @@ -406,7 +406,7 @@ Edit3DAction *Edit3DView::createSyncBackgroundColorAction() QString description = QCoreApplication::translate("SyncEdit3DColorAction", "Use Scene Environment Color"); QString tooltip = QCoreApplication::translate("SyncEdit3DColorAction", - "Sets the 3D Editor to use the Scene Environment " + "Sets the 3D view to use the Scene Environment " "color as background color."); return new Edit3DAction(QmlDesigner::Constants::EDIT3D_EDIT_SYNC_BACKGROUND_COLOR, diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 47692b08ba6..7f62b107ef0 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -142,10 +142,18 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) m_onboardingLabel = new QLabel(this); QString labelText = tr("Your file does not import Qt Quick 3D.

    " - "To create a 3D view, add the QtQuick3D module in the Library view. Or click" - " here " - "to add it immediately.

    " - "To import 3D assets from another tool, click the \"Add New Assets...\" button in the Assets tab of the Library view."); + "To create a 3D view, add the" + " QtQuick3D" + " module in the" + " Components" + " view or click" + " here" + ".

    " + "To import 3D assets, select" + " +" + " in the" + " Assets" + " view."); m_onboardingLabel->setText(labelText.arg(Utils::creatorTheme()->color(Utils::Theme::TextColorLink).name())); m_onboardingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 59471b9a664..dc524d4682a 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -927,7 +927,7 @@ void FormEditorView::checkRootModelNode() if (!rootModelNode().metaInfo().isGraphicalItem() && !Qml3DNode::isValidVisualRoot(rootModelNode())) m_formEditorWidget->showErrorMessageBox( - {DocumentMessage(tr("%1 is not supported as the root element by Form Editor.") + {DocumentMessage(tr("%1 is not supported as the root element by the 2D view.") .arg(rootModelNode().simplifiedTypeName()))}); else m_formEditorWidget->hideErrorMessageBox(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index c3e47eb6f8e..b1b6a69e2aa 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -295,6 +295,7 @@ void MaterialBrowserView::refreshModel(bool updateImages) } } + m_widget->clearSearchFilter(); m_widget->materialBrowserModel()->setMaterials(materials, m_hasQuick3DImport); if (updateImages) { diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index c89ec4581fa..c0d9648f28b 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -117,14 +117,24 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data); mimeData->removeFormat("text/plain"); + if (!m_draggedBundleMaterial) { + m_draggedBundleMaterial = m_bundleMaterialToDrag; + emit draggedBundleMaterialChanged(); + } + emit bundleMaterialDragStarted(m_bundleMaterialToDrag); model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile()); - m_bundleMaterialToDrag = {}; + m_bundleMaterialToDrag = nullptr; } } } else if (event->type() == QMouseEvent::MouseButtonRelease) { m_materialToDrag = {}; - m_bundleMaterialToDrag = {}; + m_bundleMaterialToDrag = nullptr; + + if (m_draggedBundleMaterial) { + m_draggedBundleMaterial = nullptr; + emit draggedBundleMaterialChanged(); + } } return QObject::eventFilter(obj, event); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 925e7bc2602..42739d83c42 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -36,6 +36,7 @@ class PreviewImageProvider; class MaterialBrowserWidget : public QFrame { Q_OBJECT + Q_PROPERTY(BundleMaterial *draggedBundleMaterial MEMBER m_draggedBundleMaterial NOTIFY draggedBundleMaterialChanged) public: MaterialBrowserWidget(MaterialBrowserView *view); @@ -59,6 +60,7 @@ public: signals: void bundleMaterialDragStarted(QmlDesigner::BundleMaterial *bundleMat); + void draggedBundleMaterialChanged(); protected: bool eventFilter(QObject *obj, QEvent *event) override; @@ -80,6 +82,7 @@ private: ModelNode m_materialToDrag; BundleMaterial *m_bundleMaterialToDrag = nullptr; + BundleMaterial *m_draggedBundleMaterial = nullptr; QPoint m_dragStartPoint; }; diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp index 61de509af3d..03586161a32 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp @@ -103,7 +103,7 @@ ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const QStringList &pr return; } m_ui->setupUi(this); - setWindowTitle(tr("Select property")); + setWindowTitle(tr("Select Property")); m_ui->label->setText(tr("Bind to property:")); m_ui->label->setToolTip(tr("Binds this component to the parent's selected property.")); setFixedSize(size()); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 449405fc0c8..1c68168d010 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -235,7 +235,7 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const if (role == Qt::CheckStateRole) return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked; else if (role == Qt::ToolTipRole && !modelNodeForIndex(index).isRootNode()) - return tr("Toggles the visibility of this component in the form editor.\n" + return tr("Toggles the visibility of this component in the 2D view.\n" "This is independent of the visibility property."); } else if (index.column() == ColumnType::Lock) { // lock if (role == Qt::CheckStateRole) diff --git a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp index f0a27f5a980..ee89eebffe6 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp @@ -152,8 +152,8 @@ void DynamicPropertiesProxyModel::createProperty(const QString &name, const QStr const ModelNode modelNode = selectedNodes.constFirst(); if (modelNode.isValid()) { if (modelNode.hasProperty(name.toUtf8())) { - Core::AsynchronousMessageBox::warning(tr("Property already exists"), - tr("Property '%1' already exists") + Core::AsynchronousMessageBox::warning(tr("Property Already Exists"), + tr("Property \"%1\" already exists.") .arg(name)); return; } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index f2adcf4f363..f06dae49388 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -170,10 +170,10 @@ void StatesEditorModel::renameState(int internalNodeId, const QString &newName) if (newName.isEmpty() ||! m_statesEditorView->validStateName(newName)) { QTimer::singleShot(0, [newName]{ Core::AsynchronousMessageBox::warning( - tr("Invalid state name"), + tr("Invalid State Name"), newName.isEmpty() ? tr("The empty string as a name is reserved for the base state.") : - tr("Name already used in another state")); + tr("Name already used in another state.")); }); reset(); } else { diff --git a/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.cpp b/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.cpp index bbe32f3f902..d559aea1ca1 100644 --- a/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.cpp @@ -123,6 +123,7 @@ void PropertyChangesModel::setModelNodeBackend(const QVariant &modelNodeBackend) m_view->registerPropertyChangesModel(this); emit modelNodeBackendChanged(); + emit propertyChangesVisibleChanged(); } void PropertyChangesModel::reset() diff --git a/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.h b/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.h index 6cdfcc105c4..b73d4dad693 100644 --- a/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.h +++ b/src/plugins/qmldesigner/components/stateseditornew/propertychangesmodel.h @@ -42,6 +42,8 @@ class PropertyChangesModel : public QAbstractListModel Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged) + Q_PROPERTY(bool propertyChangesVisible READ propertyChangesVisible NOTIFY + propertyChangesVisibleChanged) enum { Target = Qt::DisplayRole, @@ -70,6 +72,7 @@ public: signals: void modelNodeBackendChanged(); void countChanged(); + void propertyChangesVisibleChanged(); private: QVariant modelNodeBackend() const; diff --git a/src/plugins/qmldesigner/components/stateseditornew/propertymodel.cpp b/src/plugins/qmldesigner/components/stateseditornew/propertymodel.cpp index 64e267fcce6..35dea7cb23a 100644 --- a/src/plugins/qmldesigner/components/stateseditornew/propertymodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditornew/propertymodel.cpp @@ -117,6 +117,7 @@ void PropertyModel::setModelNodeBackend(const QVariant &modelNodeBackend) setupModel(); emit modelNodeBackendChanged(); + emit expandedChanged(); } void PropertyModel::setExplicit(bool value) diff --git a/src/plugins/qmldesigner/components/stateseditornew/propertymodel.h b/src/plugins/qmldesigner/components/stateseditornew/propertymodel.h index b6f695cd165..492b1362c0e 100644 --- a/src/plugins/qmldesigner/components/stateseditornew/propertymodel.h +++ b/src/plugins/qmldesigner/components/stateseditornew/propertymodel.h @@ -39,6 +39,7 @@ class PropertyModel : public QAbstractListModel Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged) + Q_PROPERTY(bool expanded READ expanded NOTIFY expandedChanged) enum { Name = Qt::DisplayRole, Value = Qt::UserRole, Type }; @@ -62,6 +63,7 @@ public: signals: void modelNodeBackendChanged(); + void expandedChanged(); private: QVariant modelNodeBackend() const; diff --git a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp index 96e6140f618..5d3521b1675 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp @@ -129,9 +129,11 @@ EasingCurveDialog::EasingCurveDialog(const QList &frames, QWidget *pa resize(QSize(1421, 918)); } -void EasingCurveDialog::initialize(const QString &curveString) +void EasingCurveDialog::initialize(const PropertyName &propName, const QString &curveString) { EasingCurve curve; + m_easingCurveProperty = propName; + if (curveString.isEmpty()) { QEasingCurve qcurve; qcurve.addCubicBezierSegment(QPointF(0.2, 0.2), QPointF(0.8, 0.8), QPointF(1.0, 1.0)); @@ -150,11 +152,19 @@ void EasingCurveDialog::runDialog(const QList &frames, QWidget *paren EasingCurveDialog dialog(frames, parent); ModelNode current = frames.last(); + PropertyName propName; - if (current.hasBindingProperty("easing.bezierCurve")) - dialog.initialize(current.bindingProperty("easing.bezierCurve").expression()); - else - dialog.initialize(""); + NodeMetaInfo metaInfo = current.metaInfo(); + if (metaInfo.hasProperty("easing")) + propName = "easing.bezierCurve"; + else if (metaInfo.hasProperty("easingCurve")) + propName = "easingCurve.bezierCurve"; + + QString expression; + if (!propName.isEmpty() && current.hasBindingProperty(propName)) + expression = current.bindingProperty(propName).expression(); + + dialog.initialize(propName, expression); dialog.exec(); } @@ -177,7 +187,7 @@ bool EasingCurveDialog::apply() return view->executeInTransaction("EasingCurveDialog::apply", [this](){ auto expression = m_splineEditor->easingCurve().toString(); for (const auto &frame : std::as_const(m_frames)) - frame.bindingProperty("easing.bezierCurve").setExpression(expression); + frame.bindingProperty(m_easingCurveProperty).setExpression(expression); }); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.h b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.h index 413db30b2f9..a9152f4044d 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.h +++ b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.h @@ -27,7 +27,7 @@ class EasingCurveDialog : public QDialog public: EasingCurveDialog(const QList &frames, QWidget *parent = nullptr); - void initialize(const QString &curveString); + void initialize(const PropertyName &propName, const QString &curveString); static void runDialog(const QList &frames, QWidget *parent = nullptr); @@ -58,6 +58,8 @@ private: QLabel *m_label = nullptr; QList m_frames; + + PropertyName m_easingCurveProperty; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h index e4dc67cd5d8..f4e09cf6f5b 100644 --- a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h +++ b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h @@ -26,6 +26,8 @@ class QMLDESIGNERCORE_EXPORT StylesheetMerger public: StylesheetMerger(AbstractView*, AbstractView*); void merge(); + static void styleMerge(Model *model, const QString &templateFile, class ExternalDependenciesInterface &externalDependencies); + private: void preprocessStyleSheet(); bool idExistsInBothModels(const QString& id); diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 7aee5485c14..dfc98048c38 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -785,6 +785,8 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i if (importInfo.type() == ImportType::Library) { m_majorVersion = importInfo.version().majorVersion(); m_minorVersion = importInfo.version().minorVersion(); + } else { + m_isFileComponent = true; } m_qualfiedTypeName = getUnqualifiedName(m_qualfiedTypeName); @@ -793,6 +795,8 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i || importInfo.type() == ImportType::Directory); if (prepandName) m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.'); + + m_qualfiedTypeName.replace("/", "."); } m_objectValue = getObjectValue(); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index d9ce3dbc94f..32cf4173b22 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -697,10 +697,15 @@ void ModelPrivate::setAuxiliaryData(const InternalNodePointer &node, void ModelPrivate::resetModelByRewriter(const QString &description) { - if (rewriterView()) + if (rewriterView()) { rewriterView()->resetToLastCorrectQml(); - throw RewritingException(__LINE__, __FUNCTION__, __FILE__, description.toUtf8(), rewriterView()->textModifierContent()); + throw RewritingException(__LINE__, + __FUNCTION__, + __FILE__, + description.toUtf8(), + rewriterView()->textModifierContent()); + } } void ModelPrivate::attachView(AbstractView *view) diff --git a/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp b/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp index 564bbb64ac7..dd377cc0180 100644 --- a/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp @@ -12,8 +12,14 @@ #include #include #include +#include +#include #include +#include +#include + +#include #include #include @@ -508,4 +514,69 @@ void StylesheetMerger::merge() } } } + +void StylesheetMerger::styleMerge(Model *model, const QString &templateFile, ExternalDependenciesInterface &externalDependencies) +{ + Model *parentModel = model; + + QTC_ASSERT(parentModel, return); + + auto templateModel(Model::create("QtQuick.Item", 2, 1, parentModel)); + Q_ASSERT(templateModel.get()); + + templateModel->setFileUrl(parentModel->fileUrl()); + + QPlainTextEdit textEditTemplate; + Utils::FileReader reader; + + QTC_ASSERT(reader.fetch(Utils::FilePath::fromString(templateFile)), return); + QString qmlTemplateString = QString::fromUtf8(reader.data()); + QString imports; + + for (const Import &import : parentModel->imports()) { + imports += QStringLiteral("import ") + import.toString(true) + QLatin1Char(';') + + QLatin1Char('\n'); + } + + textEditTemplate.setPlainText(imports + qmlTemplateString); + NotIndentingTextEditModifier textModifierTemplate(&textEditTemplate); + + QScopedPointer templateRewriterView(new RewriterView(externalDependencies, RewriterView::Amend)); + templateRewriterView->setTextModifier(&textModifierTemplate); + templateModel->attachView(templateRewriterView.data()); + templateRewriterView->setCheckSemanticErrors(false); + + ModelNode templateRootNode = templateRewriterView->rootModelNode(); + QTC_ASSERT(templateRootNode.isValid(), return); + + auto styleModel(Model::create("QtQuick.Item", 2, 1, parentModel)); + Q_ASSERT(styleModel.get()); + + styleModel->setFileUrl(parentModel->fileUrl()); + + QPlainTextEdit textEditStyle; + RewriterView *parentRewriterView = parentModel->rewriterView(); + QTC_ASSERT(parentRewriterView, return); + textEditStyle.setPlainText(parentRewriterView->textModifierContent()); + NotIndentingTextEditModifier textModifierStyle(&textEditStyle); + + QScopedPointer styleRewriterView(new RewriterView(externalDependencies, RewriterView::Amend)); + styleRewriterView->setTextModifier(&textModifierStyle); + styleModel->attachView(styleRewriterView.data()); + + StylesheetMerger merger(templateRewriterView.data(), styleRewriterView.data()); + + try { + merger.merge(); + } catch (Exception &e) { + e.showException(); + } + + try { + parentRewriterView->textModifier()->textDocument()->setPlainText( + templateRewriterView->textModifierContent()); + } catch (Exception &e) { + e.showException(); + } } +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 3c135e103e4..b1383f7adf4 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -501,7 +501,7 @@ public: if (metaInfo.isValid()) qDebug() << metaInfo.superClasses().front().typeName(); - if (!typeName.startsWith("...") && m_model == m_model->metaInfoProxyModel() + if (!metaInfo.isFileComponent() && m_model == m_model->metaInfoProxyModel() && metaInfo.isValid()) throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "test", "test"); } @@ -1357,6 +1357,7 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, } syncSignalDeclarationProperty(modelProperty, signature, differenceHandler); + modelPropertyNames.remove(astName.toUtf8()); continue; // Done } diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index f9c925479b2..d2c08e6c78f 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -172,7 +172,7 @@ public: QSize{300, 300}, QSize{1000, 1000}, externalDependencies, - ImageCacheCollectorNullImageHandling::DontCaptureNullImage} + ImageCacheCollectorNullImageHandling::CaptureNullImage} , factory{storage, timeStampProvider, collector} , projectStorageData{project} {} @@ -209,6 +209,11 @@ QmlDesignerProjectManager::QmlDesignerProjectManager(ExternalDependenciesInterfa QObject::connect(sessionManager, &::ProjectExplorer::SessionManager::projectRemoved, [&](auto *project) { projectRemoved(project); }); + + QObject::connect(&m_previewTimer, + &QTimer::timeout, + this, + &QmlDesignerProjectManager::generatePreview); } QmlDesignerProjectManager::~QmlDesignerProjectManager() = default; @@ -238,13 +243,7 @@ void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *) if (!m_projectData || !m_projectData->activeTarget) return; - ::QmlProjectManager::QmlBuildSystem *qmlBuildSystem = getQmlBuildSystem( - m_projectData->activeTarget); - - if (qmlBuildSystem) { - m_previewImageCacheData->collector.setTarget(m_projectData->activeTarget); - m_previewImageCacheData->factory.generate(qmlBuildSystem->mainFilePath().toString().toUtf8()); - } + m_previewTimer.start(10000); } void QmlDesignerProjectManager::editorsClosed(const QList<::Core::IEditor *> &) {} @@ -398,6 +397,20 @@ void QmlDesignerProjectManager::aboutToRemoveProject(::ProjectExplorer::Project void QmlDesignerProjectManager::projectRemoved(::ProjectExplorer::Project *) {} +void QmlDesignerProjectManager::generatePreview() +{ + if (!m_projectData || !m_projectData->activeTarget) + return; + + ::QmlProjectManager::QmlBuildSystem *qmlBuildSystem = getQmlBuildSystem( + m_projectData->activeTarget); + + if (qmlBuildSystem) { + m_previewImageCacheData->collector.setTarget(m_projectData->activeTarget); + m_previewImageCacheData->factory.generate(qmlBuildSystem->mainFilePath().toString().toUtf8()); + } +} + QmlDesignerProjectManager::ImageCacheData *QmlDesignerProjectManager::imageCacheData() { std::call_once(imageCacheFlag, [this]() { diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.h b/src/plugins/qmldesigner/qmldesignerprojectmanager.h index 51ffb6755ab..18d50ce46d0 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.h +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -50,6 +51,7 @@ private: void projectAdded(::ProjectExplorer::Project *project); void aboutToRemoveProject(::ProjectExplorer::Project *project); void projectRemoved(::ProjectExplorer::Project *project); + void generatePreview(); ImageCacheData *imageCacheData(); void fileListChanged(); @@ -66,6 +68,7 @@ private: std::unique_ptr m_imageCacheData; std::unique_ptr m_previewImageCacheData; std::unique_ptr m_projectData; + QTimer m_previewTimer; ExternalDependenciesInterface &m_externalDependencies; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui index 004f8a68eb6..2e7c9516554 100644 --- a/src/plugins/qmldesigner/settingspage.ui +++ b/src/plugins/qmldesigner/settingspage.ui @@ -102,7 +102,7 @@ - Enable Smooth Rendering in Form Editor + Enable smooth rendering in the 2D view. @@ -112,7 +112,7 @@ - Smooth Rendering: + Smooth rendering: diff --git a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp index 452488e2ed6..ce1a996f380 100644 --- a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp +++ b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp @@ -54,7 +54,7 @@ QmlMultiLanguageAspect::QmlMultiLanguageAspect(ProjectExplorer::Target *target) { setVisible(isMultilanguagePresent()); setSettingsKey(Constants::USE_MULTILANGUAGE_KEY); - setLabel(tr("Use MultiLanguage in Form Editor."), BoolAspect::LabelPlacement::AtCheckBox); + setLabel(tr("Use MultiLanguage in 2D view"), BoolAspect::LabelPlacement::AtCheckBox); setToolTip(tr("Reads translations from MultiLanguage plugin.")); setDefaultValue(!databaseFilePath().isEmpty()); diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 424af299126..270920968bd 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -217,7 +217,7 @@ void QmlProjectPlugin::openInQDSWithProject(const Utils::FilePath &filePath) Core::AsynchronousMessageBox::warning( tr("Qt Design Studio"), tr("No project file (*.qmlproject) found for Qt Design " - "Studio.\n Qt Design Studio requires a .qmlproject " + "Studio.\nQt Design Studio requires a .qmlproject " "based project to open the .ui.qml file.")); } } @@ -272,7 +272,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) if (QmlProject::isQtDesignStudio()) { Core::ActionContainer *menu = Core::ActionManager::actionContainer( ProjectExplorer::Constants::M_FILECONTEXT); - QAction *mainfileAction = new QAction(tr("Set as main .qml file"), this); + QAction *mainfileAction = new QAction(tr("Set as Main .qml File"), this); mainfileAction->setEnabled(false); connect(mainfileAction, &QAction::triggered, this, []() { @@ -315,7 +315,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) != fileNode->filePath()); }); - QAction *mainUifileAction = new QAction(tr("Set as main .ui.qml file"), this); + QAction *mainUifileAction = new QAction(tr("Set as Main .ui.qml File"), this); mainUifileAction->setEnabled(false); connect(mainUifileAction, &QAction::triggered, this, []() { diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 5b81784f7ae..0734b649c64 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1455,7 +1455,7 @@ private: const FilePath targetDir = target.parentDir(); if (!m_checkedDirectories.contains(targetDir)) { - emit progress(tr("Creating directory: %1") + emit progress(tr("Creating directory: %1\n") .arg(targetDir.toUserOutput())); if (!targetDir.ensureWritableDir()) { result.m_errorString = tr("Failed."); @@ -1466,7 +1466,7 @@ private: m_checkedDirectories.insert(targetDir); } - emit progress(tr("Copying %1/%2: %3 -> %4") + emit progress(tr("Copying %1/%2: %3 -> %4\n") .arg(m_currentIndex).arg(m_fileCount).arg(source.toUserOutput(), target.toUserOutput())); if (!source.copyFile(target)) { result.m_errorString = tr("Failed."); diff --git a/src/plugins/squish/deletesymbolicnamedialog.cpp b/src/plugins/squish/deletesymbolicnamedialog.cpp index 7bb17156b3c..5f54fae7aa2 100644 --- a/src/plugins/squish/deletesymbolicnamedialog.cpp +++ b/src/plugins/squish/deletesymbolicnamedialog.cpp @@ -106,8 +106,8 @@ void DeleteSymbolicNameDialog::updateDetailsLabel(const QString &nameToDelete) { const char *detailsText = QT_TR_NOOP( "The Symbolic Name \"%1\" you " - "want to remove is used in Multi Property Names. Please decide what to do " - "with the references in these Multi Property Names."); + "want to remove is used in Multi Property Names. Select the action to " + "apply to references in these Multi Property Names."); m_detailsLabel->setText(tr(detailsText).arg(nameToDelete)); } diff --git a/src/plugins/studiowelcome/qdsnewdialog.cpp b/src/plugins/studiowelcome/qdsnewdialog.cpp index ce23919cbea..da5224a292d 100644 --- a/src/plugins/studiowelcome/qdsnewdialog.cpp +++ b/src/plugins/studiowelcome/qdsnewdialog.cpp @@ -87,7 +87,7 @@ QdsNewDialog::QdsNewDialog(QWidget *parent) m_dialog->installEventFilter(this); QObject::connect(&m_wizard, &WizardHandler::wizardCreationFailed, this, [this]() { - QMessageBox::critical(m_dialog, tr("New project"), tr("Failed to initialize data")); + QMessageBox::critical(m_dialog, tr("New Project"), tr("Failed to initialize data.")); reject(); delete this; }); diff --git a/src/plugins/texteditor/behaviorsettingswidget.cpp b/src/plugins/texteditor/behaviorsettingswidget.cpp index d6bf371896b..83a843a2193 100644 --- a/src/plugins/texteditor/behaviorsettingswidget.cpp +++ b/src/plugins/texteditor/behaviorsettingswidget.cpp @@ -188,7 +188,7 @@ BehaviorSettingsWidget::BehaviorSettingsWidget(QWidget *parent) Row { Form { - tr("Default encoding: "), d->encodingBox, br, + tr("Default encoding:"), d->encodingBox, br, tr("UTF-8 BOM:"), d->utf8BomBox, br, tr("Default line endings:"), d->defaultLineEndings, br, }, st diff --git a/src/plugins/texteditor/tabsettingswidget.cpp b/src/plugins/texteditor/tabsettingswidget.cpp index 8ab3fb6149d..30c73835f13 100644 --- a/src/plugins/texteditor/tabsettingswidget.cpp +++ b/src/plugins/texteditor/tabsettingswidget.cpp @@ -19,7 +19,7 @@ namespace TextEditor { QString continuationTooltip() { // FIXME: This is unfair towards translators. - return QCoreApplication::translate("TextEditor::Internal::TabSettingsWidget", + return QCoreApplication::translate("TextEditor::TabSettingsWidget", "\n" "Influences the indentation of continuation lines.\n" "\n" diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 4e28d9f1a2d..043405b4df9 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -810,6 +810,7 @@ public: using UndoMultiCursor = QList; QStack m_undoCursorStack; QList m_visualIndentCache; + int m_visualIndentOffset = 0; }; class TextEditorWidgetFind : public BaseTextFind @@ -954,8 +955,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) connect(&m_codeAssistant, &CodeAssistant::finished, q, &TextEditorWidget::assistFinished); - connect(q, &QPlainTextEdit::blockCountChanged, - this, &TextEditorWidgetPrivate::slotUpdateExtraAreaWidth); + connect(q, &QPlainTextEdit::blockCountChanged, this, [this]() { slotUpdateExtraAreaWidth(); }); connect(q, &QPlainTextEdit::modificationChanged, m_extraArea, QOverload<>::of(&QWidget::update)); @@ -1699,6 +1699,11 @@ QString TextEditorWidget::selectedText() const return d->m_cursors.selectedText(); } +void TextEditorWidget::setVisualIndentOffset(int offset) +{ + d->m_visualIndentOffset = qMax(0, offset); +} + void TextEditorWidgetPrivate::updateCannotDecodeInfo() { q->setReadOnly(m_document->hasDecodingError()); @@ -4106,7 +4111,7 @@ void TextEditorWidgetPrivate::paintRightMarginArea(PaintEventData &data, QPainte // Don't use QFontMetricsF::averageCharWidth here, due to it returning // a fractional size even when this is not supported by the platform. data.rightMargin = QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char('x')) - * m_visibleWrapColumn + * (m_visibleWrapColumn + m_visualIndentOffset) + data.offset.x() + 4; if (m_marginSettings.m_tintMarginArea && data.rightMargin < data.viewportRect.width()) { const QRectF behindMargin(data.rightMargin, @@ -4389,7 +4394,7 @@ int TextEditorWidgetPrivate::indentDepthForBlock(const QTextBlock &block) const auto blockDepth = [&](const QTextBlock &block) { int depth = m_visualIndentCache.value(block.blockNumber(), -1); if (depth < 0) { - const QString text = block.text(); + const QString text = block.text().mid(m_visualIndentOffset); depth = text.simplified().isEmpty() ? -1 : tabSettings.indentationColumn(text); } return depth; @@ -4449,18 +4454,19 @@ void TextEditorWidgetPrivate::paintIndentDepth(PaintEventData &data, return; const TabSettings &tabSettings = m_document->tabSettings(); - const qreal horizontalAdvance = QFontMetricsF(q->font()).horizontalAdvance( - QString(tabSettings.m_indentSize, QChar(' '))); + const qreal horizontalAdvance = QFontMetricsF(q->font()).horizontalAdvance(' '); + const qreal fullHorizontalAdvance = horizontalAdvance * tabSettings.m_indentSize; painter.save(); painter.setPen(data.visualWhitespaceFormat.foreground().color()); const QTextLine textLine = blockData.layout->lineAt(0); const QRectF rect = textLine.naturalTextRect(); - qreal x = textLine.cursorToX(0) + data.offset.x() + qMax(0, q->cursorWidth() - 1); + qreal x = textLine.cursorToX(0) + data.offset.x() + qMax(0, q->cursorWidth() - 1) + + horizontalAdvance * m_visualIndentOffset; int paintColumn = 0; - const QString text = data.block.text(); + const QString text = data.block.text().mid(m_visualIndentOffset); while (paintColumn < depth) { if (x >= 0) { int paintPosition = tabSettings.positionAtColumn(text, paintColumn); @@ -4471,7 +4477,7 @@ void TextEditorWidgetPrivate::paintIndentDepth(PaintEventData &data, const QLineF line(top, bottom); painter.drawLine(line); } - x += horizontalAdvance; + x += fullHorizontalAdvance; paintColumn += tabSettings.m_indentSize; } painter.restore(); @@ -8017,8 +8023,11 @@ void TextEditorWidget::setupFallBackEditor(Id id) void TextEditorWidget::appendStandardContextMenuActions(QMenu *menu) { - if (optionalActions() & TextEditorActionHandler::FindUsage) - menu->addAction(ActionManager::command(Constants::FIND_USAGES)->action()); + if (optionalActions() & TextEditorActionHandler::FindUsage) { + const auto findUsage = ActionManager::command(Constants::FIND_USAGES)->action(); + if (!menu->actions().contains(findUsage)) + menu->addAction(findUsage); + } menu->addSeparator(); appendMenuActionsFromContext(menu, Constants::M_STANDARDCONTEXTMENU); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 75ccb493578..801ab5cc3e5 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -537,6 +537,8 @@ protected: virtual void finalizeInitializationAfterDuplication(TextEditorWidget *) {} static QTextCursor flippedCursor(const QTextCursor &cursor); + void setVisualIndentOffset(int offset); + public: QString selectedText() const; diff --git a/tests/auto/utils/fileutils/tst_fileutils.cpp b/tests/auto/utils/fileutils/tst_fileutils.cpp index d4cd46965cf..5fb8fa2d0c7 100644 --- a/tests/auto/utils/fileutils/tst_fileutils.cpp +++ b/tests/auto/utils/fileutils/tst_fileutils.cpp @@ -104,6 +104,9 @@ private slots: void isSameFile_data(); void isSameFile(); + void hostSpecialChars_data(); + void hostSpecialChars(); + private: QTemporaryDir tempDir; QString rootPath; @@ -1159,6 +1162,54 @@ void tst_fileutils::isSameFile() QCOMPARE(left.isSameFile(right), shouldBeEqual); } +void tst_fileutils::hostSpecialChars_data() +{ + QTest::addColumn("scheme"); + QTest::addColumn("host"); + QTest::addColumn("path"); + QTest::addColumn("expected"); + + QTest::addRow("slash-in-host") << "device" << "host/name" << "/" << FilePath::fromString("device://host%2fname/"); + QTest::addRow("percent-in-host") << "device" << "host%name" << "/" << FilePath::fromString("device://host%25name/"); + QTest::addRow("percent-and-slash-in-host") << "device" << "host/%name" << "/" << FilePath::fromString("device://host%2f%25name/"); + QTest::addRow("qtc-dev-slash-in-host-linux") << "device" << "host/name" << "/" << FilePath::fromString("/__qtc_devices__/device/host%2fname/"); + QTest::addRow("qtc-dev-slash-in-host-windows") << "device" << "host/name" << "/" << FilePath::fromString("c:/__qtc_devices__/device/host%2fname/"); + +} + +void tst_fileutils::hostSpecialChars() +{ + QFETCH(QString, scheme); + QFETCH(QString, host); + QFETCH(QString, path); + QFETCH(FilePath, expected); + + FilePath fp; + fp.setParts(scheme, host, path); + + // Check that setParts and fromString give the same result + QCOMPARE(fp, expected); + QCOMPARE(fp.host(), expected.host()); + QCOMPARE(fp.host(), host); + QCOMPARE(expected.host(), host); + + QString toStringExpected = expected.toString(); + QString toStringActual = fp.toString(); + + // Check that toString gives the same result + QCOMPARE(toStringActual, toStringExpected); + + // Check that fromString => toString => fromString gives the same result + FilePath toFromExpected = FilePath::fromString(expected.toString()); + QCOMPARE(toFromExpected, expected); + QCOMPARE(toFromExpected, fp); + + // Check that setParts => toString => fromString gives the same result + FilePath toFromActual = FilePath::fromString(fp.toString()); + QCOMPARE(toFromActual, fp); + QCOMPARE(toFromExpected, expected); +} + QTEST_GUILESS_MAIN(tst_fileutils) #include "tst_fileutils.moc" diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index e4fd4feeae9..f4eb2283263 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -10,6 +10,7 @@ "name": "mingw", "displayName": "MinGW 11.2.0", "generator": "Ninja", + "installDir": "../inst-${presetName}", "cacheVariables": { "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" }, @@ -75,8 +76,8 @@ "VCToolsVersion": "14.29.30133", "WindowsSDKVersion" : "10.0.22000.0", "VCArch": "x64", - "VCToolsInstallDir": "$penv{ProgramFiles(x86)}/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/$env{VCToolsVersion}", - "WindowsSdkDir" : "$penv{ProgramFiles(x86)}/Windows Kits/10", + "VCToolsInstallDir": "$env{ProgramFiles(x86)}/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/$env{VCToolsVersion}", + "WindowsSdkDir" : "$env{ProgramFiles(x86)}/Windows Kits/10", "WindowsSdkIncVerDir": "$env{WindowsSdkDir}/Include/$env{WindowsSDKVersion}", "WindowsSdkLibVerDir": "$env{WindowsSdkDir}/Lib/$env{WindowsSDKVersion}", @@ -90,7 +91,7 @@ "displayName": "Linux GCC", "generator": "Ninja", "binaryDir": "${sourceDir}/build-${presetName}", - "toolchainFile" : "$penv{HOME}/Qt/6.3.2/gcc_64/lib/cmake/Qt6/qt.toolchain.cmake", + "toolchainFile" : "$env{HOME}/Qt/6.3.2/gcc_64/lib/cmake/Qt6/qt.toolchain.cmake", "condition" : { "type": "equals", "lhs": "${hostSystemName}", diff --git a/tests/system/objects.map b/tests/system/objects.map index da30b655651..6d7a96a03fa 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -29,7 +29,8 @@ :Behavior.Autocomplete common prefix_QCheckBox {container=':CppTools__Internal__CompletionSettingsPage.Behavior_QGroupBox' name='partiallyComplete' text='Autocomplete common prefix' type='QCheckBox' visible='1'} :Behavior.completionTrigger_QComboBox {container=':CppTools__Internal__CompletionSettingsPage.Behavior_QGroupBox' name='completionTrigger' type='QComboBox' visible='1'} :Breakpoints_Debugger::Internal::BreakTreeView {container=':Debugger.Docks.BreakDockWidget.Debugger.Docks.Break_QFrame' type='Utils::BaseTreeView' unnamed='1' visible='1'} -:Build and Run.Save all files before build_QCheckBox {name='saveAllFilesCheckBox' type='QCheckBox' visible='1'} +:Build and Run.Save all files before build_QCheckBox {container=':Build and Run_QGroupBox' text='Save all files before build' type='QCheckBox' unnamed='1' visible='1'} +:Build and Run_QGroupBox {container=':qt_tabwidget_stackedwidget_QScrollArea' name='Build and Run' type='QGroupBox' visible='1'} :BuildAndRun_QTreeView {container=':qt_tabwidget_stackedwidget_QWidget' type='QTreeView' unnamed='1' visible='1'} :CCompiler:_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' leftWidget=':CCompiler:_QLabel' type='QComboBox' unnamed='1' visible='1'} :CCompiler:_QLabel {container=':qt_tabwidget_stackedwidget_QWidget' text='C:' type='QLabel' unnamed='1' visible='1'} @@ -95,7 +96,7 @@ :New.comboBox_QComboBox {type='QComboBox' unnamed='1' visible='1' window=':New_Core::Internal::NewDialog'} :New.frame_QFrame {name='frame' type='QFrame' visible='1' window=':New_Core::Internal::NewDialog'} :New.templateCategoryView_QTreeView {name='templateCategoryView' type='QTreeView' visible='1' window=':New_Core::Internal::NewDialog'} -:New_Core::Internal::NewDialog {name='Core.NewDialog' type='Core::Internal::NewDialogWidget' visible='1' windowTitle?='New*'} +:New_Core::Internal::NewDialog {name='Core.NewDialog' type='QDialog' visible='1' windowTitle?='New*'} :New_ProjectExplorer::JsonWizard {type='ProjectExplorer::JsonWizard' unnamed='1' visible='1'} :Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'} :No valid kits found._QLabel {text?='*No suitable kits found.*' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} @@ -176,10 +177,10 @@ :Restart required_QMessageBox {text='The language change will take effect after restart.' type='QMessageBox' unnamed='1' visible='1'} :Revert to Saved.Proceed_QPushButton {text='Proceed' type='QPushButton' unnamed='1' visible='1' window=':Revert to Saved_QMessageBox'} :Revert to Saved_QMessageBox {text?='You will lose your current changes if you proceed reverting*' type='QMessageBox' unnamed='1' visible='1'} -:Save Changes.Always save files before build_QCheckBox {name='saveBeforeBuildCheckBox' text='Always save files before build' type='QCheckBox' visible='1' window=':Save Changes_Core::Internal::SaveItemsDialog'} +:Save Changes.Always save files before build_QCheckBox {text='Always save files before build' type='QCheckBox' unnamed='1' visible='1' window=':Save Changes_Core::Internal::SaveItemsDialog'} :Save Changes.Do not Save_QPushButton {text='Do Not Save' type='QPushButton' unnamed='1' visible='1' window=':Save Changes_Core::Internal::SaveItemsDialog'} :Save Changes.Save All_QPushButton {text='Save All' type='QPushButton' unnamed='1' visible='1' window=':Save Changes_Core::Internal::SaveItemsDialog'} -:Save Changes_Core::Internal::SaveItemsDialog {name='Core__Internal__SaveItemsDialog' type='Core::Internal::SaveItemsDialog' visible='1' windowTitle='Save Changes'} +:Save Changes_Core::Internal::SaveItemsDialog {type='Core::Internal::SaveItemsDialog' unnamed='1' visible='1' windowTitle='Save Changes'} :Select a Git Commit.Show_QPushButton {name='showButton' text='Show' type='QPushButton' visible='1' window=':Select a Git Commit_Git::Internal::ChangeSelectionDialog'} :Select a Git Commit.changeNumberEdit_Utils::CompletingLineEdit {name='changeNumberEdit' type='Utils::CompletingLineEdit' visible='1' window=':Select a Git Commit_Git::Internal::ChangeSelectionDialog'} :Select a Git Commit.detailsText_QPlainTextEdit {name='detailsText' type='QPlainTextEdit' visible='1' window=':Select a Git Commit_Git::Internal::ChangeSelectionDialog'} @@ -191,16 +192,16 @@ :Send to Codepaster.protocolBox_QComboBox {name='protocolBox' type='QComboBox' visible='1' window=':Send to Codepaster_CodePaster::PasteView'} :Send to Codepaster.qt_spinbox_lineedit_QLineEdit {name='qt_spinbox_lineedit' type='QLineEdit' visible='1' window=':Send to Codepaster_CodePaster::PasteView'} :Send to Codepaster_CodePaster::PasteView {name='CodePaster.ViewDialog' type='QDialog' visible='1' windowTitle='Send to Codepaster'} -:Session Manager_ProjectExplorer::Internal::SessionDialog {name='ProjectExplorer__Internal__SessionDialog' type='ProjectExplorer::Internal::SessionDialog' visible='1' windowTitle='Session Manager'} +:Session Manager_ProjectExplorer::Internal::SessionDialog {name='ProjectExplorer.SessionDialog' type='ProjectExplorer::Internal::SessionDialog' visible='1' windowTitle='Session Manager'} :Startup.contextHelpComboBox_QComboBox {container=':Form.Startup_QGroupBox' name='contextHelpComboBox' type='QComboBox' visible='1'} :User Interface.languageBox_QComboBox {container=':Core__Internal__GeneralSettings.User Interface_QGroupBox' name='languageBox' type='QComboBox' visible='1'} :Utils::FakeToolTip {type='Utils::FakeToolTip' unnamed='1' visible='1'} :Widget Box_qdesigner_internal::WidgetBoxTreeWidget {container=':*Qt Creator.Widget Box_QDockWidget' type='qdesigner_internal::WidgetBoxTreeWidget' unnamed='1' visible='1'} :Working Copy_Utils::BaseValidatingLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'} -:WritePermissions_Core::Internal::ReadOnlyFilesDialog {name='Core__Internal__ReadOnlyFilesDialog' type='Core::ReadOnlyFilesDialog' visible='1' windowTitle='Files Without Write Permissions'} +:WritePermissions_Core::Internal::ReadOnlyFilesDialog {type='Core::ReadOnlyFilesDialog' unnamed='1' visible='1' windowTitle='Files Without Write Permissions'} :addToVersionControlComboBox_QComboBox {name='addToVersionControlComboBox' type='QComboBox' visible='1'} :formFileLineEdit_Utils::FileNameValidatingLineEdit {name='FormFileName' type='Utils::FancyLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'} -:frame.templateDescription_QTextBrowser {container=':New.frame_QFrame' name='templateDescription' type='QTextBrowser' visible='1'} +:frame.templateDescription_QTextBrowser {name='templateDescription' type='QTextBrowser' visible='1' window=':New_Core::Internal::NewDialog'} :headerFileLineEdit_Utils::FileNameValidatingLineEdit {name='HdrFileName' type='Utils::FancyLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'} :popupFrame_Proposal_QListView {container=':popupFrame_TextEditor::GenericProposalWidget' type='QListView' unnamed='1' visible='1'} :popupFrame_TextEditor::GenericProposalWidget {name='m_popupFrame' type='TextEditor::GenericProposalWidget' visible='1'} diff --git a/tests/system/suite_APTW/envvars b/tests/system/suite_APTW/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_APTW/envvars +++ b/tests/system/suite_APTW/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_CCOM/envvars b/tests/system/suite_CCOM/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_CCOM/envvars +++ b/tests/system/suite_CCOM/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_CSUP/envvars b/tests/system/suite_CSUP/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_CSUP/envvars +++ b/tests/system/suite_CSUP/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_HELP/envvars b/tests/system/suite_HELP/envvars index 00aad3eab7d..3b1d5839636 100755 --- a/tests/system/suite_HELP/envvars +++ b/tests/system/suite_HELP/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_QMLS/envvars b/tests/system/suite_QMLS/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_QMLS/envvars +++ b/tests/system/suite_QMLS/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_SCOM/envvars b/tests/system/suite_SCOM/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_SCOM/envvars +++ b/tests/system/suite_SCOM/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_WELP/envvars b/tests/system/suite_WELP/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_WELP/envvars +++ b/tests/system/suite_WELP/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_debugger/envvars b/tests/system/suite_debugger/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_debugger/envvars +++ b/tests/system/suite_debugger/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_editors/envvars b/tests/system/suite_editors/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_editors/envvars +++ b/tests/system/suite_editors/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_editors/tst_modify_readonly/test.py b/tests/system/suite_editors/tst_modify_readonly/test.py index 355283903b7..0bb68a8ed3c 100644 --- a/tests/system/suite_editors/tst_modify_readonly/test.py +++ b/tests/system/suite_editors/tst_modify_readonly/test.py @@ -62,20 +62,19 @@ def testModifyFile(fileName, editor, line, expectWarning): return checkOpenDocumentsContains("%s*" % simpleFName) def testSaveChangesAndMakeWritable(modifiedFiles, readOnlyFiles): - saveDlgStr = ("{name='Core__Internal__SaveItemsDialog' type='Core::Internal::SaveItemsDialog' " - "visible='1' windowTitle='Save Changes'}") + saveDlgStr = ":Save Changes_Core::Internal::SaveItemsDialog" try: waitForObject(saveDlgStr) except: test.fail("Save Changes dialog did not come up, but was expected to appear.") return - treeWidget = waitForObject("{name='treeWidget' type='QTreeWidget' visible='1' window=%s}" + treeWidget = waitForObject("{type='QTreeWidget' unnamed='1' visible='1' window='%s'}" % saveDlgStr) checkUnsavedChangesContains(treeWidget.model(), modifiedFiles) clickButton(waitForObject("{text='Save All' type='QPushButton' unnamed='1' visible='1' " - "window=%s}" % saveDlgStr)) + "window='%s'}" % saveDlgStr)) try: - filesTree = waitForObject("{name='treeWidget' type='QTreeWidget' visible='1' " + filesTree = waitForObject("{type='QTreeWidget' unnamed='1' visible='1' " "window=':WritePermissions_Core::Internal::ReadOnlyFilesDialog'}") items = map(os.path.expanduser, map(os.path.join, dumpItems(filesTree.model(), column=4), dumpItems(filesTree.model(), column=3))) @@ -102,7 +101,7 @@ def testSaveChangesAndMakeWritable(modifiedFiles, readOnlyFiles): test.log("Exiting without saving.") waitForObject(saveDlgStr) clickButton(waitForObject("{text='Do not Save' type='QPushButton' unnamed='1' " - "visible='1' window=%s}" % saveDlgStr)) + "visible='1' window='%s'}" % saveDlgStr)) def checkOpenDocumentsContains(itemName): selectFromCombo(":Qt Creator_Core::Internal::NavComboBox", "Open Documents") diff --git a/tests/system/suite_general/envvars b/tests/system/suite_general/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_general/envvars +++ b/tests/system/suite_general/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py index 40dbd205cfc..cc9873e5918 100644 --- a/tests/system/suite_general/tst_create_proj_wizard/test.py +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -64,7 +64,7 @@ def main(): # are there more Quick combinations - then recreate this project if counter < len(qtVersionsForQuick) - 1: displayedPlatforms = __createProject__(category, template) - elif template in ("Qt Widgets Application", "Qt Quick 2 Extension Plugin", "C++ Library"): + elif template in ("Qt Widgets Application", "C++ Library", "Code Snippet"): def skipDetails(_): clickButton(waitForObject(":Next_QPushButton")) handleBuildSystemVerifyKits(category, template, kits, diff --git a/tests/system/suite_general/tst_session_handling/test.py b/tests/system/suite_general/tst_session_handling/test.py index 07808adcfdf..f510040c447 100644 --- a/tests/system/suite_general/tst_session_handling/test.py +++ b/tests/system/suite_general/tst_session_handling/test.py @@ -66,7 +66,7 @@ def switchSession(toSession): sessionView = ("{name='sessionView' type='ProjectExplorer::Internal::SessionView' visible='1' " "window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}") mouseClick(waitForObjectItem(sessionView, toSession)) - clickButton(waitForObject("{name='btSwitch' type='QPushButton' visible='1' " + clickButton(waitForObject("{name='btOpen' type='QPushButton' visible='1' " "window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}")) def createAndSwitchToSession(toSession): diff --git a/tests/system/suite_qtquick/envvars b/tests/system/suite_qtquick/envvars index 00aad3eab7d..3b1d5839636 100644 --- a/tests/system/suite_qtquick/envvars +++ b/tests/system/suite_qtquick/envvars @@ -1 +1,2 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 diff --git a/tests/system/suite_tools/envvars b/tests/system/suite_tools/envvars index 3a6c559a87d..1018e482444 100644 --- a/tests/system/suite_tools/envvars +++ b/tests/system/suite_tools/envvars @@ -1,2 +1,3 @@ QT_PLATFORM_PLUGIN=nonesuch +QTC_DO_NOT_PROPAGATE_LD_PRELOAD=1 LC_ALL=C