From c6a4cd293baa565116cf9d4a4ca39da9c7916d25 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 10:27:32 +0200 Subject: [PATCH 01/29] CMake: Fix initializer re-ordering warning Change-Id: Iffcc4eb562a06ff12d641d23687dc4c44c797ce8 Reviewed-by: hjk --- src/plugins/cmakeprojectmanager/cmakesettingspage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index 0257738d32d..0d6430517bf 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -109,10 +109,10 @@ public: , m_name(item->displayName()) , m_executable(item->filePath()) , m_qchFile(item->qchFilePath()) + , m_versionDisplay(item->versionDisplay()) , m_isAutoRun(item->isAutoRun()) , m_autodetected(item->isAutoDetected()) , m_isSupported(item->hasFileApi()) - , m_versionDisplay(item->versionDisplay()) , m_changed(changed) { updateErrorFlags(); From 8f30ff6987b5030d63e4e9faeec86461a88ba000 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 24 Jun 2021 13:23:36 +0200 Subject: [PATCH 02/29] CMake: Show build directory when asking if it should be used When changing the build directory to a new or empty directory, we ask if the build directory should be changed and the project be configured there. Mention the new directory in the dialog. Change-Id: Ie4d7e9b132e6e90004e4d498b2182562375e7441 Reviewed-by: Cristian Adam --- .../cmakebuildconfiguration.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 94759a860d6..a98fded999e 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -852,12 +852,14 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) return newDir; if (QDir(oldDir).exists("CMakeCache.txt") && !QDir(newDir).exists("CMakeCache.txt")) { - if (QMessageBox::information(Core::ICore::dialogParent(), - tr("Changing Build Directory"), - tr("Change the build directory and start with a " - "basic CMake configuration?"), - QMessageBox::Ok, - QMessageBox::Cancel) + if (QMessageBox::information( + Core::ICore::dialogParent(), + tr("Changing Build Directory"), + tr("Change the build directory to \"%1\" and start with a " + "basic CMake configuration?") + .arg(newDir), + QMessageBox::Ok, + QMessageBox::Cancel) == QMessageBox::Ok) { return newDir; } From b1837036b3f6fca6fc2c1c4681ad4e36f27b3882 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 11:31:48 +0200 Subject: [PATCH 03/29] Fix some warnings about unused lambda captures Change-Id: Icfb1b963b3c55656c760497e4ae3ece2bdccbbc7 Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/plugins/autotest/autotestplugin.cpp | 4 ++-- src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp | 2 +- src/plugins/mcusupport/mcusupportplugin.cpp | 2 +- src/plugins/studiowelcome/studiowelcomeplugin.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 277e346fc62..20c5562b2a3 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -279,9 +279,9 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri dd = new AutotestPluginPrivate; #ifdef WITH_TESTS ExtensionSystem::PluginManager::registerScenario("TestStringTable", - [this]() { return dd->m_loadProjectScenario(); }); + [] { return dd->m_loadProjectScenario(); }); ExtensionSystem::PluginManager::registerScenario("TestModelManagerInterface", - [this]() { return dd->m_loadProjectScenario(); }); + [] { return dd->m_loadProjectScenario(); }); #endif return true; } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index c3a20a928c1..b89d5d74ef6 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -1027,7 +1027,7 @@ const QList CMakeBuildSystem::appTargets() const QStringList CMakeBuildSystem::buildTargetTitles() const { - auto nonAutogenTargets = filtered(m_buildTargets, [this](const CMakeBuildTarget &target){ + auto nonAutogenTargets = filtered(m_buildTargets, [](const CMakeBuildTarget &target){ return !CMakeBuildSystem::filteredOutTarget(target); }); return transform(nonAutogenTargets, &CMakeBuildTarget::title); diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp index 65b588bce8b..a318928f195 100644 --- a/src/plugins/mcusupport/mcusupportplugin.cpp +++ b/src/plugins/mcusupport/mcusupportplugin.cpp @@ -136,7 +136,7 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade() static McuSupportOptions::UpgradeOption selectedOption; const QStringList options = { tr("Create new kits"), tr("Replace existing kits") }; selectedOption = McuSupportOptions::UpgradeOption::Keep; - info.setComboInfo(options, [upgradeMcuSupportKits, options](const QString &selected) { + info.setComboInfo(options, [options](const QString &selected) { selectedOption = options.indexOf(selected) == 0 ? McuSupportOptions::UpgradeOption::Keep : McuSupportOptions::UpgradeOption::Replace; diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 39660b5235f..118962fec68 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -195,7 +195,7 @@ public: connect(checkout, &ExampleCheckout::finishedSucessfully, this, - [checkout, this, formFile, example]() { + [checkout, formFile, example]() { const QString projectFile = checkout->extractionFolder() + "/" + example + "/" + example + ".qmlproject"; From 627dd6681bc2f4ecd4c34eb0599ee9b65ac08537 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 10:55:02 +0200 Subject: [PATCH 04/29] Sqlite: Fix warnings - use of uninitialized value - unused local typedef Change-Id: I60d6c3a9a04d9f603a102439582c9e55d85a191f Reviewed-by: Marco Bubke Reviewed-by: Qt CI Bot --- src/libs/sqlite/sqlitebasestatement.h | 2 +- tests/unit/unittest/sqlitestatement-test.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h index e8e9026dae3..4966ee38450 100644 --- a/src/libs/sqlite/sqlitebasestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -213,7 +213,7 @@ public: auto value(const QueryTypes &...queryValues) { Resetter resetter{this}; - ResultType resultValue; + ResultType resultValue{}; bindValues(queryValues...); diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index 3804f8b31ed..fb25c9de4d7 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -1474,7 +1474,6 @@ TEST_F(SqliteStatement, ReadStatementOptionalValueWithTransactions) TEST_F(SqliteStatement, ReadStatementReadCallbackWithTransactions) { - using Tuple = std::tuple; MockFunction callbackMock; ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", database); @@ -1541,7 +1540,6 @@ TEST_F(SqliteStatement, ReadWriteStatementOptionalValueWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementReadCallbackWithTransactions) { - using Tuple = std::tuple; MockFunction callbackMock; ReadWriteStatement<3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); From f1eaf25dff3593673018c6af49444bd939c2aaac Mon Sep 17 00:00:00 2001 From: Johanna Vanhatapio Date: Thu, 24 Jun 2021 15:09:07 +0300 Subject: [PATCH 05/29] Doc: Decribe multiselection of assets Task-number: QDS-4595 Change-Id: Ibc7a40af147416ac36f0b5436470906df6039329 Reviewed-by: Leena Miettinen Reviewed-by: Mahmoud Badri --- doc/qtcreator/src/qtquick/qtquick-library.qdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/qtcreator/src/qtquick/qtquick-library.qdoc b/doc/qtcreator/src/qtquick/qtquick-library.qdoc index 331ea4eb22e..8dc9c3c44a7 100644 --- a/doc/qtcreator/src/qtquick/qtquick-library.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-library.qdoc @@ -114,7 +114,11 @@ \uicontrol Library > \uicontrol {Assets} displays the images and other files that you add to the project folder by selecting \inlineimage plus.png - . + . To add assets to your UI, drag-and-drop them to \l Navigator or + \l {Form Editor}. + + To add multiple assets to your UI simultaneously, multiselect them first by + holding \key Ctrl and clicking the asset files you wish to select. \image qtquick-assets-tab.png "Library view Assets tab" From 4ff26e2a27d692b8b38456873e5aaf4b65c36ee3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 14:20:04 +0200 Subject: [PATCH 06/29] CppEditor: Do not rely on object identity when comparing names In particular, the same namespace can be declared in lots of different places. Fixes: QTCREATORBUG-25776 Change-Id: I7e255cee560043ed4beb47b8047f99c3a9c21198 Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppquickfixes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 7c2d8cabca3..928a26f8532 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3583,8 +3583,10 @@ protected: if (i.type()->isNamedType()) { // check if we have to search recursively const Name *newName = i.type()->asNamedType()->name(); Scope *newScope = i.declaration()->enclosingScope(); - if (newName == name && newScope == scope) + if (Matcher::match(newName, name) + && Matcher::match(newScope->name(), scope->name())) { continue; // we have found the start location of the search + } return isValueType(newName, newScope, isValueType); } return false; From f295021d98f2db3af11d30eaed16c230d3dea978 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Jun 2021 09:08:11 +0200 Subject: [PATCH 07/29] Docker: Give created devices an deterministic id Change-Id: I451f37065b69da26000cb21ba92b070e6b5698d5 Reviewed-by: Christian Stenger --- src/plugins/docker/dockerdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index b920ffc04b6..563a4b63aef 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -1139,7 +1139,7 @@ public: QTC_ASSERT(item, return {}); auto device = DockerDevice::create(*item); - device->setupId(IDevice::ManuallyAdded, Utils::Id()); + device->setupId(IDevice::ManuallyAdded, Id::fromString(item->id())); device->setType(Constants::DOCKER_DEVICE_TYPE); device->setMachineType(IDevice::Hardware); From 18f9a69f29df58730c242f53eaaa07257a16493c Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 24 Jun 2021 15:40:38 +0200 Subject: [PATCH 08/29] QmlDesigner: Remove QtGraphicalEffects from ColorEditor Change-Id: I96772ddc67314d657c27e4d89f337b9c19c9684f Reviewed-by: Tim Jenssen --- .../imports/HelperWidgets/ColorEditor.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index 3a8f431df8f..89d1a35aa04 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -25,7 +25,6 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 -import QtGraphicalEffects 1.15 as Effects import QtQuick.Shapes 1.15 import QtQuick.Templates 2.15 as T import QtQuickDesignerTheme 1.0 @@ -88,7 +87,7 @@ SecondColumnLayout { gradientString += "}" - var gradientObject = Qt.createQmlObject(gradientString, gradientThumbnail, "test") + var gradientObject = Qt.createQmlObject(gradientString, gradientThumbnail, "dynamicGradient") for (i = 0; i < gradientLine.model.count; i++) { gradientObject.stops[i].color = gradientLine.model.getColor(i) @@ -123,7 +122,7 @@ SecondColumnLayout { gradientStr += "}" - var gradientObj = Qt.createQmlObject(gradientStr, shapeGradientThumbnail, "test1") + var gradientObj = Qt.createQmlObject(gradientStr, shapeGradientThumbnail, "dynamicShapeGradient") for (j = 0; j < gradientLine.model.count; j++) { gradientObj.stops[j].color = gradientLine.model.getColor(j) @@ -235,7 +234,7 @@ SecondColumnLayout { border.color: StudioTheme.Values.themeControlOutline border.width: StudioTheme.Values.border - Effects.LinearGradient { + Rectangle { id: gradientThumbnail anchors.fill: parent anchors.margins: StudioTheme.Values.border From d5544c7abafa4516c5340f65c75566ee7985b96c Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 24 Jun 2021 15:41:07 +0200 Subject: [PATCH 09/29] QmlDesigner: Fix a few warnings and errors Change-Id: Ie25fdc100a8288cd1b10ee186ab925c0ed13ee2d Reviewed-by: Tim Jenssen --- .../imports/HelperWidgets/Button.qml | 4 ++-- .../GradientPresetTabContent.qml | 2 +- .../imports/HelperWidgets/OriginControl.qml | 2 +- .../imports/HelperWidgets/OriginSelector.qml | 8 +++---- .../imports/HelperWidgets/SpinBox.qml | 22 +++++++++---------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Button.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Button.qml index 5326edd615a..45ee8e65724 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Button.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Button.qml @@ -80,8 +80,8 @@ T.AbstractButton { when: myButton.hovered && myButton.pressed PropertyChanges { target: buttonBackground - color: StudioTheme.Values.themeControlBackgroundPressed - border.color: StudioTheme.Values.themeInteraction + color: StudioTheme.Values.themeControlBackgroundInteraction + border.color: StudioTheme.Values.themeControlOutlineInteraction } }, State { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml index 569b168697c..94e83a905c2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml @@ -145,7 +145,7 @@ Rectangle { target: backgroundCard color:StudioTheme.Values.themeInteraction border.width: StudioTheme.Values.border - border.color: StudioTheme.Values.themeControlBackgroundPressed + border.color: StudioTheme.Values.themeControlOutlineInteraction } } ] diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml index cc0b93660a7..7929d2a0538 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml @@ -52,7 +52,7 @@ Row { if (enumString === "") enumString = root.backendValue.value - root.origin = enumString + root.origin = enumString === undefined ? "Center" : enumString } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginSelector.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginSelector.qml index e5f8cd8372e..e42aff045b4 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginSelector.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginSelector.qml @@ -48,7 +48,7 @@ Rectangle { states: [ State { name: "default" - when: !mouseArea.containsMouse && !mouseArea.pressed && myControl.origin !== value + when: !mouseArea.containsMouse && !mouseArea.pressed && myControl.origin !== root.value PropertyChanges { target: root color: StudioTheme.Values.themeTextColorDisabled // TODO @@ -56,7 +56,7 @@ Rectangle { }, State { name: "hover" - when: mouseArea.containsMouse && !mouseArea.pressed && myControl.origin !== value + when: mouseArea.containsMouse && !mouseArea.pressed && myControl.origin !== root.value PropertyChanges { target: root color: StudioTheme.Values.themeControlBackgroundInteraction // TODO @@ -64,7 +64,7 @@ Rectangle { }, State { name: "press" - when: mouseArea.containsPress && myControl.origin !== enumValue + when: mouseArea.containsPress && myControl.origin !== root.value PropertyChanges { target: root color: StudioTheme.Values.themeControlBackgroundInteraction // TODO @@ -73,7 +73,7 @@ Rectangle { }, State { name: "active" - when: myControl.origin === value + when: myControl.origin === root.value PropertyChanges { target: root color: StudioTheme.Values.themeInteraction diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml index b0ffe3fe6cb..cd22b7e7f26 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml @@ -46,18 +46,18 @@ Item { implicitHeight: spinBox.height onFocusChanged: { - restoreCursor(); - transaction.end(); + restoreCursor() + transaction.end() } Component.onCompleted: { - spinBox.enabled = !isBlocked(backendValue.name); + spinBox.enabled = backendValue === undefined ? false : !isBlocked(backendValue.name) } Connections { target: modelNodeBackend function onSelectionChanged() { - spinBox.enabled = !isBlocked(backendValue.name); + spinBox.enabled = backendValue === undefined ? false : !isBlocked(backendValue.name) } } @@ -65,25 +65,25 @@ Item { id: spinBox onDragStarted: { - hideCursor(); - transaction.start(); + hideCursor() + transaction.start() } onDragEnded: { - restoreCursor(); - transaction.end(); + restoreCursor() + transaction.end() } - onDragging: holdCursorInPlace(); + onDragging: holdCursorInPlace() onRealValueModified: { if (transaction.active()) - commitValue(); + commitValue() } function commitValue() { if (spinBox.backendValue.value !== spinBox.realValue) - spinBox.backendValue.value = spinBox.realValue; + spinBox.backendValue.value = spinBox.realValue } property variant backendValue From 9895cd5df8a79051b970ca0486a138a943bc6e4a Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 24 Jun 2021 18:01:03 +0200 Subject: [PATCH 10/29] QmlDesigner: Fix minor property editor issues * Remove minorQtQuickVersion * Add missing PageIndicatorSpecifics.qml * Fix label text in RectangleSpecifics Change-Id: I3dc49c893a204416b742ae603ce2834b061db4d6 Reviewed-by: Tim Jenssen --- .../Controls/PageIndicatorSpecifics.qml | 109 ++++++++++++++++++ .../QtQuick/RectangleSpecifics.qml | 4 +- .../QtQuick/TextEditSpecifics.qml | 4 +- .../QtQuick/TextInputSpecifics.qml | 4 +- .../QtQuick/TextSpecifics.qml | 4 +- .../HelperWidgets/FontExtrasSection.qml | 4 - .../imports/HelperWidgets/FontSection.qml | 4 - 7 files changed, 114 insertions(+), 19 deletions(-) create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/PageIndicatorSpecifics.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/PageIndicatorSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/PageIndicatorSpecifics.qml new file mode 100644 index 00000000000..426e35b78f9 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/PageIndicatorSpecifics.qml @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import HelperWidgets 2.0 +import StudioTheme 1.0 as StudioTheme + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("PageIndicator") + + SectionLayout { + PropertyLabel { + text: qsTr("Count") + tooltip: qsTr("The number of pages.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 0 + backendValue: backendValues.count + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Current") + tooltip: qsTr("The index of the current page.") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + minimumValue: -9999999 + maximumValue: 9999999 + decimals: 0 + backendValue: backendValues.currentIndex + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Interactive") + tooltip: qsTr("Whether the control is interactive.") + } + + SecondColumnLayout { + CheckBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + text: backendValues.interactive.valueToString + backendValue: backendValues.interactive + } + + ExpandingSpacer {} + } + } + } + + ControlSection {} + + PaddingSection {} +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml index 2c0bfd95be1..29697376016 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RectangleSpecifics.qml @@ -38,7 +38,7 @@ Column { caption: qsTr("Rectangle") SectionLayout { - PropertyLabel { text: qsTr("Color") } + PropertyLabel { text: qsTr("Fill color") } ColorEditor { backendValue: backendValues.color @@ -57,7 +57,7 @@ Column { } PropertyLabel { - text: qsTr("Border") + text: qsTr("Border width") disabledState: !backendValues.border_width.isAvailable } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextEditSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextEditSpecifics.qml index 4f0d59c4cb5..c73bff2a3b0 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextEditSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextEditSpecifics.qml @@ -47,7 +47,5 @@ Column { showStyle: false } - PaddingSection { - visible: minorQtQuickVersion > 5 - } + PaddingSection {} } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSpecifics.qml index 2061081b1f6..18d0c00b326 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSpecifics.qml @@ -48,7 +48,5 @@ Column { showStyle: false } - PaddingSection { - visible: minorQtQuickVersion > 5 - } + PaddingSection {} } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextSpecifics.qml index 991b9f8ec4f..2bfe4dc71e5 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextSpecifics.qml @@ -49,7 +49,5 @@ Column { showStyle: true } - PaddingSection { - visible: minorQtQuickVersion > 5 - } + PaddingSection {} } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontExtrasSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontExtrasSection.qml index 61f209c57f4..913c86952a9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontExtrasSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontExtrasSection.qml @@ -123,12 +123,10 @@ Section { tooltip: qsTr("Enables or disables the kerning OpenType feature when shaping the text. Disabling this may " + "improve performance when creating or changing the text, at the expense of some cosmetic features.") disabledState: !getBackendValue("kerning").isAvailable - visible: minorQtQuickVersion > 9 } SecondColumnLayout { CheckBox { - visible: minorQtQuickVersion > 9 text: backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth @@ -145,12 +143,10 @@ Section { "In some writing systems, such as Brahmic scripts, this is required in order for the text to be legible, whereas in " + "Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.") disabledState: !getBackendValue("preferShaping").isAvailable - visible: minorQtQuickVersion > 9 } SecondColumnLayout { CheckBox { - visible: minorQtQuickVersion > 9 text: backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml index a89f88989c5..d60d4d9526e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml @@ -319,12 +319,10 @@ Section { tooltip: qsTr("Enables or disables the kerning OpenType feature when shaping the text. Disabling this may " + "improve performance when creating or changing the text, at the expense of some cosmetic features.") disabledState: !getBackendValue("kerning").isAvailable - visible: minorQtQuickVersion > 9 } SecondColumnLayout { CheckBox { - visible: minorQtQuickVersion > 9 text: backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth @@ -341,12 +339,10 @@ Section { "In some writing systems, such as Brahmic scripts, this is required in order for the text to be legible, whereas in " + "Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.") disabledState: !getBackendValue("preferShaping").isAvailable - visible: minorQtQuickVersion > 9 } SecondColumnLayout { CheckBox { - visible: minorQtQuickVersion > 9 text: backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth From 2a5bdc893e16de6b51228986d7ee68526c666f27 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Jun 2021 11:06:57 +0200 Subject: [PATCH 11/29] Debugger: Robustify protocol Chicken out of list parsing when an element can't be read. Change-Id: Ia0c487c53984ee29ba1b561edc040aa1447493a6 Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerprotocol.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 6dc856324da..9c671c14144 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -308,10 +308,10 @@ void GdbMi::parseList(DebuggerOutputParser &parser) } GdbMi child; child.parseResultOrValue(parser); - if (child.isValid()) { - m_children.push_back(child); - parser.skipCommas(); - } + if (!child.isValid()) + break; + m_children.push_back(child); + parser.skipCommas(); } } From 1fef4085bf1f2fe891fd158828257f932e47c395 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Jun 2021 08:23:09 +0200 Subject: [PATCH 12/29] Debugger: Support CLion based LLDB Change-Id: Ie044def8c243a62734cc77a9eab29cbb1fa81e66 Done-by: Igor Lifanov Task-number: QTCREATORBUG-14539 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/lldbbridge.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7888752a239..20c674d0455 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1358,6 +1358,7 @@ class Dumper(DumperBase): def report(self, stuff): with self.outputLock: sys.stdout.write("@\n" + stuff + "@\n") + sys.stdout.flush() def reportState(self, state): self.report('state="%s"' % state) @@ -1588,6 +1589,7 @@ class Dumper(DumperBase): 'output = d.hexencode(sys.stdout.getvalue())', 'sys.stdout = origout', 'd.report("output={channel=\"stderr\",data=\" + output + \"}")', + 'sys.stdout.flush()', 'if result is False:', ' d.reportState("continueafternextstop")', 'return True' From 9e8cfe1a41e006d63b61f96e30011cf018a1e200 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 24 Jun 2021 15:26:36 +0200 Subject: [PATCH 13/29] macOS: Remove clangrefactoring/pchmanager from deployment They are gone for real now Change-Id: I653ed1ce1591d839a5ba01d00ef18c590d44100a Reviewed-by: Marco Bubke --- scripts/deployqtHelper_mac.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index a079cb84254..867fa5c6988 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -136,8 +136,6 @@ if [ $LLVM_INSTALL_DIR ]; then install_name_tool -add_rpath "@executable_path/../lib" "$libexec_path/clang/bin/clazy-standalone" || exit 1 fi clangbackendArgument="-executable=$libexec_path/clangbackend" - clangpchmanagerArgument="-executable=$libexec_path/clangpchmanagerbackend" - clangrefactoringArgument="-executable=$libexec_path/clangrefactoringbackend" fi #### macdeployqt @@ -173,6 +171,6 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then "-executable=$libexec_path/cpaster" \ "${qbsArguments[@]}" \ "$qml2puppetArgument" \ - "$clangbackendArgument" "$clangpchmanagerArgument" "$clangrefactoringArgument" || exit 1 + "$clangbackendArgument" || exit 1 fi From d720a7fb21b550b6cbe49390b6e6dadc421c4404 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 25 Jun 2021 09:12:03 +0200 Subject: [PATCH 14/29] Tracing: Use Qt5_VERSION to check the Qt version in CMake Instead of QT_VERSION. Change-Id: I466f4daee623b91aadda5160cc7dec104788f66c Reviewed-by: Eike Ziller Reviewed-by: Jarek Kobus --- src/libs/tracing/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/tracing/CMakeLists.txt b/src/libs/tracing/CMakeLists.txt index 762fc71c278..8d445df2bff 100644 --- a/src/libs/tracing/CMakeLists.txt +++ b/src/libs/tracing/CMakeLists.txt @@ -1,5 +1,3 @@ -find_package(QT NAMES Qt5 Qt6) - if (WITH_TESTS) set(TEST_SOURCES runscenegraphtest.cpp runscenegraphtest.h @@ -40,7 +38,7 @@ add_qtc_library(Tracing ${TEST_SOURCES} ) -if(${QT_VERSION} VERSION_LESS "6.2.0") +if(${Qt5_VERSION} VERSION_LESS "6.2.0") extend_qtc_library(Tracing SOURCES ${TRACING_CPP_SOURCES} From 4e32999fabd18c280a5dcd849463ebf5d8cf9a8f Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 24 Jun 2021 16:38:28 +0200 Subject: [PATCH 15/29] Doc: Describe different ways of editing bookmarks Task-number: QTCREATORBUG-25642 Change-Id: I39bce45571643900f2dca4c695bba4247bc1e9ad Reviewed-by: Eike Ziller --- .../src/editors/creator-coding-edit-mode.qdoc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc index 449eba8a259..e77e8305328 100644 --- a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc @@ -201,9 +201,17 @@ \image qtcreator-togglebookmark.png - To add a note to a bookmark, right-click the bookmark and select - \uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over - the bookmark. + To add a note to a bookmark: + + \list + \li Select \uicontrol Tools > \uicontrol Bookmarks > + \uicontrol {Edit Bookmark}. + \li Press \key {Ctrl+Shift+M}. + \li Right-click a bookmark and select \uicontrol {Edit Bookmark} + in the context menu. + \endlist + + To view the note, move the mouse pointer over the bookmark. To go to the previous bookmark in the current session, select \uicontrol Tools > \uicontrol Bookmarks > \uicontrol {Previous Bookmark} From b52337aef9c940dc11cccf748d9ed6c8a6e353ac Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 12:05:09 +0200 Subject: [PATCH 16/29] QbsProjectManager: Make qbs version available in settings We'll make use of this in a follow-up patch. Change-Id: I851d607256617b02a3fedc3a370203a47a8db904 Reviewed-by: Christian Stenger --- src/plugins/qbsprojectmanager/qbssettings.cpp | 42 +++++++++++++------ src/plugins/qbsprojectmanager/qbssettings.h | 3 ++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbssettings.cpp b/src/plugins/qbsprojectmanager/qbssettings.cpp index de6b1ad9dac..0233955175a 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.cpp +++ b/src/plugins/qbsprojectmanager/qbssettings.cpp @@ -49,6 +49,19 @@ const char QBS_EXE_KEY[] = "QbsProjectManager/QbsExecutable"; const char QBS_DEFAULT_INSTALL_DIR_KEY[] = "QbsProjectManager/DefaultInstallDir"; const char USE_CREATOR_SETTINGS_KEY[] = "QbsProjectManager/useCreatorDir"; +static QString getQbsVersion(const FilePath &qbsExe) +{ + if (qbsExe.isEmpty() || !qbsExe.exists()) + return {}; + QProcess qbsProc; + qbsProc.start(qbsExe.toString(), {"--version"}); + if (!qbsProc.waitForStarted(3000) || !qbsProc.waitForFinished(5000) + || qbsProc.exitCode() != 0) { + return {}; + } + return QString::fromLocal8Bit(qbsProc.readAllStandardOutput()).trimmed(); +} + static bool operator==(const QbsSettingsData &s1, const QbsSettingsData &s2) { return s1.qbsExecutableFilePath == s2.qbsExecutableFilePath @@ -88,6 +101,14 @@ QString QbsSettings::qbsSettingsBaseDir() return useCreatorSettingsDirForQbs() ? Core::ICore::userResourcePath().toString() : QString(); } +QVersionNumber QbsSettings::qbsVersion() +{ + if (instance().m_settings.qbsVersion.isNull()) + instance().m_settings.qbsVersion = QVersionNumber::fromString( + getQbsVersion(qbsExecutableFilePath())); + return instance().m_settings.qbsVersion; +} + QbsSettings &QbsSettings::instance() { static QbsSettings theSettings; @@ -140,7 +161,7 @@ public: m_qbsExePathChooser.setExpectedKind(PathChooser::ExistingCommand); m_qbsExePathChooser.setFilePath(QbsSettings::qbsExecutableFilePath()); m_defaultInstallDirLineEdit.setText(QbsSettings::defaultInstallDirTemplate()); - m_versionLabel.setText(getQbsVersion()); + m_versionLabel.setText(getQbsVersionString()); m_settingsDirCheckBox.setText(tr("Use %1 settings directory for Qbs") .arg(Core::Constants::IDE_DISPLAY_NAME)); m_settingsDirCheckBox.setChecked(QbsSettings::useCreatorSettingsDirForQbs()); @@ -150,6 +171,10 @@ public: layout->addRow(tr("Path to qbs executable:"), &m_qbsExePathChooser); layout->addRow(tr("Default installation directory:"), &m_defaultInstallDirLineEdit); layout->addRow(tr("Qbs version:"), &m_versionLabel); + + connect(&m_qbsExePathChooser, &PathChooser::pathChanged, [this] { + m_versionLabel.setText(getQbsVersionString()); + }); } void apply() @@ -159,22 +184,15 @@ public: settings.qbsExecutableFilePath = m_qbsExePathChooser.filePath(); settings.defaultInstallDirTemplate = m_defaultInstallDirLineEdit.text(); settings.useCreatorSettings = m_settingsDirCheckBox.isChecked(); + settings.qbsVersion = {}; QbsSettings::setSettingsData(settings); } private: - static QString getQbsVersion() + QString getQbsVersionString() { - const FilePath qbsExe = QbsSettings::qbsExecutableFilePath(); - if (qbsExe.isEmpty() || !qbsExe.exists()) - return tr("Failed to retrieve version."); - QProcess qbsProc; - qbsProc.start(qbsExe.toString(), {"--version"}); - if (!qbsProc.waitForStarted(3000) || !qbsProc.waitForFinished(5000) - || qbsProc.exitCode() != 0) { - return tr("Failed to retrieve version."); - } - return QString::fromLocal8Bit(qbsProc.readAllStandardOutput()).trimmed(); + const QString version = getQbsVersion(m_qbsExePathChooser.filePath()); + return version.isEmpty() ? tr("Failed to retrieve version.") : version; } PathChooser m_qbsExePathChooser; diff --git a/src/plugins/qbsprojectmanager/qbssettings.h b/src/plugins/qbsprojectmanager/qbssettings.h index 490c9c57433..fef663e2063 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.h +++ b/src/plugins/qbsprojectmanager/qbssettings.h @@ -30,6 +30,7 @@ #include #include +#include namespace QbsProjectManager { namespace Internal { @@ -38,6 +39,7 @@ class QbsSettingsData { public: Utils::FilePath qbsExecutableFilePath; QString defaultInstallDirTemplate; + QVersionNumber qbsVersion; // Ephemeral bool useCreatorSettings = true; }; @@ -52,6 +54,7 @@ public: static QString defaultInstallDirTemplate(); static bool useCreatorSettingsDirForQbs(); static QString qbsSettingsBaseDir(); + static QVersionNumber qbsVersion(); static void setSettingsData(const QbsSettingsData &settings); static QbsSettingsData rawSettingsData(); From bd9bcdb9258d221c13e1c2a058938c344beb0ee5 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 12:13:26 +0200 Subject: [PATCH 17/29] QbsProjectManager: Simplify profile creation code a bit Change-Id: I253671358955a970def0eb1343558135a38acaa2 Reviewed-by: Christian Stenger --- .../qbsprojectmanager/qbsprofilemanager.cpp | 32 ++++--------------- .../qbsprojectmanager/qbsprofilemanager.h | 3 -- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp index e32d3abeda5..ef93c2a4b0b 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp @@ -154,11 +154,6 @@ QString QbsProfileManager::ensureProfileForKit(const ProjectExplorer::Kit *k) return profileNameForKit(k); } -void QbsProfileManager::setProfileForKit(const QString &name, const ProjectExplorer::Kit *k) -{ - runQbsConfig(QbsConfigOp::Set, kitNameKeyInQbsSettings(k), name); -} - void QbsProfileManager::updateProfileIfNecessary(const ProjectExplorer::Kit *kit) { // kit in list <=> profile update is necessary @@ -173,29 +168,11 @@ void QbsProfileManager::updateAllProfiles() addProfileFromKit(kit); } -void QbsProfileManager::addProfile(const QString &name, const QVariantMap &data) -{ - const QString keyPrefix = "profiles." + name + "."; - for (auto it = data.begin(); it != data.end(); ++it) - runQbsConfig(QbsConfigOp::Set, keyPrefix + it.key(), it.value()); - emit qbsProfilesUpdated(); -} - -void QbsProfileManager::addQtProfileFromKit(const QString &profileName, const ProjectExplorer::Kit *k) -{ - if (const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(k)) { - runQbsConfig(QbsConfigOp::Set, - "profiles." + profileName + ".moduleProviders.Qt.qmakeFilePaths", - qt->qmakeCommand().toString()); - } -} - void QbsProfileManager::addProfileFromKit(const ProjectExplorer::Kit *k) { const QString name = profileNameForKit(k); runQbsConfig(QbsConfigOp::Unset, "profiles." + name); - setProfileForKit(name, k); - addQtProfileFromKit(name, k); + runQbsConfig(QbsConfigOp::Set, kitNameKeyInQbsSettings(k), name); // set up properties: QVariantMap data = m_defaultPropertyProvider->properties(k, QVariantMap()); @@ -203,8 +180,13 @@ void QbsProfileManager::addProfileFromKit(const ProjectExplorer::Kit *k) if (provider->canHandle(k)) data = provider->properties(k, data); } + if (const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(k)) + data.insert("moduleProviders.Qt.qmakeFilePaths", qt->qmakeCommand().toString()); - addProfile(name, data); + const QString keyPrefix = "profiles." + name + "."; + for (auto it = data.begin(); it != data.end(); ++it) + runQbsConfig(QbsConfigOp::Set, keyPrefix + it.key(), it.value()); + emit qbsProfilesUpdated(); } void QbsProfileManager::handleKitUpdate(ProjectExplorer::Kit *kit) diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.h b/src/plugins/qbsprojectmanager/qbsprofilemanager.h index 73f52c3d9f8..9e4b9600dcc 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.h +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.h @@ -58,9 +58,6 @@ signals: void qbsProfilesUpdated(); private: - void setProfileForKit(const QString &name, const ProjectExplorer::Kit *k); - void addProfile(const QString &name, const QVariantMap &data); - void addQtProfileFromKit(const QString &profileName, const ProjectExplorer::Kit *k); void addProfileFromKit(const ProjectExplorer::Kit *k); void updateAllProfiles(); From 472f9c30d34f60cd4bbd318f7e4b978bc20ae404 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 12:49:17 +0200 Subject: [PATCH 18/29] QbsProjectManager: Make use of qbs config --add-profile ... if available. Task-number: QTCREATORBUG-25463 Change-Id: I7fc8a06a5c43b35c4b1b571504d31cc03a95b189 Reviewed-by: Christian Stenger --- .../qbsprojectmanager/qbsprofilemanager.cpp | 17 ++++++++++++++--- .../qbsprojectmanager/qbsprofilemanager.h | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp index ef93c2a4b0b..96527ad3007 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp @@ -183,9 +183,13 @@ void QbsProfileManager::addProfileFromKit(const ProjectExplorer::Kit *k) if (const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(k)) data.insert("moduleProviders.Qt.qmakeFilePaths", qt->qmakeCommand().toString()); - const QString keyPrefix = "profiles." + name + "."; - for (auto it = data.begin(); it != data.end(); ++it) - runQbsConfig(QbsConfigOp::Set, keyPrefix + it.key(), it.value()); + if (QbsSettings::qbsVersion() < QVersionNumber({1, 20})) { + const QString keyPrefix = "profiles." + name + "."; + for (auto it = data.begin(); it != data.end(); ++it) + runQbsConfig(QbsConfigOp::Set, keyPrefix + it.key(), it.value()); + } else { + runQbsConfig(QbsConfigOp::AddProfile, name, data); + } emit qbsProfilesUpdated(); } @@ -228,6 +232,13 @@ QString QbsProfileManager::runQbsConfig(QbsConfigOp op, const QString &key, cons case QbsConfigOp::Unset: args << "--unset" << key; break; + case QbsConfigOp::AddProfile: { + args << "--add-profile" << key; + const QVariantMap props = value.toMap(); + for (auto it = props.begin(); it != props.end(); ++it) + args << it.key() << toJSLiteral(it.value()); + break; + } } const Utils::FilePath qbsExe = QbsSettings::qbsExecutableFilePath(); if (qbsExe.isEmpty() || !qbsExe.exists()) diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.h b/src/plugins/qbsprojectmanager/qbsprofilemanager.h index 9e4b9600dcc..745802da8de 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.h +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.h @@ -52,7 +52,8 @@ public: static QString ensureProfileForKit(const ProjectExplorer::Kit *k); static QString profileNameForKit(const ProjectExplorer::Kit *kit); static void updateProfileIfNecessary(const ProjectExplorer::Kit *kit); - enum class QbsConfigOp { Get, Set, Unset }; static QString runQbsConfig(QbsConfigOp op, const QString &key, const QVariant &value = {}); + enum class QbsConfigOp { Get, Set, Unset, AddProfile }; + static QString runQbsConfig(QbsConfigOp op, const QString &key, const QVariant &value = {}); signals: void qbsProfilesUpdated(); From 9706d8933578b49ca12da61f36c0e3f61868eed2 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Jun 2021 10:01:38 +0200 Subject: [PATCH 19/29] QmlDesigner: Fix warnings - unused variables - mis-ordered field initializations Change-Id: I9f265799597e7c0f4f41cbb20edf19c48cae4c0e Reviewed-by: Christian Stenger --- .../components/annotationeditor/annotationeditordialog.cpp | 5 ++--- src/plugins/qmldesigner/components/debugview/debugview.cpp | 1 + .../qmldesigner/components/formeditor/formeditoritem.cpp | 1 - .../qmldesigner/components/timelineeditor/timelineview.cpp | 2 ++ 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp index 48c8c34f189..bf4e3ce74da 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp @@ -43,10 +43,9 @@ AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId) : QDialog(parent) - , m_defaults(std::make_unique()) - , m_customId(customId) , ui(std::make_unique()) - , m_statusIsActive(false) + , m_customId(customId) + , m_defaults(std::make_unique()) { ui->setupUi(this); setGlobal(m_isGlobal); diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index a8b0b34f10e..62626b89cd7 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -515,6 +515,7 @@ void DebugView::currentStateChanged(const ModelNode &/*node*/) void DebugView::nodeOrderChanged(const NodeListProperty &listProperty) { + Q_UNUSED(listProperty) if (isDebugViewEnabled()) { QTextStream message; QString string; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index ac9fbab89e3..8200558d182 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -60,7 +60,6 @@ const int startItemOffset = 96; const qreal labelFontSize = 10; const qreal labelShowThreshold = 0.25; // Everything lower than that will hide all labels -const qreal defaultDpi = 96.0; void drawIcon(QPainter *painter, int x, diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index ed35459ded3..cb9ed8f0cd4 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -420,6 +420,8 @@ void TimelineView::customNotification(const AbstractView * /*view*/, const QList &nodeList, const QList &data) { + Q_UNUSED(nodeList) + Q_UNUSED(data) if (identifier == QStringLiteral("reset QmlPuppet")) { QmlTimeline timeline = widget()->graphicsScene()->currentTimeline(); if (timeline.isValid()) From a10728639a314d5f22b6699b35da5b487d97c460 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 25 Jun 2021 10:23:06 +0200 Subject: [PATCH 20/29] Doc: Update info about bookmarks - Update screenshots - Add subtitles - Mention that notes are visible in Bookmarks view Task-number: QTCREATORBUG-25642 Change-Id: I83e047306afb56382b5de21038beeaae1c00ecc4 Reviewed-by: Eike Ziller --- .../images/qtcreator-bookmarks-view.png | Bin 2216 -> 2653 bytes .../qtcreator-locator-bookmark-filtering.png | Bin 3514 -> 2369 bytes .../images/qtcreator-togglebookmark.png | Bin 36822 -> 15464 bytes .../src/editors/creator-coding-edit-mode.qdoc | 9 ++++++++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/qtcreator/images/qtcreator-bookmarks-view.png b/doc/qtcreator/images/qtcreator-bookmarks-view.png index d8734cfe614b8ece8ea959905561553393d44c25..70c3bc2fe3d3351eb54253f3d13eafcd380ea067 100644 GIT binary patch literal 2653 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 Q3=9kmp00i_>zopr0LopSBLDyZ literal 3514 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 diff --git a/doc/qtcreator/images/qtcreator-togglebookmark.png b/doc/qtcreator/images/qtcreator-togglebookmark.png index a09e9ebfd8968524de4fcf08d1f2823e38e6ade7..63db3e2bb52e3bd918ae44f0c4b50aafd4c5ac2d 100644 GIT binary patch literal 15464 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 Hl+XkK**tk6 literal 36822 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 z zr^7LYojtqk;+W5^;@N$6;wqLc56|8Dbm`K&kGcz^RNEny+u=!?rCHZ9{5Cc3j!#H08pIkSGC<=(Sg+TfE<{-Eq@-sh{@bQ;yr_E`4?3|9AU8-Zzax*%z$4s5K+F z?ElO9zdPMcz4Pm0y_wx6GvsLTUSe`mI=v`tZBWBv&524;yqk139_eSbzM{3kKd;kx zUC@3#&Uuk_YkO3bQ&Ra3OQ{U`j`BGj^PnsYoO$rloU+FrFedlccP490lHD9m&CF;Th!^9mcE5C%KWd_t< zTyTe}_NObi*MZU$-<4vUrIqZre(I>78MIyV%I0OC-pI%Dcb<1C)#pCI=>$%L{}VO8 zrX8F#`|9F1o{BGaO*#Ig)1+v^?KH{#erXz^Pp(8?pWl9EqGiy8ez*K-x>ugx`16+k zZ9H#Ls)BNFRkq4c_WJL^_Z!%b?Tk!axz%kEqueQrExn;kiOKES!Q3ycSq>Rx{&!Ik z3*J6``trw$kjb^0;?v@n#G6+byYwUg-rhOmbXN8gK1)J8rzzX*d-GYS z_`u|*_AZ}w0>%Cwt50iZ-`3gL<(O0R=dkom=GirZH&$PqFE3_OcIxeofEOkw8l(^W zENxET!u;vet79`A7ERGK&HAXA$?C6QSRvFZv}NU#!pziz{HK@kIoPEZq)DIkoVe2R zHP3{}hgSSjOL_?k?OORBb+5U7_Azole=N*)y}so{hMAYn1K8nVs_WyhM zzU~kA>MeGY{Qtwt>g8+Z-saSK6%_m7aZl;Nv{P53`D6FKS^xi()xy%sRiBRi|GwRR z@0TSNHSz01wM?zdDs`+6-TwG+@rR@{4uKc?|G(NFU*t98#?#l1i?*Ntz#CMss?6fKmTy{&XBC{($5XeJk0e~ zzl5^=yj}mp`S!lQe}kSM7ySBpn##wjQvuK1|DV^7V`;a%yZ2qUoa0WL4cuAbvqNPC z%QEL4e!KBrUgFyX5C1isU%j>F%*^23;1~5&u%^CJx3(uWjmPHafnq18?1Do518*{X ztDZD3aY_~nynT9d+>O|MnNv4u-tyS_*3uz#mWe{{>|f;{eC4#hZ1RhJu2cE%liNF; z^EExSUpC(7sn-7btbMv%gS!yl-Gp1T{X(^d0kTA20q>(AcKX`1_zV@sj*jXD0jJqHDjq-|dE=;!C~ zwUb|@%#SYn$lU!ymFeXa?Md~CUuv!5UzeNrEisknownO*|C@Q4+#5a~c>7@T+88eN z71Oly6}GCz{%iIA{N~T4Lu}4on&m}j-Ysa5b=K^^G;4Pjb91wi`T;HO>4LN8S{hyw z%$dCDOr+raeD$|;`PvfPfN#l2cnU_{1mMuNR$Z&j^I}FPd9aU zD}1@7`9q4mM_u@*q8^`W&E`afbHC=V5%&MG?C2wd?cz_TY;K)kUB2gXmQ|GXvT%jrXSgnV`-WxW4M*(e3Z6L$0RU{=2a3@dU%E4=YZqZP{UT_SbWH z_43?+W8FFHZT!|}<-U7yd%?%h6BC3}%){RLPqV5O*|5lT{<$euwK6-F+1x+6EOzJf z(9r3b-xvBmZ_HS#`)FdXdz~k1SzpOE>ld|;{T#|_-MQK7oz|7^to|LClA3ww@@_|F zk!#-^Zf&+cU%cAedEU>dyc54YI~^a>8JG0VN9KZh1cA=DXb5+0Pjx39lbD;FIUc+YUR z+Y8--y^{UudMz~{L^iJv+EjRNf5{u`#Bb_W_iIJ&UAWUD6_vv67*@U1$47SE`qgLp zYl_ax?me_1-{)$mNc-+v6~~kNXIwrw{Z2v8-b3tsPcOf=?flm$C@b^$XZR^zu8+K| zUuzBKHTc&jJ#t76@+rxw`pFcUWs>E8js5bYq@<)t0iR10Q%$sW7iQ%ge>7LoR>_B# ze;tQO)VFu%p8cBVvwE4(vI6JTL3OXByYC9-$79}b<%{rz?Krs8a)nsvKH7nmR1?r*b=%Q7eGD@o!$Dnl%jd6*K_&yd7aUSwRxZ{?s7Q( z*tO*<$C?+5m-xxPS<_#7{xa*9mER7^Zi~^oBcCmMkCj2f8A^% z%}T9dtU{-oYf?9DpTM5|$y}Nt>*=&ofh|#H!E*24hq_*FjJUc$WYf(cHkD&j^sl%@r#d@tixgXzNLx*?PSn3)e4@K4Z0Y%K68i zT7y_MS|3DP1qw(?-Qkov{@i^}!TPj_OO6pyV*76!MYsz|&+tDbD;u0WeX3h?gn|Hb zbXSn3DCZBS&ZxDUWCGTNDEW4`)aXrDpK?mqfxTq<>aR61Wh?f_+uqIz>tJ!($nr=U zoDx623|bmGf6dk(_c-P~ZH~!YGjY;~+2-%>@2a)l|J)-v=q<14joPfQDi==wE_`xf zpNrc|?j7a7_s!n?dve1v&PP6XPcyuiS{7y*{`=F)$)}62f5~j~SR2r|=h)`di+yGv zg}EO~>QC-!<2R8y7m#?OH~M>iqXz){nfMLMIKbXe|9$~#C_5Az0&gW{>R?E@R@aTm%(&#zVbVl&2KdIo=Z9} zz3ra9wwAH-(`LXu%g^hEp;vQzb zH!s~XDX&(W`z3kJD*?0&GF>+KPb?Wwt3Ud)5^P3%XTT+ z+HA-xT=VFc{atSzeQoWvk}*qHO-=ZsJ6ETNkN;@Htlhkf=kEl!T`)cWmdi3>?$%l2 zpIL0p9@VOrgso!#HtXD!-J;n~_}1_K|MUNk^L)I~3pjEYo_n7sb2BAPe=*a$BRNuM zbDWy@hraprF>GUaK}OxW^RllOy}bJI(UA)e!Y)|XgdXw#_q_i9d={}@zmg?!e^-Y7mRoE6 zt+ToQ<`b9MkJ;sqlEVXmTYc5m;N z`8!M_|2>*~Ky>TRl5JOhK0Y9-yXirZX_nai%J190AGqamsJT6|xqHW+0{-h#3xC!q zoqoPEHz{jde2nLJLvM}n6N>vlCDp%AAJ+zG-eljrRdR){V!@SZd3;lB%L_`rc+9ey zBE@rSbE{hVa&gC%iGK3cw8!ES7ol-+KVSOFY7j*KQJx*pl0uHp}mg!aj$jDiV8|T`OUSRCfy_T%&olRu<`M9 zJKf^tY|RB*_Hb>lDcaQ5*L6x_#xc`BNn4-1z zV2+*neCbAExf=|34ji;9)%g0WbbaMCksl&iy=h+)*Z+NLy>zn4;+r`aR;LOXw6HHd z^Zfbqs;y2<93Q=Gw&xg0e)aHPkb3v^w1Y15x3eDD<;OhdP-@nPH38ZpTCy7J**bfA ztx~jKNJLE76FK4J7Po-IDMpfxkxSi{UtjI0ez3`}J;ZF5&w|^N-f#cP0xr^;-`_W% z&h}C0$+wi>cXrqRKgG`fi7o7E)nO~O-#2StM^DfHky>sL5+(X&6R3=6`tdL9n9W3v zN*S^4lMg$mbZj;&IQnd3q>ouU|BbwlhufMU<7Q!PYpQIGKb5Q5?u%`Qh_wl_FH`_G zY!)hjV_ab$l&=V5fLc9Z{7>lP-d)?4U3>NLybu@HBk5PWTi>7R{Tll1<1?einp2Nu z)(Lw2Hkokm5&tQL=Wp}pulna(r{MPP;w`1b$;(X~A{;>Doqy$O!o%K9GQTz}S+6#w zSy33uXSlbM@@ei|f;Vv8?pV>i$+%)~6ZAGO_ulx8%dXeg6{A`OVX? zd3|Ti8|{*xyXF5L`?hg%an4P-OD!pT^p0M?zP)bB0^54uH)nSpJl82Iyo6N*G-mw% z@b_om_En_Y9Qqdj?#7LneOXg4)fef->z>UyuwHnYm|9lR>$0tE*SMY;o%nHvcxCl8>8Q$v^_piSj_@vVQQa~*)ass7rdn2I?*Qh2?rDY{H~(H915X2gqz!*qUP;$#z1@ zIXmd=!`riO9hv{~-3(h-uY%>D4qI!Ay9vdVR;XXyb9>6Aas_ryyDZ@>*8>k0#rx~M zoxcBP%&BAjD)wJEx%q3KyolNR>(-n;{r4|t-E7#<(DdV9vg*VRi=1aKUutsrupZjA z@2(b`Wxc8sU-wyY&rm7ejtJGiIs&U_oKKxUciyHSP6E5U)c!IvMorwdFHazRiSqs5 zZw|+c-j|xXsl3EYX>(F~`SX%>yA{-5AIXS$qwAG_=Th-;pOz(hU676H?F+?UYzCWW&f{fqKZa~QkqXizBrL77b}r-&il-4qwblm3;m0i zRV*u3?l@{UB{2N1t!ChgUIB>!f&1~{UVA&QPk!?A#Gvs z*$*bUF36j5Jf-K|#+&Z!?j?O9FXzRi2jwMfURziA@?G=q^7%i$_8O z{_y@(_Ug)z`He@5KV(eweBkhBZ|?o6C$`KDO{iiL7yWr(A^g`NizKs#KVog&8{hA| zm|!q(zVw$9`yVC6u4iAIC#;dYMTC9o#Jz3jBeGZKZH#Tsk@0ZjJN;iS#Bi@!#_O-U z&imY6p!!75=@uiWEssa&;)_N64$p-(I^NrJ-TxY=zi2bNf2-2IfJK)*ukGTNc`LhT z@t?c-$8|aV+Ph9&oWXT_|L@!K{~yIYV~AYOsDESA%}*Bk)01XRxEUiLAHR8t$;#`y zxn<;RE8jfnixhm(8+FV|?ZL&#>ixO#rSGNA?vXOze#h+4x0J2^6(9ecD#><>3-da% zIXy0R^5@oxeEo0dT|YawX^*9G@5a1$>--8s*_BTIt4MDPPe_UL4GnWCDLH=dW6F&5 z67z{muWKkSxc~pM>W=LPJ`4TRS-9Yz(#Nxz-?smJUjOgLsb7(f*V&q{y)FJ-sG7G| z`R>b0Qv;eBrj-2j{Q4&6-sARp6HTRgCVDNrGJERj-i`8q&ib!ivsTVR#rKlxoU>`$ zPn)GKKJu{ZMEdzj*Ka)OY2Uu+lzLd(>G(UvZ|&`}zJBND;PUU_$(XnJB8TYyzx(UN z?iyU0{r3&~{*7y;>s)INdwvcGs6V(k|9Z zw%7i*w@NE62)>vc=vhz61#Q%+xmas|6dl|%G-5e`l~&8Ey7>Z6gQrH9K~@lLu`$C)!iXx0G#*d%uPIz}*v;I! zx;^0ijslsP?$K+?cFXKpWM({V)m=MYr4?t>xkKNXC#Q?uUX$m(j=NtgM%MWEGxzSt zH8xqSX`g-e{hz#gUff5=sm-qsnCLf0)lKV2+*)q_?%wX_Q$nhbJ^hki z8MCkQzNv-6q1`FL9xK1~$}T!lw)=A4-93WMYEoOI)&}mp8lUm`;?v#V-`jrmh+d#w zVs$Me^2pif@9!h3%O6;>ZO+PHa^v5st9zr(ZoZ9{n!G^UaA#%3bep&bZv=0*W}oNN zxf3LHbM{^Ry`K*-b$8Uh4Bv9pel6Gb%~d~+yj*FYR?B@qZrapq$|h3N0)PH&6+X`H zTz5WZmHKznD$ysP!2yvY+n+jcJvztE`ytOZ)cIqFe`WHoKa|A9z}kV-#dP1n7}1FyEET*fYRk&lKJcC@Eib=*^=jz#D^sTL z@$&5I_xI4(TDyvI)w(maGbc?84hW47j{PdivdXN+yCo|p%YA#GU|0sX708SchhYPZ*O?PH2?TUy@^-Xp7quB$X@%R@0eQ%bH>Jn3s-Js zzI*XnhtstCFGXK)uToMpeNp7_;OT=cPrNqpZQE92Hq9+H{rL2&+s)!cvR`FnzRk(Z z%XeygdTrUUXUoz`vZKSLwd~FRbmcFI^@?O&rDJ6GU{iiewH(*o7`9dFQ%oCPedS%T zY}vGPVF7zra$db~gJat4=m~M=+sw9?nJLTGEO++p?M4=3 zVJa8 z&z?@K{Pev~ zo#5xvJFWBjmHdIEi@lX6*E2Dl=GLkzX!iYSIn{FMSN+FDe-3BOu3~!?yr}N$^@EP4 zwO`jK)&C1`T(`ce{a1ANMfcixb||}*KWs|^WL5NHNADGqO0gm-VB~ynzq(Iib8f}`^A-1de;_D46m7zUHQHs-aWB! zQ)x(`(_7JldWDEFK%vb zQnqSWk63=??9-`-7hj&rdFR0wwG&~L=OTH_3o_@bp8G21w&Yp<$H>{*vn&2w63Bby zv%)nmacx3rT1G}j#cLm?YYt7kR;lXWD}BEHPzqmT#_`>|IQdY}Yc}@6AIgkD4iyG{ z(o#}$le5o#on(CI%%Mv<4_|!9DK2}~vA)rz;n%!JzhfI)`XBWEm{I1lFrZ`ej(Ptc zHqL8YnX1&fY5)G+hNgB#O|#{t=ialjxpTWV{_UGL4em@8U+t>hdDuP~o%@j^8kufj zcl-RGJHOtG{7))<_B({#(pb~>>e+pKFLumm^S(Fva548yy_f$VFaEXM@2DT6u{Mw5 z`--)OtCej;WM}T!aPH2_Q#$`H>PN@MMEzZ4wb`mK?Dy_R&8uR%)VQ^0uhB36{_y*= zf*l#}w=FpEYz5PwKVqfXOHN! z`;xaq{~KoImCf#OTK->c|2e^{Lfy)5jr=)U{$2UUELSgXYcs*@_{8Fl74tr=zItQT zRAbBehb>~V4lMj@ec|KX9ac=KMVo$o(k^+u?}*BcwV7vs?Wmhrap>9JfAWf9LRM>4 z^$t94&CZB=`J^*shq-jd*Uj-URc}6?`BhePRxJ3~-P!v7-5g)Pb?IkXi+D;Wzgb&f zY;R_A;=1|n;=KPEyDawB-!EFPwaj|cs`hEYa(`c4pFVfb+?+RD1zf#vQkGgP+9(+r z>FrK?(W1L=$6EGaDY2g(tCG$>TyePheqF`kgZJ%sWK2oAwlUrC>BEB)Cwk7*-QoMr zasA)>|9{=me-ra|ZcP4tF6Xn_UnXz{+^?>Q7l=tYDZgiT!|S(lv9Y)B-MV8X=qa&V z`*U{m?KCwxQ2=86r;-o0?K)G^t9QTtwMp`cECQ|OKm*ONRmd^EZuwUeTML}Fl zgJGNIjN|SxoqRWQZ|Wz=%-@un-z6=2$XIIb>blMALO;HAR}bo4x=S!;vT^^)n3t}l zDzUR3y!p|i%)WBV746=?{_m4*=a=tVc!Q}qYjO6j1sp9r_g$w8-!4DHcD2qgYkhzC z<6h~*dwDj`GQC0l*}vk=HzRLFu3(Sd>7w@886(Q_}y+ZyZ+D7-l6`B+(gG$ z_wVGzNP5SrZp~f$Ew`EDb^aN7wdRYH9{QY?d7HKBl)h(o26L^_wYJcHMy2^G$ERMB zh8~%_`wvfdNjsS4UX`JHscBwZcx-r##QhywJ6?z_RA1k*;C?>e`uU7E zjm}M)9H?|Es_Mbtc0a~{|LU%Vze`Cn)91T0H^BDngIJyQ`U|9w#p%!femiH)+By9URUOoA9cJ&UQD-6z@GZ|Pv{&hPrVbgvivz=8rCbKQ9UAX)Y z-MBqVN?KA@?&a~bhCh;)KB_JLrSwvD>i*xKjU-E>*8Vdtez{ZC?M?b?wYg!7>(!li zI4)ea8Wnw2l=Mc4HlXMG|&U*gM?m1i3n1NtqmoquH?AT;~eyl}6G zlCwW)0;-2R$`JQWZ z?BG@-xi4$qMzXDcv~TiS!)2+<19xf*yw^@)Kh9iNte*b-S@E-oV_hOPc1xVjO%&Op zFjw98`S;#*xjlP>oOF6^8kg)a*v#L)NUe-BNHu)rqt%X+P9*b`-rTv*HgVC*PghQ^ zc`A_g@SIv>nqi*Al|#nIjs_oY;NpzCI)mSetF8awg@~?`Z_T*iwWPjy<^6c zFQz+Zy1Fb+=ZQS`e8s+HD_DEGP9InLT6$&Ioehl3ey*_1pP|RBX=Px!_u1vMm*%`! zG|yIVy0*Xv2bYK4_xw_}35M?Ce&Js-UG#fXoMd0wb;~IS53Kmo$;+m3{&8o?bDt3Z z^IuG=7o^NMe|)LAfA_-|(p-;z8#nKW(R*|uJnh-^Y15{KYv>pw{k9`4 ziZS=C=iZq9==XV*e_jq}CSxtiT*~_zv(k{jMEuWs}J4r9-!?(6S{r^8K-hKL# z{>wQ<$?Ubu7k)nYAf=|h`}Bcx^S*3IS@_$}`jnJy@CIGOQyg;6hxY{=zua-IL9~xS zA!^?|i(AjzUvEBsX2E%ZH!E2m^WR#2Oov})afx}pT=i<%uMD=)TXYRG{C-bQ3szfp zSv=gjpYd~P%iLwJ&!)&!9@yExsrk#f9aq0R{{Q>F<>D15JpOMu{V>lVFR8{S#H;S} z9=AQ>|36$mAN1?n_g!!6YIpBQ&t13O#=>Bgg~^pyzuGeo-`-*yGihtJu5i{xu4W7mM=A5V_qUB^iBW6*~L0NxT7G&*jOU@7)s4Dw;5B^(({T zJKdXuHx|gQIM(PY`N_^n`rXSn^KaNK&i_)jjekNz=n;q5*KBrrYj0FeyOlBJ^YL5K zx2$eQOBo(v?!J0-L9DEsxd~sOrMP~`oTZ5mWG=Tw-$^qrcfWnxJ*<3sTKabL?cr%{ z9qCydtQsBf&kM^u(GO@2;m8lvWq+M;IJ~RlZ|6f4QtlOXTwmvmu*YwkiGOzgczNkS-2D^!iADDR z?*_Qu&!0CX!#7?>KmPEVkc6l2b1nuhfBxw4wO!`+*-oB|P5eDe;)7zhHN~xb^LMYF zVAefH=SL|)k1}%pJiF5Ovfsvh@{0v4i}?9vRv#2Uv3PBl7GLPEr{awpx5P!96|8j) zw_cjDIw#L0wPfSVfRE3foNwK;ciZFdAAVlAWO#b;s_rj~_)sUhOfb!V87i1^ZtA zaQoxaqGOcVyk)QRLYdD;v<_Z;_2CFlW_yu`HS5m%srMagq>s86e@oP!{JKcZz5ZbK zUa!h6P6u^P+_#uGKl_LgoBQf38ApXUGuhIGt4}1Ih-l*8BW02D==2=B`&>6&6Zd)* zdMro~d)jtB^m^o~?(6D>+X_SUg3pP~i}up~c3fP#V3KfKkG|>4CAT-O>-Dd>_G)!? zlkxX$E*_jK9gZbrT(R;FF4`KgQtU%Y&PC}LFRtb+b6R1b@g&Rg!#T68A3mDR3&R-2 zR+lT=>z1CL{^CqgPyR*G!+{SaX(Ynp+r}?G>)PF-Q7Ikf8q(7H+PY9qIypVlDT#7Olw0`NZwJF47_9!B#H8 z?t=oSCf=L-dP>qpCmkV!$eP2ivy&%%bVx8->9%shmf>rnc4ZFfuaTzq$U*1CB<;r`B0E3#VT(iM;Q6cW>j_w}F{wk8N%}Dc&C~ zmr|^=-@Exwj_yhBp+w?y7qKjvjEJ#@LtCu}^a{BXQ#!fHRo{|5v>F>ha z^djK}^H!{v??2Yub$h8~w8VqW3$63~UVr{HM<-9Hqf|;s>hH^^ZMVOjy)N(Pf9YV{ zxd`9=UnlRI;Buz+_QzM1y3GdS?=HT4YJ1ygdGM;#;FGHUm-v@`3)}m4gCwiYR7az* zrsA!+pL-(bGS>AE!|6~2< z_X}!&9`-*T<$d$#o2QBC^50i*{*}?+^_P~&{xt@`MoAD7$0 zqR*tLOB+mx*>ob|#hK@?-kxFIcxa9N0-jqYrMuR8=*??B;At#+{pD5bxLwRXWltV# ztNLyEWUqVSo#LJQ_IKp{IrKSY)h4#v7ek}>Cm3mWGtJ*=Tf$$kWpnL3JLjoBSB}~5 zeJb)gE&sQ|j;a|o9~%Vq-kOG$L^7=@IL*A)?xT)*cB}8iYx94E1gLRd4gH(IFZXxV zq9zV8vtQh`d-fz5d7HCl*_PgU{B5d#{tf#bxuR`1EzG4~w5;3U-hcOx@SZnsY%cwN z@@MZQm3n>s^*dHEPUE=6x$xheA8dweR%l;t-h0^i^6A&Jt7T@!oU*+c5jkW2?Adda zFGU=(FS^wirud*hHUGKqtS?1+-M`OCcx$I@R#~ZweYLkr za{AHWy}_{`e!endoUQNZ=EgqLvo`f`mT9TZ)(1JanGzRg>Mr`?!uf4h#9hhBzPA%@ z*9E^x5c*U-@B5cI(J7ff9{(-uwL1MV^!D)|CRftiIQI&M*gGFP?dBH#E9AA@jcw8L zwo{sX9Oo2&pP^oGb%x5dSKVDNDnm6Gf@RK^_Ds9f z*|LK#d-uyiy9cI*=kjvrEl=jAH`<^~HAbF1hxp_Rp7`hXO{8LC5c&I)6W2a>m(p51Y2LeLVQ!>yOw+ zr=q5%FE5t~`g?Hk&26Fud208IHjnSHOjer56Uq|4FbQ`}WToK;lW$n8hBl?NHQZ?d+XC1-Ssl_FU-1W!j`vs zPnx3hLuKo! zj31Ns{CO$d9O?e)3r}pErNnyPP1S-^1?1m9{9vK9UB2(Y!hdIeu%(uXwIBP)u8_x3 zUYx*|!xwUGzgkcDw2txSe(v8Z+!N$F%66}C-SqKR!LF%2yJko^ zWphNTDP0iv4fokA!@&JyN}0E!mZ4y6UgwnbC7;7TUwHq|W&5N6F|U~`zACazYUO*J zdikYAN_f_8ftv*$J_jP+oU@4ex8mvB_%#=2wKU&#t}Fa8rRU!YsgFA&cV02en7zyV zg0=M1Z3g`X&lYICW!YKud-lx9$4al1FkdT@EnlV-=egZ1?6S@8O&8gno!Jj7-wBqh zUX@om@tpFSPvxGsV@uh0^nLtxm77I=`@Wb}t0Qt=Z;sINIemV0-*xeinQ_gP5=(xa z(D?3B^sk!7&#Tj8-L^9)uNYmQG%o{a=44&Fh=7_3y&N z%@3K6t@BZwCh*7YxzlTI`Sp*K#ip+R|B`Fxt3yS}cCUQv3hthI*m+jHye8aY)#k1H zHgPpAy--%^8+rUvj%(HY)C+58XZY$zIdtem+{w+As4Je;b!$q^orw5K-@A>+)+p(@ zRI-Ha)B3`FLiKcGCY$(2g>{>^?>Bl^Sz}-E-cbMgQh%lSJ`r1-DMwx$NN!nXLOCeq8pR@hHI*RIYp*t{z; zX0LV2-Is3`IUBGu59{@8=Y$xuU_%S_6plKwKO^JhjUi`{Jg}lo%Pq3i$RZGRG2dV zjI!8s?Y+JGs#pmQ#*1PT&1Q(+nDx9{srzT-#`Aa9DktTa=_Y8t5#HLdXZsXyi#bc= z&KIN@$yO|%x!pOjc$(N^_G;npdTUg9=hgqe{#~h2(&ONag5shNrzLNwt({U~`^8)L z#r&+^ig*3*Ub=-}T~zg}za^XVoSdnK$Tr#N$iRJ?p~26Nc`d#iXTfUr{rnuoji=8D zF}*riJAakgrju)C>vvZFIg&ng@$$0kt-Hnh*C!rU3UV(Dc3l_#UVU-on#*^dn@=`~ zesh^|`)#|;tEKO5ZFNnZad4Z{Y-_&P)rT&>UHB>7bn)cLlZ&lmSm*rb{QCTuxe>$k zlM*7A9=&-aHkEx@wAPV7&ANx)+&N@6l{4qQ(aZ9SpIdf(GD=#P7+1PwhlsGD{T98u zGIM!3C40Lh_&D!NxVwdH+Boavi!V2?JXyLaR8-PfP;{g1Uj4cGlD%Cw?^!+jcCDwi zwa?A1rzPb=q>*H1#jPM&aiNWtwJi>bON3U=o7A&DB7Bn7vBgSd&-qk0uei7(@;D9y>XOTb1*2J*-Rp5#aLUUf-oPi}J)w=g58Ld%da6`O@~N)#6g@J7;e$o_H~P zZ}yp)Z5L16kTuYmGU?jm$Imt!7d9S!6l@?dW&YRHzLu7rrCT>^bRXIBV&N4nx$wg; zy^p)PycIZCvWK-M=|n)(Rn7ZCToZgF`gkPIXWenUn!iANLgxqDmxmYpI-O=FF3B=` z$C6KTZp`z&I6cO?wLrO^OWe{*%BYEZ_M$glN4c#hFLYi!G5N6KZd@_igTq*y-B6`mv((j*iq< zazX}k480buJN5PW73NQ_#cfyDt@-jxk)i%zT6~O4ir4qHxPz~>y7>CFSG;`n(pzi& z2@ZbW?8TX9q+V)iZOK`oW@w_4KaJ1r;ir$A&RqDgp`+u&hZ&1X=cU%@EPY=2>*2)j zYF9&&V^UIFwCAOoaT+WQ72dr^H77H}BPlw&Hcxk!Pn@<#N6l4>{d?Pb`+3$!Jejfe zc&sF+{$=CEO-1G&3qG@*3Ms7c@bK`tdPq?E5$CJ({qL_AKWUu*Jv%H~W`Cpb4yS+9 zt#jQEztKJPtKw_xQQ3E%`>RStnWHZ}eSA}VT7}ERy2o>^?PF(feSKN=&f>Dw@~iU> z&p#L)`upy`x5vM~64%Q~c=mD90sgu=(}i`fzQ-q|9xy`FJSt*X&# zXB5aa8U*}>a=8rNv=KQzZ1w47aIg}vdv#?PHThnBy4|MrdC z=N6AY!V^yY=qcNDT3l(lbr!_w3wMtQOp0(5y9KyW_E2(W-$r63lwS);55)ylbqm d*WLHOKIc@rrJRdp4FdxMgQu&X%Q~loCIH5jy{iBK diff --git a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc index e77e8305328..c7e25fbcd78 100644 --- a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc @@ -201,6 +201,8 @@ \image qtcreator-togglebookmark.png + \section2 Adding Notes to Bookmarks + To add a note to a bookmark: \list @@ -211,7 +213,10 @@ in the context menu. \endlist - To view the note, move the mouse pointer over the bookmark. + To view the note, move the mouse pointer over the bookmark or open the + \uicontrol Bookmarks view in the \l{Working with Sidebars}{sidebar}. + + \section2 Navigating Bookmarks To go to the previous bookmark in the current session, select \uicontrol Tools > \uicontrol Bookmarks > \uicontrol {Previous Bookmark} @@ -229,6 +234,8 @@ \image qtcreator-locator-bookmark-filtering.png "Filtering bookmarks in locator" + \section2 Viewing Bookmarks + Bookmarks are listed in the \uicontrol Bookmarks view in the sidebar. To move between bookmarks, select the \uicontrol {Previous Bookmark} or \uicontrol {Next Bookmark} button or use the keyboard shortcuts. From 6d26f4f5b0a29c11b4fe33c630a62dae4f8eded8 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 22 Jun 2021 14:08:20 +0200 Subject: [PATCH 21/29] CMake: Allow autodetected tools to associate themselves with kits Change-Id: I5b48ddf36ba1b9c4eb6476017be63c4d43b60627 Reviewed-by: Christian Stenger --- .../cmakeprojectmanager/cmakekitinformation.cpp | 15 +++++++++++++-- src/plugins/cmakeprojectmanager/cmaketool.h | 4 ++++ .../cmakeprojectmanager/cmaketoolmanager.cpp | 3 ++- .../cmakeprojectmanager/cmaketoolmanager.h | 2 +- src/plugins/docker/dockerdevice.cpp | 3 ++- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index 24669a58a53..925c240942c 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -272,8 +272,19 @@ Tasks CMakeKitAspect::validate(const Kit *k) const void CMakeKitAspect::setup(Kit *k) { CMakeTool *tool = CMakeKitAspect::cmakeTool(k); - if (!tool) - setCMakeTool(k, defaultCMakeToolId()); + if (tool) + return; + + // Look for a suitable auto-detected one: + const QString id = k->autoDetectionSource(); + for (CMakeTool *tool : CMakeToolManager::cmakeTools()) { + if (tool->detectionSource() == id) { + setCMakeTool(k, tool->id()); + return; + } + } + + setCMakeTool(k, defaultCMakeToolId()); } void CMakeKitAspect::fix(Kit *k) diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h index 1414168acb1..62b5c9964ce 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.h +++ b/src/plugins/cmakeprojectmanager/cmaketool.h @@ -109,6 +109,9 @@ public: static Utils::FilePath searchQchFile(const Utils::FilePath &executable); + QString detectionSource() const { return m_detectionSource; } + void setDetectionSource(const QString &source) { m_detectionSource = source; } + private: void readInformation() const; @@ -126,6 +129,7 @@ private: bool m_isAutoRun = true; bool m_isAutoDetected = false; + QString m_detectionSource; bool m_autoCreateBuildDirectory = false; Utils::optional m_readerType; diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp index a250b1cf4fb..42beff4b932 100644 --- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp @@ -177,7 +177,7 @@ void CMakeToolManager::updateDocumentation() Core::HelpManager::registerDocumentation(docs); } -void CMakeToolManager::registerCMakeByPath(const FilePath &cmakePath) +void CMakeToolManager::registerCMakeByPath(const FilePath &cmakePath, const QString &detectionSource) { const Id id = Id::fromString(cmakePath.toUserOutput()); @@ -188,6 +188,7 @@ void CMakeToolManager::registerCMakeByPath(const FilePath &cmakePath) auto newTool = std::make_unique(CMakeTool::ManualDetection, id); newTool->setFilePath(cmakePath); newTool->setDisplayName(cmakePath.toUserOutput()); + newTool->setDetectionSource(detectionSource); registerCMakeTool(std::move(newTool)); } diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h index a8fb3a24329..2f71ddf34c4 100644 --- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h +++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h @@ -63,7 +63,7 @@ public: static void updateDocumentation(); public slots: - void registerCMakeByPath(const Utils::FilePath &cmakePath); + void registerCMakeByPath(const Utils::FilePath &cmakePath, const QString &detectionSource); signals: void cmakeAdded (const Utils::Id &id); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 563a4b63aef..5510972443c 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -491,7 +491,8 @@ void DockerDevicePrivate::autoDetectCMake(QTextBrowser *log) log->append(tr("Found CMake binary: %1").arg(cmake.toUserOutput())); const bool res = QMetaObject::invokeMethod(cmakeManager, "registerCMakeByPath", - Q_ARG(Utils::FilePath, cmake)); + Q_ARG(Utils::FilePath, cmake), + Q_ARG(QString, m_data.id())); QTC_CHECK(res); } } From f8a77287bfc74d1cb2e25eb510bfa9f97ca5bc8b Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 24 Jun 2021 17:44:14 +0200 Subject: [PATCH 22/29] CMakePM: Add support for qtc_runnable feature This will allow for the Qt Creator's CMake build only qtcreator target to be selected as runnable. Similar to qmake's qtc_runnable or Qbs's qtcRunnable features. Fixes: QTCREATORBUG-25908 Change-Id: I6416873d0ad9cfec4960d98fc4b289ec98cc58b1 Reviewed-by: Eike Ziller --- cmake/QtCreatorAPI.cmake | 7 ++++++- src/app/CMakeLists.txt | 1 + src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp | 1 + src/plugins/cmakeprojectmanager/cmakebuildtarget.h | 1 + src/plugins/cmakeprojectmanager/fileapidataextractor.cpp | 2 ++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index e89274a061a..ed3602e6d6d 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -602,7 +602,7 @@ function(extend_qtc_test target_name) endfunction() function(add_qtc_executable name) - cmake_parse_arguments(_arg "SKIP_INSTALL;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;SKIP_PCH" + cmake_parse_arguments(_arg "SKIP_INSTALL;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;SKIP_PCH;QTC_RUNNABLE" "DESTINATION;COMPONENT;BUILD_DEFAULT" "CONDITION;DEPENDS;DEFINES;INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}) @@ -707,6 +707,11 @@ function(add_qtc_executable name) enable_pch(${name}) endif() + if (_arg_QTC_RUNNABLE) + # Used by QtCreator to select the default target in the project + set_target_properties(${name} PROPERTIES FOLDER "qtc_runnable") + endif() + if (NOT _arg_SKIP_INSTALL) unset(COMPONENT_OPTION) if (_arg_COMPONENT) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index b08211cf573..43650cab5ad 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -17,6 +17,7 @@ add_qtc_executable(qtcreator MACOSX_BUNDLE ON OUTPUT_NAME "${IDE_APP_TARGET}" DESTINATION "${IDE_APP_PATH}" + QTC_RUNNABLE ) if (NOT TARGET qtcreator) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index b89d5d74ef6..688c0f26627 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -1009,6 +1009,7 @@ const QList CMakeBuildSystem::appTargets() const bti.workingDirectory = ct.workingDirectory; bti.buildKey = buildKey; bti.usesTerminal = !ct.linksToQtGui; + bti.isQtcRunnable = ct.qtcRunnable; // Workaround for QTCREATORBUG-19354: bti.runEnvModifier = [this, buildKey](Environment &env, bool enabled) { diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h index c2a51c67fc4..6bc7d41249e 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h @@ -54,6 +54,7 @@ public: Utils::FilePath executable; // TODO: rename to output? TargetType targetType = UtilityType; bool linksToQtGui = false; + bool qtcRunnable = true; Utils::FilePath workingDirectory; Utils::FilePath sourceDirectory; Utils::FilePath makeCommand; diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 1d96dad7f91..7b38aa0f41f 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -256,6 +256,8 @@ QList generateBuildTargets(const PreprocessedData &input, || f.fragment.contains("Qt6Gui")); }); + ct.qtcRunnable = t.folderTargetProperty == "qtc_runnable"; + // Extract library directories for executables: for (const FragmentInfo &f : t.link.value().fragments) { if (f.role == "flags") // ignore all flags fragments From 68ff37e630cfde85f9fcf412781fbdfbd39fb802 Mon Sep 17 00:00:00 2001 From: Pekka Kaikkonen Date: Fri, 18 Jun 2021 21:21:52 +0300 Subject: [PATCH 23/29] QmlDesigner : QRC File integration Split resource file generation into two actions. Take file from current project into account. .qrc generation should take existing .qrc file into account. Task-number: QDS-4516 Task-number: QDS-4517 Task-number: QDS-4519 Change-Id: Iee15880657e456fbd74df505c10ee83a80ee64a7 Reviewed-by: Qt CI Bot Reviewed-by: Vikas Pachdha Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/generateresource.cpp | 305 ++++++++++++++++--- src/plugins/qmldesigner/generateresource.h | 9 +- 2 files changed, 277 insertions(+), 37 deletions(-) diff --git a/src/plugins/qmldesigner/generateresource.cpp b/src/plugins/qmldesigner/generateresource.cpp index 68f159db1d3..182ede79dc1 100644 --- a/src/plugins/qmldesigner/generateresource.cpp +++ b/src/plugins/qmldesigner/generateresource.cpp @@ -63,7 +63,7 @@ namespace QmlDesigner { -QTableWidget* GenerateResource::createFilesTable(const QStringList &fileNames) +QTableWidget* GenerateResource::createFilesTable(const QList &fileNames) { auto table = new QTableWidget(0, 1); table->setSelectionMode(QAbstractItemView::SingleSelection); @@ -74,12 +74,19 @@ QTableWidget* GenerateResource::createFilesTable(const QStringList &fileNames) table->verticalHeader()->hide(); table->setShowGrid(false); - for (const QString &filePath : fileNames) { + QFont font; + font.setBold(true); + + for (ResourceFile resource : fileNames){ + QString filePath = resource.fileName; auto checkboxItem = new QTableWidgetItem(); checkboxItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); checkboxItem->setCheckState(Qt::Checked); checkboxItem->setText(filePath); + if (resource.inProject) + checkboxItem->setFont(font); + int row = table->rowCount(); table->insertRow(row); table->setItem(row, 0, checkboxItem); @@ -88,7 +95,7 @@ QTableWidget* GenerateResource::createFilesTable(const QStringList &fileNames) return table; } -QStringList GenerateResource::getFileList(const QStringList &fileNames) +QStringList GenerateResource::getFileList(const QList &fileNames) { QStringList result; QDialog *dialog = new QDialog(Core::ICore::dialogParent()); @@ -107,21 +114,21 @@ QStringList GenerateResource::getFileList(const QStringList &fileNames) mainLayout->addWidget(buttonBox, 3, 2, 1, 2); - QObject::connect(buttonBox, &QDialogButtonBox::accepted, dialog, [dialog](){ + QObject::connect(buttonBox, &QDialogButtonBox::accepted, dialog, [dialog]() { dialog->accept(); dialog->deleteLater(); }); - QObject::connect(buttonBox, &QDialogButtonBox::rejected, dialog, [dialog](){ + QObject::connect(buttonBox, &QDialogButtonBox::rejected, dialog, [dialog]() { dialog->reject(); dialog->deleteLater(); }); - QObject::connect(dialog, &QDialog::accepted, [&result, &table](){ + QObject::connect(dialog, &QDialog::accepted, [&result, &table]() { QStringList fileList; QString file; - for (int i = 0; i < table->rowCount(); ++i){ + for (int i = 0; i < table->rowCount(); ++i) { if (table->item(i,0)->checkState()){ file = table->item(i,0)->text(); fileList.append(file); @@ -141,19 +148,21 @@ void GenerateResource::generateMenuEntry() Core::ActionContainer *buildMenu = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT); - const Core::Context projectContext(QmlProjectManager::Constants::QML_PROJECT_ID); // ToDo: move this to QtCreator and add tr to the string then - auto action = new QAction(QCoreApplication::translate("QmlDesigner::GenerateResource", "Generate Resource File")); + auto action = new QAction(QCoreApplication::translate("QmlDesigner::GenerateResource", + "Generate QRC Resource File")); action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); // todo make it more intelligent when it gets enabled - QObject::connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::startupProjectChanged, [action]() { + QObject::connect(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::startupProjectChanged, [action]() { action->setEnabled(ProjectExplorer::SessionManager::startupProject()); }); Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateResource"); QObject::connect(action, &QAction::triggered, [] () { auto currentProject = ProjectExplorer::SessionManager::startupProject(); + QTC_ASSERT(currentProject, return); auto projectPath = currentProject->projectFilePath().parentDir().toString(); static QMap lastUsedPathes; @@ -163,21 +172,13 @@ void GenerateResource::generateMenuEntry() saveLastUsedPath(lastUsedPathes.value(currentProject->displayName(), currentProject->projectFilePath().parentDir().parentDir().toString())); - auto resourceFileName = Core:: DocumentManager::getSaveFileName( - QCoreApplication::translate("QmlDesigner::GenerateResource", "Save Project as Resource"), - lastUsedPathes.value(currentProject->displayName()) + "/" + currentProject->displayName() + ".qmlrc", - QCoreApplication::translate("QmlDesigner::GenerateResource", "QML Resource File (*.qmlrc)")); - if (resourceFileName.isEmpty()) - return; - - Core::MessageManager::writeSilently( - QCoreApplication::translate("QmlDesigner::GenerateResource", - "Generate a resource file out of project %1 to %2") - .arg(currentProject->displayName(), QDir::toNativeSeparators(resourceFileName))); - + QString projectFileName = currentProject->displayName() + ".qrc"; QTemporaryFile temp(projectPath + "/XXXXXXX.create.resource.qrc"); + QFile persistentFile(projectPath + "/" + projectFileName); + if (!temp.open()) return; + temp.close(); QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion( @@ -196,7 +197,7 @@ void GenerateResource::generateMenuEntry() Core::MessageManager::writeDisrupting( QCoreApplication::translate("QmlDesigner::GenerateResource", "Unable to generate resource file: %1") - .arg(resourceFileName)); + .arg(temp.fileName())); return; } QByteArray stdOut; @@ -208,10 +209,11 @@ void GenerateResource::generateMenuEntry() "A timeout occurred running \"%1\"") .arg(rccBinary + " " + arguments.join(" "))); return; + } - if (!stdOut.trimmed().isEmpty()) { + if (!stdOut.trimmed().isEmpty()) Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdOut)); - } + if (!stdErr.trimmed().isEmpty()) Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdErr)); @@ -229,14 +231,13 @@ void GenerateResource::generateMenuEntry() .arg(rccProcess.exitCode())); return; } - } if (!temp.open()) return; QXmlStreamReader reader(&temp); - QStringList fileList = {}; + QList fileList = {}; QByteArray firstLine = temp.readLine(); while (!reader.atEnd()) { @@ -247,12 +248,244 @@ void GenerateResource::generateMenuEntry() if (reader.name() == QLatin1String("file")) { QString fileName = reader.readElementText().trimmed(); - if ((!fileName.startsWith("./.")) && (!fileName.startsWith("./XXXXXXX"))) - fileList.append(fileName); + + if ((!fileName.startsWith("./.")) && (!fileName.startsWith("./XXXXXXX")) + && !fileName.endsWith(".qmlproject") && !fileName.endsWith(".pri") + && !fileName.endsWith(".pro") && !fileName.endsWith(".user") + && !fileName.endsWith(".qrc")) { + ResourceFile file; + file.fileName = fileName; + file.inProject = false; + fileList.append(file); + } + } + } + + QDir dir; + dir.setCurrent(projectPath); + + Utils::FilePaths paths = currentProject->files(ProjectExplorer::Project::AllFiles); + QStringList projectFiles = {}; + + for (const Utils::FilePath &path : paths) { + QString relativepath = dir.relativeFilePath(path.toString()); + + if (!relativepath.endsWith(".qmlproject") && !relativepath.endsWith(".pri") + && !relativepath.endsWith(".pro") && !relativepath.endsWith(".user") + && !relativepath.endsWith(".qrc")) { + projectFiles.append(relativepath); + + bool found = false; + QString compareString = "./" + relativepath.trimmed(); + for (int i = 0; i < fileList.count(); ++i) + if (fileList.at(i).fileName == compareString) { + fileList[i].inProject = true; + found = true; + break; + } + + if (!found) { + ResourceFile res; + res.fileName = "./" + relativepath.trimmed(); + res.inProject = true; + fileList.append(res); + } } } temp.close(); + + QStringList modifiedList = getFileList(fileList); + + if (!persistentFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) + return; + + QXmlStreamWriter writer(&persistentFile); + writer.setAutoFormatting(true); + writer.setAutoFormattingIndent(0); + + persistentFile.write(firstLine.trimmed()); + writer.writeStartElement("qresource"); + + for (QString file : modifiedList) + writer.writeTextElement("file", file.trimmed()); + + writer.writeEndElement(); + persistentFile.write("\n\n"); + persistentFile.close(); + + saveLastUsedPath(Utils::FilePath::fromString(projectFileName).parentDir().toString()); + }); + + // ToDo: move this to QtCreator and add tr to the string then + auto rccAction = new QAction(QCoreApplication::translate("QmlDesigner::GenerateResource", + "Generate RCC Resource File")); + rccAction->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); + QObject::connect(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::startupProjectChanged, [rccAction]() { + rccAction->setEnabled(ProjectExplorer::SessionManager::startupProject()); + }); + + Core::Command *cmd2 = Core::ActionManager::registerAction(rccAction, + "QmlProject.CreateRCCResource"); + QObject::connect(rccAction, &QAction::triggered, [] () { + auto currentProject = ProjectExplorer::SessionManager::startupProject(); + QTC_ASSERT(currentProject, return); + auto projectPath = currentProject->projectFilePath().parentDir().toString(); + + static QMap lastUsedPathes; + auto saveLastUsedPath = [currentProject] (const QString &lastUsedPath) { + lastUsedPathes.insert(currentProject->displayName(), lastUsedPath); + }; + saveLastUsedPath(lastUsedPathes.value(currentProject->displayName(), + currentProject->projectFilePath().parentDir().parentDir().toString())); + + auto resourceFileName = Core:: DocumentManager::getSaveFileName( + QCoreApplication::translate("QmlDesigner::GenerateResource", + "Save Project as Resource"), lastUsedPathes.value(currentProject->displayName()) + + "/" + currentProject->displayName() + ".qmlrc", + QCoreApplication::translate("QmlDesigner::GenerateResource", + "QML Resource File (*.qmlrc);;Resource File (*.rcc)")); + if (resourceFileName.isEmpty()) + return; + + Core::MessageManager::writeSilently( + QCoreApplication::translate("QmlDesigner::GenerateResource", + "Generate a resource file out of project %1 to %2") + .arg(currentProject->displayName(), QDir::toNativeSeparators(resourceFileName))); + + QString projectFileName = currentProject->displayName() + ".qrc"; + QFile persistentFile(projectPath + "/" + projectFileName); + QTemporaryFile temp(projectPath + "/XXXXXXX.create.resource.qrc"); + + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion( + currentProject->activeTarget()->kit()); + QString rccBinary = qtVersion->rccCommand(); + + Utils::QtcProcess rccProcess; + rccProcess.setWorkingDirectory(projectPath); + + QXmlStreamReader reader; + QByteArray firstLine; + + if (!QFileInfo(persistentFile).exists()) { + if (!temp.open()) + return; + temp.close(); + + const QStringList arguments1 = {"--project", "--output", temp.fileName()}; + + for (const auto &arguments : {arguments1}) { + rccProcess.setCommand({rccBinary, arguments}); + rccProcess.start(); + if (!rccProcess.waitForStarted()) { + Core::MessageManager::writeDisrupting( + QCoreApplication::translate("QmlDesigner::GenerateResource", + "Unable to generate resource file: %1") + .arg(resourceFileName)); + return; + } + QByteArray stdOut; + QByteArray stdErr; + if (!rccProcess.readDataFromProcess(30, &stdOut, &stdErr, true)) { + rccProcess.stopProcess(); + Core::MessageManager::writeDisrupting( + QCoreApplication::translate("QmlDesigner::GenerateResource", + "A timeout occurred running \"%1\"") + .arg(rccBinary + " " + arguments.join(" "))); + return; + } + if (!stdOut.trimmed().isEmpty()) + Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdOut)); + + if (!stdErr.trimmed().isEmpty()) + Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdErr)); + + if (rccProcess.exitStatus() != QProcess::NormalExit) { + Core::MessageManager::writeDisrupting( + QCoreApplication::translate("QmlDesigner::GenerateResource", "\"%1\" crashed.") + .arg(rccBinary + " " + arguments.join(" "))); + return; + } + if (rccProcess.exitCode() != 0) { + Core::MessageManager::writeDisrupting( + QCoreApplication::translate("QmlDesigner::GenerateResource", + "\"%1\" failed (exit code %2).") + .arg(rccBinary + " " + arguments.join(" ")) + .arg(rccProcess.exitCode())); + return; + } + } + + reader.setDevice(&temp); + + if (!temp.open()) + return; + firstLine = temp.readLine(); + + } else { + reader.setDevice(&persistentFile); + if (!persistentFile.open(QIODevice::ReadWrite)) + return; + + firstLine = persistentFile.readLine(); + } + + QList fileList = {}; + + while (!reader.atEnd()) { + const auto token = reader.readNext(); + + if (token != QXmlStreamReader::StartElement) + continue; + + if (reader.name() == QLatin1String("file")) { + QString fileName = reader.readElementText().trimmed(); + if ((!fileName.startsWith("./.")) && (!fileName.startsWith("./XXXXXXX")) + && !fileName.endsWith(".qmlproject") && !fileName.endsWith(".pri") + && !fileName.endsWith(".pro") && !fileName.endsWith(".user") + && !fileName.endsWith(".qrc")) { + ResourceFile file; + file.fileName = fileName; + file.inProject = false; + fileList.append(file); + } + } + } + + QDir dir; + dir.setCurrent(projectPath); + + Utils::FilePaths paths = currentProject->files(ProjectExplorer::Project::AllFiles); + QStringList projectFiles = {}; + + for (const Utils::FilePath &path : paths) { + QString relativepath = dir.relativeFilePath(path.toString()); + + if (!relativepath.endsWith(".qmlproject") && !relativepath.endsWith(".pri") + && !relativepath.endsWith(".pro") && !relativepath.endsWith(".user") + && !relativepath.endsWith(".qrc")) { + projectFiles.append(relativepath); + + bool found = false; + QString compareString = "./" + relativepath.trimmed(); + for (int i = 0; i < fileList.count(); ++i) + if (fileList.at(i).fileName == compareString) { + fileList[i].inProject = true; + found = true; + } + + if (!found) { + ResourceFile res; + res.fileName = "./" + relativepath.trimmed(); + res.inProject = true; + fileList.append(res); + } + } + } + + temp.close(); + persistentFile.close(); QStringList modifiedList = getFileList(fileList); QTemporaryFile tempFile(projectPath + "/XXXXXXX.create.modifiedresource.qrc"); @@ -266,14 +499,15 @@ void GenerateResource::generateMenuEntry() tempFile.write(firstLine.trimmed()); writer.writeStartElement("qresource"); - for (int i = 0; i < modifiedList.count(); ++i) - writer.writeTextElement("file", modifiedList.at(i).trimmed()); + for (QString file : modifiedList) + writer.writeTextElement("file", file.trimmed()); writer.writeEndElement(); tempFile.write("\n\n"); tempFile.close(); - const QStringList arguments2 = {"--binary", "--output", resourceFileName, tempFile.fileName()}; + const QStringList arguments2 = {"--binary", "--output", resourceFileName, + tempFile.fileName()}; for (const auto &arguments : {arguments2}) { rccProcess.setCommand({rccBinary, arguments}); @@ -293,12 +527,12 @@ void GenerateResource::generateMenuEntry() QCoreApplication::translate("QmlDesigner::GenerateResource", "A timeout occurred running \"%1\"") .arg(rccBinary + " " + arguments.join(" "))); - return ; + return; } - if (!stdOut.trimmed().isEmpty()) { + if (!stdOut.trimmed().isEmpty()) Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdOut)); - } + if (!stdErr.trimmed().isEmpty()) Core::MessageManager::writeFlashing(QString::fromLocal8Bit(stdErr)); @@ -322,6 +556,7 @@ void GenerateResource::generateMenuEntry() saveLastUsedPath(Utils::FilePath::fromString(resourceFileName).parentDir().toString()); }); buildMenu->addAction(cmd, ProjectExplorer::Constants::G_BUILD_RUN); + buildMenu->addAction(cmd2, ProjectExplorer::Constants::G_BUILD_RUN); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/generateresource.h b/src/plugins/qmldesigner/generateresource.h index f6030e1c0c4..42d96c2d513 100644 --- a/src/plugins/qmldesigner/generateresource.h +++ b/src/plugins/qmldesigner/generateresource.h @@ -28,8 +28,13 @@ namespace QmlDesigner { namespace GenerateResource { +struct ResourceFile +{ + QString fileName; + bool inProject; +}; void generateMenuEntry(); - QStringList getFileList(const QStringList &); - QTableWidget* createFilesTable(const QStringList &); + QStringList getFileList(const QList &); + QTableWidget* createFilesTable(const QList &); } } // namespace QmlDesigner From a842409d2cb30798e837ae52f5da816122eb32f1 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Fri, 25 Jun 2021 14:51:00 +0200 Subject: [PATCH 24/29] QmlDesigner: Fix minor property editor issues * Fix infinity indicator in AnimationSection * Fix property label capitalization and spelling * Update import version and license header Change-Id: If0eb6a0c00f17bbe1dcdacae73dca7be5e6faf8d Reviewed-by: Tim Jenssen --- .../QtQuick/AnimationSection.qml | 9 ++++++++- .../QtQuick/Controls/ComboBoxSpecifics.qml | 4 ++-- .../QtQuick/Controls/ItemDelegateSection.qml | 2 +- .../imports/HelperWidgets/CharacterSection.qml | 4 ++-- .../imports/HelperWidgets/CheckBox.qml | 5 +++-- .../imports/HelperWidgets/FontSection.qml | 4 ++-- .../imports/StudioControls/InfinityLoopIndicator.qml | 4 +--- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml index 14fc80c971a..cdbf07307d3 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml @@ -91,7 +91,14 @@ Section { StudioControls.InfinityLoopIndicator { id: infinityLoopIndicator - infinite: backendValues.loops.value === -1 ? true : false + property var valueFromBackend: backendValues.loops.value + + onValueFromBackendChanged: { + if (valueFromBackend === -1) + infinityLoopIndicator.infinite = true + else + infinityLoopIndicator.infinite = false + } onInfiniteChanged: { if (infinityLoopIndicator.infinite === true) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ComboBoxSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ComboBoxSpecifics.qml index 12c183560ac..debeeeaecf1 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ComboBoxSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ComboBoxSpecifics.qml @@ -81,7 +81,7 @@ Column { } PropertyLabel { - text: qsTr("Current") + text: qsTr("Current index") tooltip: qsTr("The index of the current item.") } @@ -90,8 +90,8 @@ Column { implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth width: implicitWidth - maximumValue: 9999999 minimumValue: -9999999 + maximumValue: 9999999 decimals: 0 backendValue: backendValues.currentIndex } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ItemDelegateSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ItemDelegateSection.qml index 2ad12fd7de1..ffe81ef7fa4 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ItemDelegateSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/Controls/ItemDelegateSection.qml @@ -49,7 +49,7 @@ Section { SectionLayout { PropertyLabel { - text: qsTr("Highlighted") + text: qsTr("Highlight") tooltip: qsTr("Whether the delegate is highlighted.") } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml index 8fea7777345..d88d50fa1a8 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml @@ -296,7 +296,7 @@ Section { } PropertyLabel { - text: qsTr("Letter space") + text: qsTr("Letter spacing") tooltip: qsTr("Letter spacing for the font.") } @@ -316,7 +316,7 @@ Section { } PropertyLabel { - text: qsTr("Word space") + text: qsTr("Word spacing") tooltip: qsTr("Word spacing for the font.") } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml index b9a8055f2c7..5cdedf0dbad 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -23,7 +23,7 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick 2.15 import StudioControls 1.0 as StudioControls StudioControls.CheckBox { @@ -43,6 +43,7 @@ StudioControls.CheckBox { actionIndicator.forceVisible: extFuncLogic.menuVisible labelColor: colorLogic.textColor + ColorLogic { id: colorLogic backendValue: checkBox.backendValue diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml index d60d4d9526e..8e688b84866 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml @@ -275,7 +275,7 @@ Section { } PropertyLabel { - text: qsTr("Letter space") + text: qsTr("Letter spacing") tooltip: qsTr("Letter spacing for the font.") } @@ -295,7 +295,7 @@ Section { } PropertyLabel { - text: qsTr("Word space") + text: qsTr("Word spacing") tooltip: qsTr("Word spacing for the font.") } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/InfinityLoopIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/InfinityLoopIndicator.qml index 9a7e7be6b08..1fc438d2f64 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/InfinityLoopIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/InfinityLoopIndicator.qml @@ -58,9 +58,7 @@ Rectangle { id: mouseArea anchors.fill: parent hoverEnabled: true - onPressed: { - infinityLoopIndicator.infinite = !infinityLoopIndicator.infinite - } + onClicked: infinityLoopIndicator.infinite = !infinityLoopIndicator.infinite } states: [ From 35021ec2da364e6ea2f4b5627a625b2aa4404cef Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 26 Jan 2021 16:41:28 +0100 Subject: [PATCH 25/29] AutoTest: Turn pointer into value ... which avoids a raw pointer which needs additional "management". Change-Id: I9c478b4043a563b00ced09de8366657eaf34c349 Reviewed-by: Christian Stenger --- src/plugins/autotest/autotestplugin.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 20c5562b2a3..6f26981bef6 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -94,7 +94,7 @@ public: AutotestPluginPrivate(); ~AutotestPluginPrivate() override; - TestNavigationWidgetFactory *m_navigationWidgetFactory = nullptr; + TestNavigationWidgetFactory m_navigationWidgetFactory; TestResultsPane *m_resultsPane = nullptr; QMap m_runconfigCache; @@ -149,7 +149,6 @@ AutotestPluginPrivate::AutotestPluginPrivate() m_frameworkManager.registerTestTool(new CTestTool); m_frameworkManager.synchronizeSettings(ICore::settings()); - m_navigationWidgetFactory = new TestNavigationWidgetFactory; m_resultsPane = TestResultsPane::instance(); auto panelFactory = new ProjectExplorer::ProjectPanelFactory(); @@ -186,7 +185,6 @@ AutotestPluginPrivate::~AutotestPluginPrivate() s_projectSettings.clear(); } - delete m_navigationWidgetFactory; delete m_resultsPane; } From 1ae5787e38bd1de0d2da7ef28e1961fb12e2a3fc Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 25 Jun 2021 17:28:38 +0200 Subject: [PATCH 26/29] Doc: Remove docs for Auto-create build directories CMake option The option was removed, so removed also the docs and updated the screenshot. Task-number: QTCREATORBUG-25642 Change-Id: I61b3e01ad0b620bc7d2661a7a76deb53c7ffa238 Reviewed-by: Cristian Adam --- .../images/qtcreator-cmakeexecutable.png | Bin 16369 -> 15539 bytes .../src/cmake/creator-projects-cmake.qdoc | 5 ----- 2 files changed, 5 deletions(-) diff --git a/doc/qtcreator/images/qtcreator-cmakeexecutable.png b/doc/qtcreator/images/qtcreator-cmakeexecutable.png index 31f162d48b1de955525885988df302336a8d99da..7f49186f27133d8fb97379410142128d17033a14 100755 GIT binary patch literal 15539 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 literal 16369 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 Date: Fri, 18 Jun 2021 08:46:38 +0200 Subject: [PATCH 27/29] Pass the new node in ProjectTree::currentNodeChanged Avoids some roundtrips asking for ProjectTree::currentNode() which traverses the project tree every time. Change-Id: I650728eab5a47a7f4760cf88844a4b7106365255 Reviewed-by: Christian Kandeler --- .../cmakeprojectmanager.cpp | 16 +++++++------- .../cmakeprojectmanager/cmakeprojectmanager.h | 2 +- .../cmakeprojectplugin.cpp | 4 ++-- .../cmakeprojectmanager/cmakeprojectplugin.h | 4 +++- .../projectexplorer/projectexplorer.cpp | 21 ++++++++++--------- src/plugins/projectexplorer/projecttree.cpp | 2 +- src/plugins/projectexplorer/projecttree.h | 2 +- .../qbsprojectmanagerplugin.cpp | 7 +++---- .../qbsprojectmanagerplugin.h | 7 +++++-- .../qmakeprojectmanagerplugin.cpp | 9 ++++---- src/plugins/qmlpreview/qmlpreviewplugin.cpp | 3 +-- .../resourceeditor/resourceeditorplugin.cpp | 5 ++--- 12 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index fcf52408e5a..10cb64d3e91 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -130,26 +130,28 @@ CMakeManager::CMakeManager() mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); connect(m_buildFileAction, &QAction::triggered, this, [this] { buildFile(); }); - connect(SessionManager::instance(), &SessionManager::startupProjectChanged, - this, &CMakeManager::updateCmakeActions); - connect(BuildManager::instance(), &BuildManager::buildStateChanged, - this, &CMakeManager::updateCmakeActions); + connect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, [this] { + updateCmakeActions(ProjectTree::currentNode()); + }); + connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, [this] { + updateCmakeActions(ProjectTree::currentNode()); + }); connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, this, &CMakeManager::updateBuildFileAction); connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, this, &CMakeManager::updateCmakeActions); - updateCmakeActions(); + updateCmakeActions(ProjectTree::currentNode()); } -void CMakeManager::updateCmakeActions() +void CMakeManager::updateCmakeActions(Node *node) { auto project = qobject_cast(SessionManager::startupProject()); const bool visible = project && !BuildManager::isBuilding(project); m_runCMakeAction->setVisible(visible); m_clearCMakeCacheAction->setVisible(visible); m_rescanProjectAction->setVisible(visible); - enableBuildFileMenus(ProjectTree::currentNode()); + enableBuildFileMenus(node); } void CMakeManager::clearCMakeCache(BuildSystem *buildSystem) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index db3b10b6e2c..56d3aaffa45 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -44,7 +44,7 @@ public: CMakeManager(); private: - void updateCmakeActions(); + void updateCmakeActions(ProjectExplorer::Node *node); void clearCMakeCache(ProjectExplorer::BuildSystem *buildSystem); void runCMake(ProjectExplorer::BuildSystem *buildSystem); void rescanProject(ProjectExplorer::BuildSystem *buildSystem); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp index c1cce18df94..891b89916d8 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp @@ -142,9 +142,9 @@ void CMakeProjectPlugin::extensionsInitialized() CMakeToolManager::restoreCMakeTools(); } -void CMakeProjectPlugin::updateContextActions() +void CMakeProjectPlugin::updateContextActions(Node *node) { - auto targetNode = dynamic_cast(ProjectTree::currentNode()); + auto targetNode = dynamic_cast(node); const QString targetDisplayName = targetNode ? targetNode->displayName() : QString(); // Build Target: diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h index 75646ef265d..5daa0edcd7a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.h @@ -27,6 +27,8 @@ #include +namespace ProjectExplorer { class Node; } + namespace CMakeProjectManager { namespace Internal { @@ -60,7 +62,7 @@ private: bool initialize(const QStringList &arguments, QString *errorMessage) final; void extensionsInitialized() final; - void updateContextActions(); + void updateContextActions(ProjectExplorer::Node *node); class CMakeProjectPluginPrivate *d = nullptr; }; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 241e74a1133..24514e3ff5c 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -403,7 +403,7 @@ class ProjectExplorerPluginPrivate : public QObject public: ProjectExplorerPluginPrivate(); - void updateContextMenuActions(); + void updateContextMenuActions(Node *currentNode); void updateLocationSubMenus(); void executeRunConfiguration(RunConfiguration *, Utils::Id mode); QPair buildSettingsEnabledForSession(); @@ -767,10 +767,12 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er }); ProjectTree *tree = &dd->m_projectTree; - connect(tree, &ProjectTree::currentProjectChanged, - dd, &ProjectExplorerPluginPrivate::updateContextMenuActions); - connect(tree, &ProjectTree::nodeActionsChanged, - dd, &ProjectExplorerPluginPrivate::updateContextMenuActions); + connect(tree, &ProjectTree::currentProjectChanged, dd, [] { + dd->updateContextMenuActions(ProjectTree::currentNode()); + }); + connect(tree, &ProjectTree::nodeActionsChanged, dd, [] { + dd->updateContextMenuActions(ProjectTree::currentNode()); + }); connect(tree, &ProjectTree::currentNodeChanged, dd, &ProjectExplorerPluginPrivate::updateContextMenuActions); connect(tree, &ProjectTree::currentProjectChanged, @@ -1763,8 +1765,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(this, &ProjectExplorerPlugin::settingsChanged, dd, &ProjectExplorerPluginPrivate::updateRunWithoutDeployMenu); - connect(ICore::instance(), &ICore::newItemDialogStateChanged, - dd, &ProjectExplorerPluginPrivate::updateContextMenuActions); + connect(ICore::instance(), &ICore::newItemDialogStateChanged, dd, [] { + dd->updateContextMenuActions(ProjectTree::currentNode()); + }); dd->updateWelcomePage(); @@ -3257,7 +3260,7 @@ void ProjectExplorerPluginPrivate::invalidateProject(Project *project) updateActions(); } -void ProjectExplorerPluginPrivate::updateContextMenuActions() +void ProjectExplorerPluginPrivate::updateContextMenuActions(Node *currentNode) { m_addExistingFilesAction->setEnabled(false); m_addExistingDirectoryAction->setEnabled(false); @@ -3294,8 +3297,6 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() runMenu->menu()->clear(); runMenu->menu()->menuAction()->setVisible(false); - const Node *currentNode = ProjectTree::currentNode(); - if (currentNode && currentNode->managingProject()) { ProjectNode *pn; if (const ContainerNode *cn = currentNode->asContainerNode()) diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp index 30b9af0e9f1..e94dcb602c2 100644 --- a/src/plugins/projectexplorer/projecttree.cpp +++ b/src/plugins/projectexplorer/projecttree.cpp @@ -227,7 +227,7 @@ void ProjectTree::setCurrent(Node *node, Project *project) if (node != m_currentNode) { m_currentNode = node; - emit currentNodeChanged(); + emit currentNodeChanged(node); } if (changedProject) { diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h index 5fe45416812..060dad22903 100644 --- a/src/plugins/projectexplorer/projecttree.h +++ b/src/plugins/projectexplorer/projecttree.h @@ -104,7 +104,7 @@ public: signals: void currentProjectChanged(ProjectExplorer::Project *project); - void currentNodeChanged(); + void currentNodeChanged(Node *node); void nodeActionsChanged(); // Emitted whenever the model needs to send a update signal. diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index cf46e0b544d..992047bb1fa 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -262,7 +262,7 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * }); // Run initial setup routines - updateContextActions(); + updateContextActions(ProjectTree::currentNode()); updateReparseQbsAction(); updateBuildActions(); @@ -280,10 +280,9 @@ void QbsProjectManagerPlugin::targetWasAdded(Target *target) this, &QbsProjectManagerPlugin::projectChanged); } -void QbsProjectManagerPlugin::updateContextActions() +void QbsProjectManagerPlugin::updateContextActions(Node *node) { auto project = qobject_cast(ProjectTree::currentProject()); - const Node *node = ProjectTree::currentNode(); bool isEnabled = !BuildManager::isBuilding(project) && project && project->activeTarget() && !project->activeTarget()->buildSystem()->isParsing() @@ -369,7 +368,7 @@ void QbsProjectManagerPlugin::projectChanged() updateReparseQbsAction(); if (!project || project == ProjectTree::currentProject()) - updateContextActions(); + updateContextActions(ProjectTree::currentNode()); if (!project || project == currentEditorProject()) updateBuildActions(); diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h index 641bf5d01d8..d93869c0ba7 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h @@ -29,7 +29,10 @@ #include #include -namespace ProjectExplorer { class Target; } +namespace ProjectExplorer { +class Target; +class Node; +} // namespace ProjectExplorer namespace QbsProjectManager { namespace Internal { @@ -72,7 +75,7 @@ private: void reparseCurrentProject(); void reparseProject(QbsProject *project); - void updateContextActions(); + void updateContextActions(ProjectExplorer::Node *node); void updateReparseQbsAction(); void updateBuildActions(); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index bd62251e2de..01da9cad48f 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -86,7 +86,7 @@ public: void activeTargetChanged(); void updateActions(); void updateRunQMakeAction(); - void updateContextActions(); + void updateContextActions(Node *node); void buildStateChanged(Project *pro); void updateBuildFileAction(); void disableBuildFileMenus(); @@ -496,7 +496,7 @@ void QmakeProjectManagerPluginPrivate::activeTargetChanged() void QmakeProjectManagerPluginPrivate::updateActions() { updateRunQMakeAction(); - updateContextActions(); + updateContextActions(ProjectTree::currentNode()); } void QmakeProjectManagerPluginPrivate::updateRunQMakeAction() @@ -515,9 +515,8 @@ void QmakeProjectManagerPluginPrivate::updateRunQMakeAction() m_runQMakeAction->setEnabled(enable); } -void QmakeProjectManagerPluginPrivate::updateContextActions() +void QmakeProjectManagerPluginPrivate::updateContextActions(Node *node) { - const Node *node = ProjectTree::currentNode(); Project *project = ProjectTree::currentProject(); const ContainerNode *containerNode = node ? node->asContainerNode() : nullptr; @@ -578,7 +577,7 @@ void QmakeProjectManagerPluginPrivate::buildStateChanged(Project *pro) { if (pro == ProjectTree::currentProject()) { updateRunQMakeAction(); - updateContextActions(); + updateContextActions(ProjectTree::currentNode()); updateBuildFileAction(); } } diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp index cf22d7d5c64..b10725ebb7e 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp +++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp @@ -236,8 +236,7 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent) Core::ActionManager::registerAction(action, "QmlPreview.PreviewFile", Core::Context(Constants::C_PROJECT_TREE)), Constants::G_FILE_OTHER); action->setVisible(false); - connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, action, [action]() { - const Node *node = ProjectTree::currentNode(); + connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, action, [action](Node *node) { const FileNode *fileNode = node ? node->asFileNode() : nullptr; action->setVisible(fileNode ? fileNode->fileType() == FileType::QML : false); }); diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp index 25c29e2cdcd..19fa120d585 100644 --- a/src/plugins/resourceeditor/resourceeditorplugin.cpp +++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp @@ -132,7 +132,7 @@ public: void copyPathContextMenu(); void copyUrlContextMenu(); - void updateContextActions(); + void updateContextActions(Node *node); ResourceEditorW * currentEditor() const; @@ -368,9 +368,8 @@ void ResourceEditorPluginPrivate::renamePrefixContextMenu() node->renamePrefix(prefix, dialog.lang()); } -void ResourceEditorPluginPrivate::updateContextActions() +void ResourceEditorPluginPrivate::updateContextActions(Node *node) { - const Node *node = ProjectTree::currentNode(); const bool isResourceNode = dynamic_cast(node); m_addPrefix->setEnabled(isResourceNode); m_addPrefix->setVisible(isResourceNode); From 6a826bd75148a05d19680cc6ab0a74c798016402 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Jun 2021 16:06:16 +0200 Subject: [PATCH 28/29] QtSupport: Claim support for any Qt version with docker It's hard to draw the line, and it's only about a potentially missing warning here. Change-Id: Ie86905d0b8309297965133dedf636b6172a11757 Reviewed-by: Christian Stenger --- src/plugins/qtsupport/baseqtversion.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 7d5e4bd2a5b..7e4ff317084 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -516,9 +516,11 @@ Tasks BaseQtVersion::validateKit(const Kit *k) return result; const Id dt = DeviceTypeKitAspect::deviceTypeId(k); - const QSet tdt = targetDeviceTypes(); - if (!tdt.isEmpty() && !tdt.contains(dt)) - result << BuildSystemTask(Task::Warning, tr("Device type is not supported by Qt version.")); + if (dt != "DockerDeviceType") { + const QSet tdt = targetDeviceTypes(); + if (!tdt.isEmpty() && !tdt.contains(dt)) + result << BuildSystemTask(Task::Warning, tr("Device type is not supported by Qt version.")); + } if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) { Abi targetAbi = tc->targetAbi(); From d1300542bbf985b86ae336cb61d966e5b0a18407 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Jun 2021 08:55:09 +0200 Subject: [PATCH 29/29] Proparser: Don't crash on accidental remote files Change-Id: I62ca1b17436fce21d582816388db497d82df6582 Reviewed-by: Christian Stenger --- src/shared/proparser/ioutils.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index 10d75817650..8b0aef01ed2 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -48,6 +48,18 @@ using namespace QMakeInternal; IoUtils::FileType IoUtils::fileType(const QString &fileName) { + // FIXME: + if (fileName.startsWith("docker:/")) { + if (!fileName.startsWith("docker://")) + qWarning("File name not canonical"); + int pos = fileName.indexOf('/', 10); + if (pos == 0) { + qWarning("File name not canonical"); + return FileNotFound; + } + return fileType(fileName.mid(pos)); + } + Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName)); #ifdef Q_OS_WIN DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16());