From a7ceb64895ac80e38d18bd1d100760018252dec5 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 6 Oct 2022 12:50:07 +0200 Subject: [PATCH 01/24] QmlDesigner: Add arrow to MenuItem for sub menus Task-number: QDS-7867 Change-Id: Ia2c9dcf4534a5ccc2525f36720acb2d7f971abe4 Reviewed-by: Reviewed-by: Mahmoud Badri --- .../imports/StudioControls/MenuItem.qml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/MenuItem.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/MenuItem.qml index c4bbcd7cb9f..18d9b26a5c5 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/MenuItem.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/MenuItem.qml @@ -70,6 +70,17 @@ T.MenuItem { } } + arrow: T.Label { + id: arrow + x: parent.width - (StudioTheme.Values.height + arrow.width) / 2 + y: (parent.height - arrow.height) / 2 + visible: control.subMenu + text: StudioTheme.Constants.startNode + color: StudioTheme.Values.themeTextColor + font.pixelSize: 8 + font.family: StudioTheme.Constants.iconFont.family + } + background: Rectangle { implicitWidth: textLabel.implicitWidth + control.labelSpacing + shortcutLabel.implicitWidth + control.leftPadding + control.rightPadding From 4ce9ea64c0b9e469640210becbcf1c93e783645c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Fri, 7 Oct 2022 17:45:47 +0200 Subject: [PATCH 02/24] McuSupport: Fix wrong toolchain file path There was a typo in the package creation for the arm-greenhills toolchain file. The correct filename, as found in the QUL install directory tree, should be ghs-arm.cmake Task-number: QTCREATORBUG-28184 Change-Id: Id2db26f06f996cc24b99f412370ebfeef0f67a10 Reviewed-by: Reviewed-by: Yasser Grimes Reviewed-by: Alessandro Portale --- src/plugins/mcusupport/mcusupportsdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index b5ef907d8fe..b0d8a36cfd1 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -500,7 +500,7 @@ static McuAbstractTargetFactory::Ptr createFactory(bool isLegacy, {"arm-greenhills", McuPackagePtr{new McuPackage{settingsHandler, {}, - toolchainFilePrefix / "arm-ghs.cmake", + toolchainFilePrefix / "ghs-arm.cmake", {}, {}, Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE, From fcc7edc135012ed5853e7afc7c56c811d95d2464 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 6 Oct 2022 14:51:11 +0300 Subject: [PATCH 03/24] QmlDesigner: Fix applying a bundle material to a multi-selection Fixes: QDS-7830 Change-Id: Ic939b1e3b86e6931c369b1b06887284d0b23fa79 Reviewed-by: Reviewed-by: Samuel Ghinet Reviewed-by: Miikka Heikkinen --- .../materialbrowser/materialbrowserview.cpp | 81 +++++++++---------- .../materialbrowser/materialbrowserview.h | 4 +- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 4cedfb9260f..01ee657f848 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -145,10 +146,10 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(matBrowserBundleModel, &MaterialBrowserBundleModel::applyToSelectedTriggered, this, [&] (BundleMaterial *bundleMat, bool add) { - if (!m_selectedModel.isValid()) + if (m_selectedModels.isEmpty()) return; - m_bundleMaterialDropTarget = m_selectedModel; + m_bundleMaterialTargets = m_selectedModels; m_bundleMaterialAddToSelected = add; ModelNode defaultMat = getBundleMaterialDefaultInstance(bundleMat->type()); @@ -201,40 +202,42 @@ void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundl newMatNode = bundleMat; } - if (m_bundleMaterialDropTarget.isValid() - && m_bundleMaterialDropTarget.isSubclassOf("QtQuick3D.Model")) { - QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget); - if (m_bundleMaterialAddToSelected) { - // TODO: unify this logic as it exist elsewhere also - auto expToList = [](const QString &exp) { - QString copy = exp; - copy = copy.remove("[").remove("]"); + // TODO: unify this logic as it exist elsewhere also + auto expToList = [](const QString &exp) { + QString copy = exp; + copy = copy.remove("[").remove("]"); - QStringList tmp = copy.split(',', Qt::SkipEmptyParts); - for (QString &str : tmp) - str = str.trimmed(); + QStringList tmp = copy.split(',', Qt::SkipEmptyParts); + for (QString &str : tmp) + str = str.trimmed(); - return tmp; - }; + return tmp; + }; - auto listToExp = [](QStringList &stringList) { - if (stringList.size() > 1) - return QString("[" + stringList.join(",") + "]"); + auto listToExp = [](QStringList &stringList) { + if (stringList.size() > 1) + return QString("[" + stringList.join(",") + "]"); - if (stringList.size() == 1) - return stringList.first(); + if (stringList.size() == 1) + return stringList.first(); - return QString(); - }; - QStringList matList = expToList(qmlObjNode.expression("materials")); - matList.append(newMatNode.id()); - QString updatedExp = listToExp(matList); - qmlObjNode.setBindingProperty("materials", updatedExp); - } else { - qmlObjNode.setBindingProperty("materials", newMatNode.id()); + return QString(); + }; + + for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) { + if (target.isValid() && target.isSubclassOf("QtQuick3D.Model")) { + QmlObjectNode qmlObjNode(target); + if (m_bundleMaterialAddToSelected) { + QStringList matList = expToList(qmlObjNode.expression("materials")); + matList.append(newMatNode.id()); + QString updatedExp = listToExp(matList); + qmlObjNode.setBindingProperty("materials", updatedExp); + } else { + qmlObjNode.setBindingProperty("materials", newMatNode.id()); + } } - m_bundleMaterialDropTarget = {}; + m_bundleMaterialTargets = {}; m_bundleMaterialAddToSelected = false; } }); @@ -301,24 +304,20 @@ void MaterialBrowserView::selectedNodesChanged(const QList &selectedN { Q_UNUSED(lastSelectedNodeList) - m_selectedModel = {}; + m_selectedModels = Utils::filtered(selectedNodeList, [](const ModelNode &node) { + return node.isSubclassOf("QtQuick3D.Model"); + }); - for (const ModelNode &node : selectedNodeList) { - if (node.isSubclassOf("QtQuick3D.Model")) { - m_selectedModel = node; - break; - } - } - - m_widget->materialBrowserModel()->setHasModelSelection(m_selectedModel.isValid()); + m_widget->materialBrowserModel()->setHasModelSelection(!m_selectedModels.isEmpty()); + // the logic below selects the material of the first selected model if auto selection is on if (!m_autoSelectModelMaterial) return; - if (selectedNodeList.size() > 1 || !m_selectedModel.isValid()) + if (selectedNodeList.size() > 1 || m_selectedModels.isEmpty()) return; - QmlObjectNode qmlObjNode(m_selectedModel); + QmlObjectNode qmlObjNode(m_selectedModels.at(0)); QString matExp = qmlObjNode.expression("materials"); if (matExp.isEmpty()) return; @@ -478,7 +477,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt } else if (identifier == "delete_selected_material") { m_widget->materialBrowserModel()->deleteSelectedMaterial(); } else if (identifier == "drop_bundle_material") { - m_bundleMaterialDropTarget = nodeList.first(); + m_bundleMaterialTargets = nodeList; ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type()); if (defaultMat.isValid()) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index d1a4c85db6d..74eaa3a6e21 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -72,8 +72,8 @@ private: ModelNode getBundleMaterialDefaultInstance(const TypeName &type); QPointer m_widget; - ModelNode m_bundleMaterialDropTarget; - ModelNode m_selectedModel; // first selected 3D model node + QList m_bundleMaterialTargets; + QList m_selectedModels; // selected 3D model nodes BundleMaterial *m_draggedBundleMaterial = nullptr; bool m_bundleMaterialAddToSelected = false; bool m_hasQuick3DImport = false; From 7319eac2835b21d9a8c3be72016071de07d608d2 Mon Sep 17 00:00:00 2001 From: Samuel Ghinet Date: Fri, 7 Oct 2022 19:49:52 +0300 Subject: [PATCH 04/24] Refactor Assets Library Extracted the dialogs, the context menu, and the assets view into separate qml files. Also, reordered some functions in the assets library model Task-number: QDS-7344 Change-Id: Ida21b60d30f34723c07b2659a138e14b95598421 Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../itemLibraryQmlSources/Assets.qml | 512 +----------------- .../AssetsContextMenu.qml | 120 ++++ .../itemLibraryQmlSources/AssetsView.qml | 246 +++++++++ .../ConfirmDeleteFolderDialog.qml | 92 ++++ .../itemLibraryQmlSources/NewFolderDialog.qml | 102 ++++ .../RenameFolderDialog.qml | 124 +++++ .../assetslibrary/assetslibrarymodel.cpp | 150 ++--- 7 files changed, 764 insertions(+), 582 deletions(-) create mode 100644 share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml create mode 100644 share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml create mode 100644 share/qtcreator/qmldesigner/itemLibraryQmlSources/ConfirmDeleteFolderDialog.qml create mode 100644 share/qtcreator/qmldesigner/itemLibraryQmlSources/NewFolderDialog.qml create mode 100644 share/qtcreator/qmldesigner/itemLibraryQmlSources/RenameFolderDialog.qml diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index 6578f96b7d1..1a91e2f492b 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -46,6 +46,10 @@ Item { // Array of supported externally dropped files that trigger custom import process property var dropComplexExtFiles: [] + AssetsContextMenu { + id: contextMenu + } + function clearSearchFilter() { searchBox.clear(); @@ -125,307 +129,11 @@ Item { root.selectedAssetsChanged() } - StudioControls.Menu { - id: contextMenu - - closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape - - onOpened: { - var numSelected = Object.values(root.selectedAssets).filter(p => p).length - deleteFileItem.text = numSelected > 1 ? qsTr("Delete Files") : qsTr("Delete File") - } - - StudioControls.MenuItem { - text: qsTr("Expand All") - enabled: root.allExpandedState !== 1 - visible: root.isDirContextMenu - height: visible ? implicitHeight : 0 - onTriggered: assetsModel.toggleExpandAll(true) - } - - StudioControls.MenuItem { - text: qsTr("Collapse All") - enabled: root.allExpandedState !== 2 - visible: root.isDirContextMenu - height: visible ? implicitHeight : 0 - onTriggered: assetsModel.toggleExpandAll(false) - } - - StudioControls.MenuSeparator { - visible: root.isDirContextMenu - height: visible ? StudioTheme.Values.border : 0 - } - - StudioControls.MenuItem { - id: deleteFileItem - text: qsTr("Delete File") - visible: root.contextFilePath - height: deleteFileItem.visible ? deleteFileItem.implicitHeight : 0 - onTriggered: { - assetsModel.deleteFiles(Object.keys(root.selectedAssets).filter(p => root.selectedAssets[p])) - } - } - - StudioControls.MenuSeparator { - visible: root.contextFilePath - height: visible ? StudioTheme.Values.border : 0 - } - - StudioControls.MenuItem { - text: qsTr("Rename Folder") - visible: root.isDirContextMenu - height: visible ? implicitHeight : 0 - onTriggered: renameFolderDialog.open() - } - - StudioControls.MenuItem { - text: qsTr("New Folder") - onTriggered: newFolderDialog.open() - } - - StudioControls.MenuItem { - text: qsTr("Delete Folder") - visible: root.isDirContextMenu - height: visible ? implicitHeight : 0 - onTriggered: { - var dirEmpty = !(root.contextDir.dirsModel && root.contextDir.dirsModel.rowCount() > 0) - && !(root.contextDir.filesModel && root.contextDir.filesModel.rowCount() > 0); - - if (dirEmpty) - assetsModel.deleteFolder(root.contextDir.dirPath) - else - confirmDeleteFolderDialog.open() - } - } - } - RegExpValidator { id: folderNameValidator regExp: /^(\w[^*/> 0 ? 5 : 0 - bottomPadding: 0 - hideHeader: dirDepth === 0 - showLeftBorder: dirDepth > 0 - expanded: dirExpanded - visible: dirVisible - expandOnClick: false - useDefaulContextMenu: false - dropEnabled: true - - onToggleExpand: { - dirExpanded = !dirExpanded - } - - onDropEnter: (drag)=> { - root.updateDropExtFiles(drag) - section.highlight = drag.accepted && root.dropSimpleExtFiles.length > 0 - } - - onDropExit: { - section.highlight = false - } - - onDrop: { - section.highlight = false - rootView.handleExtFilesDrop(root.dropSimpleExtFiles, - root.dropComplexExtFiles, - dirPath) - } - - onShowContextMenu: { - root.contextFilePath = "" - root.contextDir = model - root.isDirContextMenu = true - root.allExpandedState = assetsModel.getAllExpandedState() - contextMenu.popup() - } - - Column { - spacing: 5 - leftPadding: 5 - - Repeater { - model: dirsModel - delegate: dirSection - } - - Repeater { - model: filesModel - delegate: fileSection - } - - Text { - text: qsTr("Empty folder") - color: StudioTheme.Values.themeTextColorDisabled - font.pixelSize: 12 - visible: !(dirsModel && dirsModel.rowCount() > 0) - && !(filesModel && filesModel.rowCount() > 0) - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton - onClicked: { - root.contextFilePath = "" - root.contextDir = model - root.isDirContextMenu = true - contextMenu.popup() - } - } - } - } - } - } - - Component { - id: fileSection - - Rectangle { - width: assetsView.width - - (assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0) - height: img.height - color: root.selectedAssets[filePath] - ? StudioTheme.Values.themeInteraction - : (mouseArea.containsMouse ? StudioTheme.Values.themeSectionHeadBackground - : "transparent") - - Row { - spacing: 5 - - Image { - id: img - asynchronous: true - fillMode: Image.PreserveAspectFit - width: 48 - height: 48 - source: "image://qmldesigner_assets/" + filePath - } - - Text { - text: fileName - color: StudioTheme.Values.themeTextColor - font.pixelSize: 14 - anchors.verticalCenter: parent.verticalCenter - } - } - - readonly property string suffix: fileName.substr(-4) - readonly property bool isFont: suffix === ".ttf" || suffix === ".otf" - property bool currFileSelected: false - - MouseArea { - id: mouseArea - - property bool allowTooltip: true - - anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onExited: tooltipBackend.hideTooltip() - onEntered: allowTooltip = true - onCanceled: { - tooltipBackend.hideTooltip() - allowTooltip = true - } - onPositionChanged: tooltipBackend.reposition() - onPressed: (mouse)=> { - forceActiveFocus() - allowTooltip = false - tooltipBackend.hideTooltip() - var ctrlDown = mouse.modifiers & Qt.ControlModifier - if (mouse.button === Qt.LeftButton) { - if (!root.selectedAssets[filePath] && !ctrlDown) - root.selectedAssets = {} - currFileSelected = ctrlDown ? !root.selectedAssets[filePath] : true - root.selectedAssets[filePath] = currFileSelected - root.selectedAssetsChanged() - - if (currFileSelected) { - rootView.startDragAsset( - Object.keys(root.selectedAssets).filter(p => root.selectedAssets[p]), - mapToGlobal(mouse.x, mouse.y)) - } - } else { - if (!root.selectedAssets[filePath] && !ctrlDown) - root.selectedAssets = {} - currFileSelected = root.selectedAssets[filePath] || !ctrlDown - root.selectedAssets[filePath] = currFileSelected - root.selectedAssetsChanged() - - root.contextFilePath = filePath - root.contextDir = model.fileDir - root.isDirContextMenu = false - - contextMenu.popup() - } - } - - onReleased: (mouse)=> { - allowTooltip = true - if (mouse.button === Qt.LeftButton) { - if (!(mouse.modifiers & Qt.ControlModifier)) - root.selectedAssets = {} - root.selectedAssets[filePath] = currFileSelected - root.selectedAssetsChanged() - } - } - - ToolTip { - visible: !isFont && mouseArea.containsMouse && !contextMenu.visible - text: filePath - delay: 1000 - } - - Timer { - interval: 1000 - running: mouseArea.containsMouse && mouseArea.allowTooltip - onTriggered: { - if (suffix === ".ttf" || suffix === ".otf") { - tooltipBackend.name = fileName - tooltipBackend.path = filePath - tooltipBackend.showTooltip() - } - } - } - } - } - } - } } } } diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml new file mode 100644 index 00000000000..5caa139651f --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets as HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +StudioControls.Menu { + id: contextMenu + + closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape + + onOpened: { + var numSelected = Object.values(root.selectedAssets).filter(p => p).length + deleteFileItem.text = numSelected > 1 ? qsTr("Delete Files") : qsTr("Delete File") + } + + StudioControls.MenuItem { + text: qsTr("Expand All") + enabled: root.allExpandedState !== 1 + visible: root.isDirContextMenu + height: visible ? implicitHeight : 0 + onTriggered: assetsModel.toggleExpandAll(true) + } + + StudioControls.MenuItem { + text: qsTr("Collapse All") + enabled: root.allExpandedState !== 2 + visible: root.isDirContextMenu + height: visible ? implicitHeight : 0 + onTriggered: assetsModel.toggleExpandAll(false) + } + + StudioControls.MenuSeparator { + visible: root.isDirContextMenu + height: visible ? StudioTheme.Values.border : 0 + } + + StudioControls.MenuItem { + id: deleteFileItem + text: qsTr("Delete File") + visible: root.contextFilePath + height: deleteFileItem.visible ? deleteFileItem.implicitHeight : 0 + onTriggered: { + assetsModel.deleteFiles(Object.keys(root.selectedAssets).filter(p => root.selectedAssets[p])) + } + } + + StudioControls.MenuSeparator { + visible: root.contextFilePath + height: visible ? StudioTheme.Values.border : 0 + } + + StudioControls.MenuItem { + text: qsTr("Rename Folder") + visible: root.isDirContextMenu + height: visible ? implicitHeight : 0 + onTriggered: renameFolderDialog.open() + + RenameFolderDialog { + id: renameFolderDialog + } + } + + StudioControls.MenuItem { + text: qsTr("New Folder") + + NewFolderDialog { + id: newFolderDialog + } + + onTriggered: newFolderDialog.open() + } + + StudioControls.MenuItem { + text: qsTr("Delete Folder") + visible: root.isDirContextMenu + height: visible ? implicitHeight : 0 + + ConfirmDeleteFolderDialog { + id: confirmDeleteFolderDialog + } + + onTriggered: { + var dirEmpty = !(root.contextDir.dirsModel && root.contextDir.dirsModel.rowCount() > 0) + && !(root.contextDir.filesModel && root.contextDir.filesModel.rowCount() > 0); + + if (dirEmpty) + assetsModel.deleteFolder(root.contextDir.dirPath) + else + confirmDeleteFolderDialog.open() + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml new file mode 100644 index 00000000000..e1c017814d6 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +ScrollView { // TODO: experiment using ListView instead of ScrollView + Column + id: assetsView + clip: true + interactive: assetsView.verticalScrollBarVisible && !contextMenu.opened + + Column { + Repeater { + model: assetsModel // context property + delegate: dirSection + } + + Component { + id: dirSection + + Section { + id: section + + width: assetsView.width - + (assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0) - 5 + caption: dirName + sectionHeight: 30 + sectionFontSize: 15 + leftPadding: 0 + topPadding: dirDepth > 0 ? 5 : 0 + bottomPadding: 0 + hideHeader: dirDepth === 0 + showLeftBorder: dirDepth > 0 + expanded: dirExpanded + visible: dirVisible + expandOnClick: false + useDefaulContextMenu: false + dropEnabled: true + + onToggleExpand: { + dirExpanded = !dirExpanded + } + + onDropEnter: (drag)=> { + root.updateDropExtFiles(drag) + section.highlight = drag.accepted && root.dropSimpleExtFiles.length > 0 + } + + onDropExit: { + section.highlight = false + } + + onDrop: { + section.highlight = false + rootView.handleExtFilesDrop(root.dropSimpleExtFiles, + root.dropComplexExtFiles, + dirPath) + } + + onShowContextMenu: { + root.contextFilePath = "" + root.contextDir = model + root.isDirContextMenu = true + root.allExpandedState = assetsModel.getAllExpandedState() + contextMenu.popup() + } + + Column { + spacing: 5 + leftPadding: 5 + + Repeater { + model: dirsModel + delegate: dirSection + } + + Repeater { + model: filesModel + delegate: fileSection + } + + Text { + text: qsTr("Empty folder") + color: StudioTheme.Values.themeTextColorDisabled + font.pixelSize: 12 + visible: !(dirsModel && dirsModel.rowCount() > 0) + && !(filesModel && filesModel.rowCount() > 0) + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: { + root.contextFilePath = "" + root.contextDir = model + root.isDirContextMenu = true + contextMenu.popup() + } + } + } + } + } + } + + Component { + id: fileSection + + Rectangle { + width: assetsView.width - + (assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0) + height: img.height + color: root.selectedAssets[filePath] + ? StudioTheme.Values.themeInteraction + : (mouseArea.containsMouse ? StudioTheme.Values.themeSectionHeadBackground + : "transparent") + + Row { + spacing: 5 + + Image { + id: img + asynchronous: true + fillMode: Image.PreserveAspectFit + width: 48 + height: 48 + source: "image://qmldesigner_assets/" + filePath + } + + Text { + text: fileName + color: StudioTheme.Values.themeTextColor + font.pixelSize: 14 + anchors.verticalCenter: parent.verticalCenter + } + } + + readonly property string suffix: fileName.substr(-4) + readonly property bool isFont: suffix === ".ttf" || suffix === ".otf" + property bool currFileSelected: false + + MouseArea { + id: mouseArea + + property bool allowTooltip: true + + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onExited: tooltipBackend.hideTooltip() + onEntered: allowTooltip = true + onCanceled: { + tooltipBackend.hideTooltip() + allowTooltip = true + } + onPositionChanged: tooltipBackend.reposition() + onPressed: (mouse)=> { + forceActiveFocus() + allowTooltip = false + tooltipBackend.hideTooltip() + var ctrlDown = mouse.modifiers & Qt.ControlModifier + if (mouse.button === Qt.LeftButton) { + if (!root.selectedAssets[filePath] && !ctrlDown) + root.selectedAssets = {} + currFileSelected = ctrlDown ? !root.selectedAssets[filePath] : true + root.selectedAssets[filePath] = currFileSelected + root.selectedAssetsChanged() + + if (currFileSelected) { + rootView.startDragAsset( + Object.keys(root.selectedAssets).filter(p => root.selectedAssets[p]), + mapToGlobal(mouse.x, mouse.y)) + } + } else { + if (!root.selectedAssets[filePath] && !ctrlDown) + root.selectedAssets = {} + currFileSelected = root.selectedAssets[filePath] || !ctrlDown + root.selectedAssets[filePath] = currFileSelected + root.selectedAssetsChanged() + + root.contextFilePath = filePath + root.contextDir = model.fileDir + root.isDirContextMenu = false + + contextMenu.popup() + } + } + + onReleased: (mouse)=> { + allowTooltip = true + if (mouse.button === Qt.LeftButton) { + if (!(mouse.modifiers & Qt.ControlModifier)) + root.selectedAssets = {} + root.selectedAssets[filePath] = currFileSelected + root.selectedAssetsChanged() + } + } + + ToolTip { + visible: !isFont && mouseArea.containsMouse && !contextMenu.visible + text: filePath + delay: 1000 + } + + Timer { + interval: 1000 + running: mouseArea.containsMouse && mouseArea.allowTooltip + onTriggered: { + if (suffix === ".ttf" || suffix === ".otf") { + tooltipBackend.name = fileName + tooltipBackend.path = filePath + tooltipBackend.showTooltip() + } + } + } + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ConfirmDeleteFolderDialog.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ConfirmDeleteFolderDialog.qml new file mode 100644 index 00000000000..a4fd300975e --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ConfirmDeleteFolderDialog.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +Dialog { + id: confirmDeleteFolderDialog + + title: qsTr("Folder Not Empty") + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + implicitWidth: 300 + modal: true + + contentItem: Column { + spacing: 20 + width: parent.width + + Text { + id: folderNotEmpty + + text: qsTr("Folder \"%1\" is not empty. Delete it anyway?") + .arg(root.contextDir ? root.contextDir.dirName : "") + color: StudioTheme.Values.themeTextColor + wrapMode: Text.WordWrap + width: confirmDeleteFolderDialog.width + leftPadding: 10 + rightPadding: 10 + + Keys.onEnterPressed: btnDelete.onClicked() + Keys.onReturnPressed: btnDelete.onClicked() + } + + Text { + text: qsTr("If the folder has assets in use, deleting it might cause the project to not work correctly.") + color: StudioTheme.Values.themeTextColor + wrapMode: Text.WordWrap + width: confirmDeleteFolderDialog.width + leftPadding: 10 + rightPadding: 10 + } + + Row { + anchors.right: parent.right + Button { + id: btnDelete + + text: qsTr("Delete") + + onClicked: { + assetsModel.deleteFolder(root.contextDir.dirPath) + confirmDeleteFolderDialog.accept() + } + } + + Button { + text: qsTr("Cancel") + onClicked: confirmDeleteFolderDialog.reject() + } + } + } + + onOpened: folderNotEmpty.forceActiveFocus() +} diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/NewFolderDialog.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/NewFolderDialog.qml new file mode 100644 index 00000000000..130026ddce1 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/NewFolderDialog.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +Dialog { + id: newFolderDialog + + title: qsTr("Create New Folder") + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + modal: true + + contentItem: Column { + spacing: 2 + + Row { + Text { + text: qsTr("Folder name: ") + anchors.verticalCenter: parent.verticalCenter + color: StudioTheme.Values.themeTextColor + } + + StudioControls.TextField { + id: folderName + + actionIndicator.visible: false + translationIndicator.visible: false + validator: folderNameValidator + + Keys.onEnterPressed: btnCreate.onClicked() + Keys.onReturnPressed: btnCreate.onClicked() + } + } + + Text { + text: qsTr("Folder name cannot be empty.") + color: "#ff0000" + anchors.right: parent.right + visible: folderName.text === "" + } + + Item { // spacer + width: 1 + height: 20 + } + + Row { + anchors.right: parent.right + + Button { + id: btnCreate + + text: qsTr("Create") + enabled: folderName.text !== "" + onClicked: { + assetsModel.addNewFolder(root.contextDir.dirPath + '/' + folderName.text) + newFolderDialog.accept() + } + } + + Button { + text: qsTr("Cancel") + onClicked: newFolderDialog.reject() + } + } + } + + onOpened: { + folderName.text = qsTr("New folder") + folderName.selectAll() + folderName.forceActiveFocus() + } +} diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/RenameFolderDialog.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/RenameFolderDialog.qml new file mode 100644 index 00000000000..351c0a35fc8 --- /dev/null +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/RenameFolderDialog.qml @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +Dialog { + id: renameFolderDialog + + title: qsTr("Rename Folder") + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + implicitWidth: 280 + modal: true + + property bool renameError: false + + contentItem: Column { + spacing: 2 + + StudioControls.TextField { + id: folderRename + + actionIndicator.visible: false + translationIndicator.visible: false + width: renameFolderDialog.width - 12 + validator: folderNameValidator + + onEditChanged: renameFolderDialog.renameError = false + Keys.onEnterPressed: btnRename.onClicked() + Keys.onReturnPressed: btnRename.onClicked() + } + + Text { + text: qsTr("Folder name cannot be empty.") + color: "#ff0000" + visible: folderRename.text === "" && !renameFolderDialog.renameError + } + + Text { + text: qsTr("Could not rename folder. Make sure no folder with the same name exists.") + wrapMode: Text.WordWrap + width: renameFolderDialog.width - 12 + color: "#ff0000" + visible: renameFolderDialog.renameError + } + + Item { // spacer + width: 1 + height: 10 + } + + Text { + text: qsTr("If the folder has assets in use, renaming it might cause the project to not work correctly.") + color: StudioTheme.Values.themeTextColor + wrapMode: Text.WordWrap + width: renameFolderDialog.width + leftPadding: 10 + rightPadding: 10 + } + + Item { // spacer + width: 1 + height: 20 + } + + Row { + anchors.right: parent.right + + Button { + id: btnRename + + text: qsTr("Rename") + enabled: folderRename.text !== "" + onClicked: { + var success = assetsModel.renameFolder(root.contextDir.dirPath, folderRename.text) + if (success) + renameFolderDialog.accept() + + renameFolderDialog.renameError = !success + } + } + + Button { + text: qsTr("Cancel") + onClicked: renameFolderDialog.reject() + } + } + } + + onOpened: { + folderRename.text = root.contextDir.dirName + folderRename.selectAll() + folderRename.forceActiveFocus() + renameFolderDialog.renameError = false + } +} diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 18967a5fe1d..c538b452729 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -57,6 +57,25 @@ static Q_LOGGING_CATEGORY(assetsLibraryBenchmark, "qtc.assetsLibrary.setRoot", Q namespace QmlDesigner { +AssetsLibraryModel::AssetsLibraryModel(Utils::FileSystemWatcher *fileSystemWatcher, QObject *parent) + : QAbstractListModel(parent) + , m_fileSystemWatcher(fileSystemWatcher) +{ + // add role names + int role = 0; + const QMetaObject meta = AssetsLibraryDir::staticMetaObject; + for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i) + m_roleNames.insert(role++, meta.property(i).name()); +} + +void AssetsLibraryModel::setSearchText(const QString &searchText) +{ + if (m_searchText != searchText) { + m_searchText = searchText; + refresh(); + } +} + void AssetsLibraryModel::saveExpandedState(bool expanded, const QString &assetPath) { m_expandedStateHash.insert(assetPath, expanded); @@ -208,66 +227,18 @@ QObject *AssetsLibraryModel::rootDir() const return m_assetsDir; } -const QStringList &AssetsLibraryModel::supportedImageSuffixes() +bool AssetsLibraryModel::isEmpty() const { - static QStringList retList; - if (retList.isEmpty()) { - const QList suffixes = QImageReader::supportedImageFormats(); - for (const QByteArray &suffix : suffixes) - retList.append("*." + QString::fromUtf8(suffix)); + return m_isEmpty; +}; + +void AssetsLibraryModel::setIsEmpty(bool empty) +{ + if (m_isEmpty != empty) { + m_isEmpty = empty; + emit isEmptyChanged(); } - return retList; -} - -const QStringList &AssetsLibraryModel::supportedFragmentShaderSuffixes() -{ - static const QStringList retList {"*.frag", "*.glsl", "*.glslf", "*.fsh"}; - return retList; -} - -const QStringList &AssetsLibraryModel::supportedShaderSuffixes() -{ - static const QStringList retList {"*.frag", "*.vert", - "*.glsl", "*.glslv", "*.glslf", - "*.vsh", "*.fsh"}; - return retList; -} - -const QStringList &AssetsLibraryModel::supportedFontSuffixes() -{ - static const QStringList retList {"*.ttf", "*.otf"}; - return retList; -} - -const QStringList &AssetsLibraryModel::supportedAudioSuffixes() -{ - static const QStringList retList {"*.wav", "*.mp3"}; - return retList; -} - -const QStringList &AssetsLibraryModel::supportedVideoSuffixes() -{ - static const QStringList retList {"*.mp4"}; - return retList; -} - -const QStringList &AssetsLibraryModel::supportedTexture3DSuffixes() -{ - // These are file types only supported by 3D textures - static QStringList retList {"*.hdr", "*.ktx"}; - return retList; -} - -AssetsLibraryModel::AssetsLibraryModel(Utils::FileSystemWatcher *fileSystemWatcher, QObject *parent) - : QAbstractListModel(parent) - , m_fileSystemWatcher(fileSystemWatcher) -{ - // add role names - int role = 0; - const QMetaObject meta = AssetsLibraryDir::staticMetaObject; - for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i) - m_roleNames.insert(role++, meta.property(i).name()); -} +}; QVariant AssetsLibraryModel::data(const QModelIndex &index, int role) const { @@ -377,12 +348,54 @@ void AssetsLibraryModel::setRootPath(const QString &path) qCInfo(assetsLibraryBenchmark) << "model reset:" << time.elapsed(); } -void AssetsLibraryModel::setSearchText(const QString &searchText) +const QStringList &AssetsLibraryModel::supportedImageSuffixes() { - if (m_searchText != searchText) { - m_searchText = searchText; - refresh(); + static QStringList retList; + if (retList.isEmpty()) { + const QList suffixes = QImageReader::supportedImageFormats(); + for (const QByteArray &suffix : suffixes) + retList.append("*." + QString::fromUtf8(suffix)); } + return retList; +} + +const QStringList &AssetsLibraryModel::supportedFragmentShaderSuffixes() +{ + static const QStringList retList {"*.frag", "*.glsl", "*.glslf", "*.fsh"}; + return retList; +} + +const QStringList &AssetsLibraryModel::supportedShaderSuffixes() +{ + static const QStringList retList {"*.frag", "*.vert", + "*.glsl", "*.glslv", "*.glslf", + "*.vsh", "*.fsh"}; + return retList; +} + +const QStringList &AssetsLibraryModel::supportedFontSuffixes() +{ + static const QStringList retList {"*.ttf", "*.otf"}; + return retList; +} + +const QStringList &AssetsLibraryModel::supportedAudioSuffixes() +{ + static const QStringList retList {"*.wav", "*.mp3"}; + return retList; +} + +const QStringList &AssetsLibraryModel::supportedVideoSuffixes() +{ + static const QStringList retList {"*.mp4"}; + return retList; +} + +const QStringList &AssetsLibraryModel::supportedTexture3DSuffixes() +{ + // These are file types only supported by 3D textures + static QStringList retList {"*.hdr", "*.ktx"}; + return retList; } const QSet &AssetsLibraryModel::supportedSuffixes() @@ -403,19 +416,6 @@ const QSet &AssetsLibraryModel::supportedSuffixes() return allSuffixes; } -bool AssetsLibraryModel::isEmpty() const -{ - return m_isEmpty; -}; - -void AssetsLibraryModel::setIsEmpty(bool empty) -{ - if (m_isEmpty != empty) { - m_isEmpty = empty; - emit isEmptyChanged(); - } -}; - const QSet &AssetsLibraryModel::previewableSuffixes() const { static QSet previewableSuffixes; From b0fa74756504e83b690ca737c6a67de1de8e32ba Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 10 Oct 2022 16:33:54 +0300 Subject: [PATCH 05/24] QmlDesigner: Add "imported" icon to the icons font Change-Id: I100a382a549b1945d7c7e83de0a3ffa609b5148c Reviewed-by: Miikka Heikkinen --- .../imports/StudioTheme/InternalConstants.qml | 242 +++++++++--------- .../imports/StudioTheme/icons.ttf | Bin 24432 -> 23968 bytes .../components/componentcore/theme.h | 4 +- 3 files changed, 121 insertions(+), 125 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml index 368a7e9b76f..484386ec946 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml @@ -71,128 +71,126 @@ QtObject { readonly property string centerHorizontal: "\u0042" readonly property string centerVertical: "\u0043" readonly property string closeCross: "\u0044" - readonly property string closeLink: "\u0045" - readonly property string colorPopupClose: "\u0046" - readonly property string columnsAndRows: "\u0047" - readonly property string copyLink: "\u0048" - readonly property string copyStyle: "\u0049" - readonly property string cornerA: "\u004A" - readonly property string cornerB: "\u004B" - readonly property string cornersAll: "\u004C" - readonly property string curveDesigner: "\u004D" - readonly property string curveEditor: "\u004E" - readonly property string customMaterialEditor: "\u004F" - readonly property string decisionNode: "\u0050" - readonly property string deleteColumn: "\u0051" - readonly property string deleteMaterial: "\u0052" - readonly property string deleteRow: "\u0053" - readonly property string deleteTable: "\u0054" - readonly property string detach: "\u0055" - readonly property string distributeBottom: "\u0056" - readonly property string distributeCenterHorizontal: "\u0057" - readonly property string distributeCenterVertical: "\u0058" - readonly property string distributeLeft: "\u0059" - readonly property string distributeOriginBottomRight: "\u005A" - readonly property string distributeOriginCenter: "\u005B" - readonly property string distributeOriginNone: "\u005C" - readonly property string distributeOriginTopLeft: "\u005D" - readonly property string distributeRight: "\u005E" - readonly property string distributeSpacingHorizontal: "\u005F" - readonly property string distributeSpacingVertical: "\u0060" - readonly property string distributeTop: "\u0061" - readonly property string download: "\u0062" - readonly property string downloadUnavailable: "\u0063" - readonly property string downloadUpdate: "\u0064" - readonly property string downloaded: "\u0065" - readonly property string edit: "\u0066" - readonly property string eyeDropper: "\u0067" - readonly property string favorite: "\u0068" - readonly property string flowAction: "\u0069" - readonly property string flowTransition: "\u006A" - readonly property string fontStyleBold: "\u006B" - readonly property string fontStyleItalic: "\u006C" - readonly property string fontStyleStrikethrough: "\u006D" - readonly property string fontStyleUnderline: "\u006E" - readonly property string gradient: "\u006F" - readonly property string gridView: "\u0070" - readonly property string idAliasOff: "\u0071" - readonly property string idAliasOn: "\u0072" - readonly property string infinity: "\u0073" - readonly property string keyframe: "\u0074" - readonly property string linkTriangle: "\u0075" - readonly property string linked: "\u0076" - readonly property string listView: "\u0077" - readonly property string lockOff: "\u0078" - readonly property string lockOn: "\u0079" - readonly property string materialPreviewEnvironment: "\u007A" - readonly property string materialPreviewModel: "\u007B" - readonly property string mergeCells: "\u007C" - readonly property string minus: "\u007D" - readonly property string mirror: "\u007E" - readonly property string newMaterial: "\u007F" - readonly property string openLink: "\u0080" - readonly property string openMaterialBrowser: "\u0081" - readonly property string orientation: "\u0082" - readonly property string paddingEdge: "\u0083" - readonly property string paddingFrame: "\u0084" - readonly property string pasteStyle: "\u0085" - readonly property string pause: "\u0086" - readonly property string pin: "\u0087" - readonly property string play: "\u0088" - readonly property string plus: "\u0089" - readonly property string promote: "\u008A" - readonly property string readOnly: "\u008B" - readonly property string redo: "\u008C" - readonly property string rotationFill: "\u008D" - readonly property string rotationOutline: "\u008E" - readonly property string search: "\u008F" - readonly property string sectionToggle: "\u0090" - readonly property string splitColumns: "\u0091" - readonly property string splitRows: "\u0092" - readonly property string startNode: "\u0093" - readonly property string testIcon: "\u0094" - readonly property string textAlignBottom: "\u0095" - readonly property string textAlignCenter: "\u0096" - readonly property string textAlignJustified: "\u0097" - readonly property string textAlignLeft: "\u0098" - readonly property string textAlignMiddle: "\u0099" - readonly property string textAlignRight: "\u009A" - readonly property string textAlignTop: "\u009B" - readonly property string textBulletList: "\u009D" - readonly property string textFullJustification: "\u009E" - readonly property string textNumberedList: "\u009F" - readonly property string tickIcon: "\u00A0" - readonly property string translationCreateFiles: "\u00A1" - readonly property string translationCreateReport: "\u00A2" - readonly property string translationExport: "\u00A3" - readonly property string translationImport: "\u00A4" - readonly property string translationSelectLanguages: "\u00A5" - readonly property string translationTest: "\u00A6" - readonly property string transparent: "\u00A7" - readonly property string triState: "\u00A8" - readonly property string triangleArcA: "\u00A9" - readonly property string triangleArcB: "\u00AA" - readonly property string triangleCornerA: "\u00AB" - readonly property string triangleCornerB: "\u00AC" - readonly property string unLinked: "\u00AE" - readonly property string undo: "\u00AF" - readonly property string unpin: "\u00B0" - readonly property string upDownIcon: "\u00B1" - readonly property string upDownSquare2: "\u00B2" - readonly property string visibilityOff: "\u00B3" - readonly property string visibilityOn: "\u00B4" - readonly property string wildcard: "\u00B5" - readonly property string wizardsAutomotive: "\u00B6" - readonly property string wizardsDesktop: "\u00B7" - readonly property string wizardsGeneric: "\u00B8" - readonly property string wizardsMcuEmpty: "\u00B9" - readonly property string wizardsMcuGraph: "\u00BA" - readonly property string wizardsMobile: "\u00BB" - readonly property string wizardsUnknown: "\u00BC" - readonly property string zoomAll: "\u00BD" - readonly property string zoomIn: "\u00BE" - readonly property string zoomOut: "\u00BF" - readonly property string zoomSelection: "\u00C0" + readonly property string colorPopupClose: "\u0045" + readonly property string columnsAndRows: "\u0046" + readonly property string copyStyle: "\u0047" + readonly property string cornerA: "\u0048" + readonly property string cornerB: "\u0049" + readonly property string cornersAll: "\u004A" + readonly property string curveDesigner: "\u004B" + readonly property string curveEditor: "\u004C" + readonly property string customMaterialEditor: "\u004D" + readonly property string decisionNode: "\u004E" + readonly property string deleteColumn: "\u004F" + readonly property string deleteMaterial: "\u0050" + readonly property string deleteRow: "\u0051" + readonly property string deleteTable: "\u0052" + readonly property string detach: "\u0053" + readonly property string distributeBottom: "\u0054" + readonly property string distributeCenterHorizontal: "\u0055" + readonly property string distributeCenterVertical: "\u0056" + readonly property string distributeLeft: "\u0057" + readonly property string distributeOriginBottomRight: "\u0058" + readonly property string distributeOriginCenter: "\u0059" + readonly property string distributeOriginNone: "\u005A" + readonly property string distributeOriginTopLeft: "\u005B" + readonly property string distributeRight: "\u005C" + readonly property string distributeSpacingHorizontal: "\u005D" + readonly property string distributeSpacingVertical: "\u005E" + readonly property string distributeTop: "\u005F" + readonly property string download: "\u0060" + readonly property string downloadUnavailable: "\u0061" + readonly property string downloadUpdate: "\u0062" + readonly property string downloaded: "\u0063" + readonly property string edit: "\u0064" + readonly property string eyeDropper: "\u0065" + readonly property string favorite: "\u0066" + readonly property string flowAction: "\u0067" + readonly property string flowTransition: "\u0068" + readonly property string fontStyleBold: "\u0069" + readonly property string fontStyleItalic: "\u006A" + readonly property string fontStyleStrikethrough: "\u006B" + readonly property string fontStyleUnderline: "\u006C" + readonly property string gradient: "\u006D" + readonly property string gridView: "\u006E" + readonly property string idAliasOff: "\u006F" + readonly property string idAliasOn: "\u0070" + readonly property string imported: "\u0071" + readonly property string infinity: "\u0072" + readonly property string keyframe: "\u0073" + readonly property string linkTriangle: "\u0074" + readonly property string linked: "\u0075" + readonly property string listView: "\u0076" + readonly property string lockOff: "\u0077" + readonly property string lockOn: "\u0078" + readonly property string materialPreviewEnvironment: "\u0079" + readonly property string materialPreviewModel: "\u007A" + readonly property string mergeCells: "\u007B" + readonly property string minus: "\u007C" + readonly property string mirror: "\u007D" + readonly property string newMaterial: "\u007E" + readonly property string openMaterialBrowser: "\u007F" + readonly property string orientation: "\u0080" + readonly property string paddingEdge: "\u0081" + readonly property string paddingFrame: "\u0082" + readonly property string pasteStyle: "\u0083" + readonly property string pause: "\u0084" + readonly property string pin: "\u0085" + readonly property string play: "\u0086" + readonly property string plus: "\u0087" + readonly property string promote: "\u0088" + readonly property string readOnly: "\u0089" + readonly property string redo: "\u008A" + readonly property string rotationFill: "\u008B" + readonly property string rotationOutline: "\u008C" + readonly property string search: "\u008D" + readonly property string sectionToggle: "\u008E" + readonly property string splitColumns: "\u008F" + readonly property string splitRows: "\u0090" + readonly property string startNode: "\u0091" + readonly property string testIcon: "\u0092" + readonly property string textAlignBottom: "\u0093" + readonly property string textAlignCenter: "\u0094" + readonly property string textAlignJustified: "\u0095" + readonly property string textAlignLeft: "\u0096" + readonly property string textAlignMiddle: "\u0097" + readonly property string textAlignRight: "\u0098" + readonly property string textAlignTop: "\u0099" + readonly property string textBulletList: "\u009A" + readonly property string textFullJustification: "\u009B" + readonly property string textNumberedList: "\u009D" + readonly property string tickIcon: "\u009E" + readonly property string translationCreateFiles: "\u009F" + readonly property string translationCreateReport: "\u00A0" + readonly property string translationExport: "\u00A1" + readonly property string translationImport: "\u00A2" + readonly property string translationSelectLanguages: "\u00A3" + readonly property string translationTest: "\u00A4" + readonly property string transparent: "\u00A5" + readonly property string triState: "\u00A6" + readonly property string triangleArcA: "\u00A7" + readonly property string triangleArcB: "\u00A8" + readonly property string triangleCornerA: "\u00A9" + readonly property string triangleCornerB: "\u00AA" + readonly property string unLinked: "\u00AB" + readonly property string undo: "\u00AC" + readonly property string unpin: "\u00AE" + readonly property string upDownIcon: "\u00AF" + readonly property string upDownSquare2: "\u00B0" + readonly property string visibilityOff: "\u00B1" + readonly property string visibilityOn: "\u00B2" + readonly property string wildcard: "\u00B3" + readonly property string wizardsAutomotive: "\u00B4" + readonly property string wizardsDesktop: "\u00B5" + readonly property string wizardsGeneric: "\u00B6" + readonly property string wizardsMcuEmpty: "\u00B7" + readonly property string wizardsMcuGraph: "\u00B8" + readonly property string wizardsMobile: "\u00B9" + readonly property string wizardsUnknown: "\u00BA" + readonly property string zoomAll: "\u00BB" + readonly property string zoomIn: "\u00BC" + readonly property string zoomOut: "\u00BD" + readonly property string zoomSelection: "\u00BE" readonly property font iconFont: Qt.font({ "family": controlIcons.name, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index acd8df6ce3ff87fe98d8d5df178d672e0d6d070e..e3b40281c8265d55a97d54aa1443743a3a6928af 100644 GIT binary patch delta 1450 zcmeyck8#0n#(D-u1_lORh6V;^h5$FW5Z}29ZJ7)Vu`LV?3^M+~`bLqhsVNK$j1deB z3<=4(i3RulcxEs#Ff%YPFa{-;l_)SMGF37#u!Jx$FtDU278m^g50Z?nVPIh3NYANE zlkq?Kf`Nf`1_Og9Pey8DifZhgas~#5I}8jAW*Hf&^@&`c|4(FKU=(3sU{J}(EvXRO z%Pqvfz_^2ffzd4|KRJ=5Ts((?fhB^0fzcs1v7&(CGs9^H21W}81_p(^#N5>B3yv@| zF!(KDU|_mgkY8L7#*xACfYXPwiE{_%FD?VFIIcZh7r0(+i>S`&*MJA zeS`Z8j{uJfPZiH0UOrww-f6r~_!#)q_$v5T@a^O0;5Xx+#D7A7L%>5IO<;$>1%YRR zI)Xid7lg!wI)v^Bs|ec&hY3#-{wHE5;w2I%(kHU0UgVX?4^cJI2+;>(5@H@=MPkdu zwun6v7Z8^dw-KKteosO}qD119q?lxm*Rw8WWfElF9K!vEjfstYvy;$7#>w^~C7b7qnsLOlFu48CWS+@%k%5hY zn?Z;{l7WFyosXH_kdIMKU09A;+?(RZxnHNY>-x?pE-pcKv)axZJ0o@fJl17n z=i=aGnyORR^Xx$-7ptTavu<7Qv-?%L%(A*{tc+Zen_1+dIaFRU>oCYNs4y_FD5sD7ZzhTHk({$Zy+Ng@^6pGH=b>Rf?N0)*Dx_A=`bp4C%+O9*dik{`INnmMs{{K zqp^8*wi#m@V?t+p^1ll?S=rf)=3@0xZU01K>O?c!K8n>xHEmXQun?%1X0QNfNd^W+ z21$kvD4U6aonaG{&CFoNr~zfOFi0{^hO${1_!-Ya*=!7wOo9x|42&$Cpi+bZR2+fW zj0{E$Ay9E920n&GP&P9|4#O@GTY-g>frY_{F&@NW;bdTCkYij6WwS9DG2Wg0D?n2# zmm!fMi6N08g`tQclYzlGzo4=xGd-h3K_gjH!N|bKNJk+zF)1;nD06a5-~moU1_K6N z215pe$;v?%tcC`jW7U8PQ?70Q`MJ1^zlf$D< hZPtrcWKjVXHUIyEiycrw%y7@=EvRHeDxuEI001)aT#Wz# delta 1998 zcmZ3moAJXw#(D-u1_lORh6V;^h5$FW5Z^hk*YYzk#D_32Fv$1^>l;OOq{c8XFh(#i zFeD`BCKlX(w|W)>12YQ)17lEfS&0IJB2y&;0}Du=B|WjY;QxOHW(J0M9|i^nj`W<$ zw2bd*pBNZe7cek*t;tADOi|SoI>^AlaEF0`!7L*qwLX#S<^PEc42&WS3=Aq6xg`~1 zh1?+i4h9BBublkkM6>^1Wef}~AV;|5CRP+Md}TPzz`$t1z`&r8mzbNn@5NhV28IA1 z1_q|51^LA#X^9`47#M<07#MgYz@B4dU^x40&*^x6o39Mq%r6)i7#QyRryqjQGU))^vJ|5-8|%5bgf|JF5#bPt6FDWyB`PMWRWBMPnkTwV^oZyu zF%_{jVo$_H#O=h3#2dudiQf@_CBY#PC$UQ6i=>0(G|5L&7E)8B9!S?nFOYsF<0aD} zb4=DrHb?fB>?b)MIW;*axeB>$a_{7u7ozgeu6y*~t1}a@D zXH?l#!x)$t6d4#8wU}lxY+lT|oRvw4WwQ_W8#X3(w#`;T6B+CE{--hTV*11&&A`CP zC?>+Dq|V96rle+K&dI1|VrC@H$!KOICc@67z&L?ZSd#N!!M_4dNnuXL3I7T}e8vfk z6To~O?Bf3lAo{?u&HUez`8l&Z12+Q$Clfm-qdF(!Yc4tpjT)yztAG{*S~Kd6POBpvW29C+>QSBgA4&1 z$hbLAyU?OwfkmcHrfQD&zkXp!&IT?J(U_r@VpTWC=@-y)M?vyF%)hdvX7+y8Rr znM@ZMm>Jj^7#P(V#f8}!&6)dk{yf&<(q)#_Wts|NGDqtEd92H@`HD<5hyM*`X$E-) zH3kM2B{g+(IYwh6GjlseHFZ5kB{p_-J4PchaXCg2Hg+~aQAJT*Mo}j3gWKG-ZRdrB z&$SJ~wcyJZx7xXHG2x0}})Le>-NP zEn_CmvcIa5f*6)J_VWj017b~biJHFaSzc4IS>$+v9{WVpEg z?GgFLvyGE;3m@YeCdMQkMn&!9R{{cC`1mHP+v(_<=9*+P8k?Ksnwl}DF(!1jC;z*U zlVy@?%4jZDAJz6xB&JR@v+bi;eN+pQSP7db`?-xwEeUKD7@$ig^}asK89L2*o6yvaHF#i>4-dD)Y#LbW-0 zlJg5HLA=e0p_xUCN2; Date: Tue, 27 Sep 2022 15:05:26 +0300 Subject: [PATCH 06/24] Fix copying dynamic properties on materials Fixes: QDS-7803 Change-Id: I24c8cd269965552a62fbbbc521efbff00811fa43 Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Bot --- .../MaterialBrowser.qml | 5 +- .../materialbrowser/materialbrowsermodel.cpp | 60 ++++++++++++------- .../materialbrowser/materialbrowsermodel.h | 1 + .../materialbrowser/materialbrowserview.cpp | 38 +++++++++--- .../designercore/include/modelnode.h | 1 + .../designercore/model/modelnode.cpp | 12 ++++ 6 files changed, 88 insertions(+), 29 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 1e50f3f99b2..2fecc7582ad 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -125,7 +125,10 @@ Item { width: parent.width onAboutToShow: { - root.matSectionsModel = ["All"]; + if (root.currentMaterial.hasDynamicProperties) + root.matSectionsModel = ["All", "Custom"]; + else + root.matSectionsModel = ["All"]; switch (root.currentMaterial.materialType) { case "DefaultMaterial": diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index e9af23eb804..cb3a295259b 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -73,6 +73,9 @@ QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const return matType; } + if (roleName == "hasDynamicProperties") + return !m_materialList.at(index.row()).dynamicProperties().isEmpty(); + return {}; } @@ -143,7 +146,8 @@ QHash MaterialBrowserModel::roleNames() const {Qt::UserRole + 1, "materialName"}, {Qt::UserRole + 2, "materialInternalId"}, {Qt::UserRole + 3, "materialVisible"}, - {Qt::UserRole + 4, "materialType"} + {Qt::UserRole + 4, "materialType"}, + {Qt::UserRole + 5, "hasDynamicProperties"} }; return roles; } @@ -360,33 +364,47 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io setCopiedMaterialType(matType); m_allPropsCopied = section == "All"; + bool dynamicPropsCopied = section == "Custom"; QmlObjectNode mat(m_copiedMaterial); QSet validProps; + QHash dynamicProps; PropertyNameList copiedProps; - // Base state properties are always valid - const auto baseProps = m_copiedMaterial.propertyNames(); - for (const auto &baseProp : baseProps) - validProps.insert(baseProp); - - if (!mat.isInBaseState()) { - QmlPropertyChanges changes = mat.propertyChangeForCurrentState(); - if (changes.isValid()) { - const QList changedProps = changes.targetProperties(); - for (const auto &changedProp : changedProps) - validProps.insert(changedProp.name()); + if (dynamicPropsCopied || m_allPropsCopied) { + // Dynamic properties must always be set in base state + const QList dynProps = m_copiedMaterial.dynamicProperties(); + for (const auto &prop : dynProps) { + dynamicProps.insert(prop.name(), prop.dynamicTypeName()); + validProps.insert(prop.name()); } } - if (mat.timelineIsActive()) { - const QList keyframeGroups - = mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial); - for (const auto &kfg : keyframeGroups) - validProps.insert(kfg.propertyName()); - } + if (!dynamicPropsCopied) { + // Base state properties are always valid + const auto baseProps = m_copiedMaterial.propertyNames(); + for (const auto &baseProp : baseProps) + validProps.insert(baseProp); - if (m_allPropsCopied || m_propertyGroupsObj.empty()) { + if (!mat.isInBaseState()) { + QmlPropertyChanges changes = mat.propertyChangeForCurrentState(); + if (changes.isValid()) { + const QList changedProps = changes.targetProperties(); + for (const auto &changedProp : changedProps) + validProps.insert(changedProp.name()); + } + } + + if (mat.timelineIsActive()) { + const QList keyframeGroups + = mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial); + for (const auto &kfg : keyframeGroups) + validProps.insert(kfg.propertyName()); + } + } + validProps.remove("objectName"); + + if (m_allPropsCopied || dynamicPropsCopied || m_propertyGroupsObj.empty()) { copiedProps = validProps.values(); } else { QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject(); @@ -411,8 +429,10 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io PropertyCopyData data; data.name = propName; data.isValid = m_allPropsCopied || validProps.contains(propName); - data.isBinding = mat.hasBindingProperty(propName); if (data.isValid) { + if (dynamicProps.contains(propName)) + data.dynamicTypeName = dynamicProps[propName]; + data.isBinding = mat.hasBindingProperty(propName); if (data.isBinding) data.value = mat.expression(propName); else diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index c054d07527b..3cd8b65a411 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -97,6 +97,7 @@ public: struct PropertyCopyData { PropertyName name; + TypeName dynamicTypeName; QVariant value; bool isBinding = false; bool isValid = false; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 01ee657f848..94c75d93a77 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -25,6 +25,7 @@ #include "materialbrowserview.h" +#include "bindingproperty.h" #include "bundlematerial.h" #include "materialbrowserwidget.h" #include "materialbrowsermodel.h" @@ -105,13 +106,19 @@ WidgetInfo MaterialBrowserView::widgetInfo() // remove current properties PropertyNameList propNames; if (mat.isInBaseState()) { - propNames = material.propertyNames(); + const QList baseProps = material.properties(); + for (const auto &baseProp : baseProps) { + if (!baseProp.isDynamic()) + propNames.append(baseProp.name()); + } } else { QmlPropertyChanges changes = mat.propertyChangeForCurrentState(); if (changes.isValid()) { const QList changedProps = changes.targetProperties(); - for (const auto &changedProp : changedProps) - propNames.append(changedProp.name()); + for (const auto &changedProp : changedProps) { + if (!changedProp.isDynamic()) + propNames.append(changedProp.name()); + } } } for (const PropertyName &propName : qAsConst(propNames)) { @@ -122,14 +129,29 @@ WidgetInfo MaterialBrowserView::widgetInfo() // apply pasted properties for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) { - if (propData.name == "objectName") - continue; - if (propData.isValid) { - if (propData.isBinding) + const bool isDynamic = !propData.dynamicTypeName.isEmpty(); + const bool isBaseState = currentState().isBaseState(); + const bool hasProperty = mat.hasProperty(propData.name); + if (propData.isBinding) { + if (isDynamic && (!hasProperty || isBaseState)) { + mat.modelNode().bindingProperty(propData.name) + .setDynamicTypeNameAndExpression( + propData.dynamicTypeName, propData.value.toString()); + continue; + } mat.setBindingProperty(propData.name, propData.value.toString()); - else + } else { + const bool isRecording = mat.timelineIsActive() + && mat.currentTimeline().isRecording(); + if (isDynamic && (!hasProperty || (isBaseState && !isRecording))) { + mat.modelNode().variantProperty(propData.name) + .setDynamicTypeNameAndValue( + propData.dynamicTypeName, propData.value); + continue; + } mat.setVariantProperty(propData.name, propData.value); + } } else { mat.removeProperty(propData.name); } diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index def083f02f6..e44234fffb6 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -145,6 +145,7 @@ public: QList nodeListProperties() const; QList bindingProperties() const; QList signalProperties() const; + QList dynamicProperties() const; PropertyNameList propertyNames() const; bool hasProperties() const; diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 913c67b1a24..c221215acc0 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -691,6 +691,18 @@ QList ModelNode::signalProperties() const return propertyList; } +QList ModelNode::dynamicProperties() const +{ + QList propertyList; + + const QList abstractProperties = properties(); + for (const AbstractProperty &abstractProperty : abstractProperties) { + if (abstractProperty.isDynamic()) + propertyList.append(abstractProperty); + } + return propertyList; +} + /*! \brief removes a property from this node \param name name of the property From 007a9a46a52b8a71b8c78ff50456033b720362a5 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 10 Oct 2022 17:41:40 +0300 Subject: [PATCH 07/24] QmlDesigner: Reset item library drag on model detach Fixes: QDS-7823 Change-Id: If0b758f79dd4a55356d2cd5aefe65fa3e6e321be Reviewed-by: Reviewed-by: Mahmoud Badri --- .../qmldesigner/components/itemlibrary/itemlibrarywidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 51b807d614a..a72c334a4cb 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -295,8 +295,10 @@ void ItemLibraryWidget::delayedUpdateModel() void ItemLibraryWidget::setModel(Model *model) { m_model = model; - if (!model) + if (!model) { + m_itemToDrag = {}; return; + } setItemLibraryInfo(model->metaInfo().itemLibraryInfo()); From b30233e619b6b118382c9f7a2eaee2da4c0c7ba4 Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Wed, 5 Oct 2022 16:32:18 +0200 Subject: [PATCH 08/24] QmlDesigner: Modify States Tutorial Change in some texts order, and trying to update to keep it relevant for the newer version. Fixes: QDS-7761 Change-Id: I05812f806dd56e2d11d63652d399a776599282cf Reviewed-by: Leena Miettinen --- doc/qtdesignstudio/examples/doc/loginui3.qdoc | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/doc/qtdesignstudio/examples/doc/loginui3.qdoc b/doc/qtdesignstudio/examples/doc/loginui3.qdoc index bbe81f777db..d4799d199d4 100644 --- a/doc/qtdesignstudio/examples/doc/loginui3.qdoc +++ b/doc/qtdesignstudio/examples/doc/loginui3.qdoc @@ -137,29 +137,6 @@ \image loginui3-login-state-preview.jpg "Preview of the login state" - \section2 Learn More - States - - The \l{Adding States}{state} of a particular visual component is the set of - information which describes how and where the individual parts of the visual - component are displayed within it, and all the data associated with that - state. Most visual components in a UI will have a limited number of states, - each with well-defined properties. - - For example, a list item may be either selected or not, and if - selected, it may either be the currently active single selection or it - may be part of a selection group. Each of those states may have certain - associated visual appearance (neutral, highlighted, expanded, and so on). - - Youn can apply states to trigger behavior or animations. UI components - typically have a default state that contains all of a component's initial - property values and is therefore useful for managing property values before - state changes. - - You can specify additional states by adding new states. Each state within a - component has a unique name. To change the current state of an component, - the state property is set to the name of the state. State changes can be - bound to conditions by using the \c when property. - Next, you will create connections to specify that clicking the \uicontrol {Create Account} button on the login page triggers a transition to the account creation page. @@ -184,9 +161,13 @@ \e createAccount should apply. \li Double-click the value \uicontrol Action column and select \uicontrol {Change state to createAccount} in the drop-down menu. - \image loginui3-connections.png "Connections tab" + \note Or, you can right-click the \e createAccount button in \l Navigator. + Then select \uicontrol {Connections} > \uicontrol {Add signal handler} > + \uicontrol {clicked} > \uicontrol {Change State to createAccount}. + \image loginui3-connections.png "Connections tab" \li Select \uicontrol File > \uicontrol Save or press \key {Ctrl+S} to save your changes. + \endlist In the live preview, you can now click the \uicontrol {Create Account} @@ -194,8 +175,30 @@ \image loginui3.gif "Moving between login page and account creation page" + \section1 Learn More + \section2 States + The \l{Adding States}{state} of a particular visual component is the set of + information which describes how and where the individual parts of the visual + component are displayed within it, and all the data associated with that + state. Most visual components in a UI will have a limited number of states, + each with well-defined properties. - \section2 Learn More - Signal and Event Handlers + For example, a list item may be either selected or not, and if + selected, it may either be the currently active single selection or it + may be part of a selection group. Each of those states may have certain + associated visual appearance (neutral, highlighted, expanded, and so on). + + Youn can apply states to trigger behavior or animations. UI components + typically have a default state that contains all of a component's initial + property values and is therefore useful for managing property values before + state changes. + + You can specify additional states by adding new states. Each state within a + component has a unique name. To change the current state of an component, + the state property is set to the name of the state. State changes can be + bound to conditions by using the \c when property. + + \section2 Signal and Event Handlers UI components need to communicate with each other. For example, a button needs to know that the user has clicked on it. In response, the button may From a902729b35cea630dd33fa66a857df76e0c301d3 Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Tue, 4 Oct 2022 17:41:45 +0200 Subject: [PATCH 09/24] QmlDesigner: Update UI Positioning document Change in some texts, re-organized icons, and moved the Learn more section to reduce complexity of the tutorial. Fixes: QDS-7761 Change-Id: I504cb0a5edeee4c6798f22c1d4fd4332a8fd8c26 Reviewed-by: Leena Miettinen --- doc/qtdesignstudio/examples/doc/loginui2.qdoc | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/doc/qtdesignstudio/examples/doc/loginui2.qdoc b/doc/qtdesignstudio/examples/doc/loginui2.qdoc index aeb1111f33b..e4318179adb 100644 --- a/doc/qtdesignstudio/examples/doc/loginui2.qdoc +++ b/doc/qtdesignstudio/examples/doc/loginui2.qdoc @@ -98,13 +98,11 @@ rectangle at the top, while keeping its horizontal center aligned with that of the rectangle. \li Select \e tagLine in \uicontrol Navigator. - \li In \uicontrol Properties > \uicontrol Layout, deselect the - \inlineimage icons/anchor-center-vertical.png - button to remove the vertical center anchor, and then select the - \inlineimage icons/anchor-top.png - button to anchor the tag line to - \e qt_logo_green_128x128px in the \uicontrol Target field with a - 40-pixel margin. This attaches the top of the tag line to the + \li In \uicontrol Properties > \uicontrol Layout, + select the \inlineimage icons/anchor-top.png + button and then select \e qt_logo_green_128x128px + as \uicontrol Target to anchor \e tagLine with a 40-pixel margin. + This attaches the top of the tag line to the bottom of the logo, while keeping its horizontal center aligned with that of the rectangle. \image loginui2-layout-text.png "Text Layout properties" @@ -123,20 +121,6 @@ \image loginui2-loginpage.jpg "Login page in the Design mode and live preview" - \section2 Learn More - Anchors - - In an anchor-based layout, each component instance can be thought of as - having a set of invisible \e anchor lines: top, bottom, left, right, fill, - horizontal center, vertical center, and baseline. - - Anchors enable placing a component instance either adjacent to or inside of - another component instance, by attaching one or more of the instance's - anchor lines to the anchor lines of the other component instance. If a - component instance changes, the instances that are anchored to it will - adjust automatically to maintain the anchoring. - - For more information, see \l{Positioning with Anchors}. - \section1 Using Column Positioners You will now position the entry fields and buttons in columns @@ -172,7 +156,7 @@ \li Select \e fields in \uicontrol Navigator. \li In \uicontrol Properties > \uicontrol Layout, select the \inlineimage icons/anchor-top.png - button to anchor the top of the field column to + button to anchor the top of the fields column to the bottom of \e tagLine with a 170-pixel margin. \li Select the \inlineimage icons/anchor-center-horizontal.png button to anchor the column horizontally to its parent. @@ -192,7 +176,20 @@ \image loginui2-loginpage-ready.jpg "Login page in the Design mode and live preview" - \section1 Learn More - Positioners + \section1 Learn More + \section2 Anchors + In an anchor-based layout, each component instance can be thought of as + having a set of invisible \e anchor lines: top, bottom, left, right, fill, + horizontal center, vertical center, and baseline. + + Anchors enable placing a component instance either adjacent to or inside of + another component instance, by attaching one or more of the instance's + anchor lines to the anchor lines of the other component instance. If a + component instance changes, the instances that are anchored to it will + adjust automatically to maintain the anchoring. + + For more information, see \l{Positioning with Anchors}. + \section2 Positioners For many use cases, the best positioner to use is a simple grid, row, or column, and \QDS provides components that will position children in these From 0645a8aef341ef01628bb05fae4c54fc54297e24 Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Tue, 4 Oct 2022 12:08:11 +0200 Subject: [PATCH 10/24] QmlDesigner: Improve the UI tutorial Change the arrangement of texts, update images Fixes: QDS-7761 Change-Id: I63447ce34a72e2a2df7c18053276ba1362386c00 Reviewed-by: Leena Miettinen --- .../doc/images/loginui1-library-assets.jpg | Bin 58564 -> 68266 bytes .../examples/doc/images/loginui1-project.png | Bin 41456 -> 35138 bytes doc/qtdesignstudio/examples/doc/loginui1.qdoc | 310 +++++++++--------- 3 files changed, 161 insertions(+), 149 deletions(-) diff --git a/doc/qtdesignstudio/examples/doc/images/loginui1-library-assets.jpg b/doc/qtdesignstudio/examples/doc/images/loginui1-library-assets.jpg index 999959b20bf76cd8713b154fc37ec46500872f2a..4dc8e4e910c0019c5e3e05d1d0ae0895feb1d82d 100644 GIT binary patch literal 68266 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 literal 58564 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 z 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 diff --git a/doc/qtdesignstudio/examples/doc/images/loginui1-project.png b/doc/qtdesignstudio/examples/doc/images/loginui1-project.png index 93ca7c6c8c9f4fb0eb49f5a579fd7e9d101d73a1..28984175b94f76dcb086e20f7ea2480253d986d3 100644 GIT binary patch literal 35138 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
}S91b>DZ%_=)~0qYYPfdi<>Ne7l(* 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

=w;rLBAF7JNT<2t)%k$%aQHCw;msr|0_ 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 \inlineimage icons/plus.png - . + (Select \uicontrol View > \uicontrol Views > \uicontrol Assets to enable it, + if you can't find it). \li Select the asset files, and then select \uicontrol Open. \li Select the location where the files will be saved in the \uicontrol {Add Resources} dialog. @@ -180,8 +138,8 @@ To modify the \e Screen01 component in the \uicontrol {2D} view: \list 1 - \li Drag-and-drop the background image from \uicontrol Assets to the - rectangle in \l Navigator. + \li Drag-and-drop the background image (1) from \uicontrol Assets to the + \l{basic-rectangle}{Rectangle} (2) in \l Navigator. \image loginui1-library-assets.jpg "Assets view" \li \QDS automatically creates an instance of the \l{Images}{Image} component for you with the path to the image file set as the @@ -189,7 +147,7 @@ \image loginui1-image-properties.png "Image properties" \li Drag-and-drop the Qt logo from \uicontrol Assets to the rectangle in \uicontrol Navigator and move it to the top-center of the - background image in \uicontrol the {2D} view. + background image in the \uicontrol {2D} view. \li Select \e Text in \uicontrol Navigator and drag it below the logo in the \uicontrol {2D} view. If the text is hidden behind the background, select \inlineimage icons/navigator-arrowdown.png @@ -204,8 +162,8 @@ line: \e {Are you ready to explore?}. \image loginui1-text-properties.png "Text properties" \li In \uicontrol Font, select \e {Titillium Web ExtraLight}. - \li In \uicontrol Size, set the font size of the tag line to - \e 50 pixels (\uicontrol px). + \li In \uicontrol Size, first select the scale to pixels (\uicontrol px), + then set font size of the tag line to \e 50 (\uicontrol px). \li In \uicontrol {Text color}, set the text color to white (\e #ffffff). \endlist @@ -219,74 +177,6 @@ \image loginui1-main-page.jpg "Modified UI in the Design mode" You can resize the preview dialog to display the whole screen. - - \section2 Learn More - Components - - \QDS provides preset \l{glossary-component}{components} for creating - UIs, including components for creating and animating visual components, - receiving user input, and creating data models and views. - - To be able to use the functionality of preset components, the wizard template - adds the following \e import statements to the UI files (.ui.qml) that it - creates: - - \quotefromfile Loginui1/content/Screen01.ui.qml - \skipto import - \printuntil Controls - - You can view the import statements in the \uicontrol {Code} view. - - The \l Components view lists the components in each module that are - supported by \QDS. You can use the basic components to create your own - components, and they will be listed in \uicontrol {My Components}. - This section is only visible if you have created custom components. - - The \l {basic-rectangle}{Rectangle}, \l Text, and \l {Images}{Image} - components used in this tutorial are based on the \l Item component. - It is the base component for all visual elements, with implementation - of basic functions and properties, such as component type, ID, position, - size, and visibility. - - For more information, see \l{Use Case - Visual Elements In QML}. For - descriptions of all components, see \l{All QML Types} in the Qt reference - documentation. - - \section3 Regtangle Properties - - The default \l {basic-rectangle}{Rectangle} component is used for drawing - shapes with four sides and four corners. You can fill rectangles either with - a solid fill color or a gradient. You can specify the border color separately. - By setting the value of the radius property, you can create shapes with - rounded corners. - - If you want to specify the radius of each corner separately, you can use the - \l{studio-rectangle}{Rectangle} component from the - \uicontrol {Qt Quick Studio Components} module instead of the basic rectangle - component. It is available in \uicontrol Components - > \uicontrol {Qt Quick Studio Components}. - - \section3 Text Properties - - The \l Text component is used for adding static text to the UI, such as - titles and labels. You can select the font to use and specify extensive - properties for each text component, such as size in points or pixels, - weight, style, and spacing. - - If you want to create a label with a background, use the \l Label component - from the \uicontrol {Qt Quick Controls} module instead of the Text component. - - \section3 Image Properties - - The \l {Images}{Image} component is used for adding images to the UI in several - supported formats, including bitmap formats such as PNG and JPEG and vector - graphics formats such as SVG. To add an image to \uicontrol Assets, select - \inlineimage icons/plus.png - , and then select the image file. - - If you need to display animated images, use the \l {Animated Image} - component, also available in \uicontrol Components > - \uicontrol {Default Components} > \uicontrol Basic. - \section1 Creating a Push Button You can use another wizard template to create a push button and to add it to @@ -320,21 +210,9 @@ \image loginui1-button.png "Button in the Design mode." - \section2 Learn More - UI Controls - - The \e {Custom Button} wizard template creates a button component - based on the \l {Button} control in the \l {Qt Quick Controls} module. It - is a push-button control that can be pushed or clicked by the user. Buttons - are normally used to perform an action or to answer a question. The - properties and functionality inherited from the Button component enable - you to set text, display an icon, react to mouse clicks, and so on. - - To be able to use the functionality of the Button control, the wizard template - adds the following \e import statements to the \e EntryField.ui.qml file: - - \quotefromfile Loginui1/content/EntryField.ui.qml - \skipto import - \printuntil Controls + \note To open the \uicontrol States view, select it from + \uicontrol View > \uicontrol Views > \uicontrol States, if + it is not available by default. Next, you will change the appearance of the EntryField component by modifying its properties. @@ -375,8 +253,8 @@ properties in \uicontrol Properties. \li In \uicontrol Character > \uicontrol Font, select \e {Titillium Web ExtraLight}. - \li In \uicontrol Size, set the font size to \e 34 pixels - (\uicontrol px). + \li In \uicontrol Size, first select the scale to pixels (\uicontrol px), + then set font size to \e 34 (\uicontrol px). \li In \uicontrol {Text color}, set the text color to white (\e #ffffff). \li In \uicontrol {Alignment H}, select the \uicontrol Left button to @@ -396,6 +274,10 @@ \image loginui1-entry-field-styled.jpg "Modified button in the 2D view" + \note Do not edit the the value of \uicontrol Text in the \uicontrol Character + property, because this will break the connection, and later you won't be able + to change the text in \uicontrol {Button Content} > \uicontrol Text. + Next, you will add instances of the \e EntryField component to the \e Screen01 component and modify their properties. @@ -459,7 +341,8 @@ its properties in \uicontrol Properties. \li In \uicontrol Character > \uicontrol Font, select \e {Titillium Web ExtraLight}. - \li In \uicontrol Size, set the font size to \e 34 pixels. + \li In \uicontrol Size, first select the scale to pixels (\uicontrol px), + then set font size to \e 34 (\uicontrol px). \li In \uicontrol {Text color}, set the text color to \e #41cd52. \li In the \uicontrol States view, select the \e normal state and repeat the changes, as necessary. @@ -503,7 +386,136 @@ \image loginui1-ready.jpg "The finished UI in the 2D view" - \section2 Learn More - Component IDs + \section1 Learn More + The \e {Learn More} sections provide additional information about the + tasks performed by the wizards and about other basic tasks and concepts. + + \section2 Projects and Files + \QDS creates a set of files and folders that you need to create + a UI. The files are listed in the \l{File System} view. + + \image loginui1-project-files.png + \list + \li The \e {loginui1.qmlproject} project file defines that all + component, JavaScript, and image files in the project folder belong + to the project. Therefore, you do not need to individually list new + files when you add them to the project. + \li The \e {loginui1.qml} file defines the functionality of + the UI. For the time being, it does not do anything. + \li The \e {Screen01.ui.qml} file is a custom component created by + the wizard template. For more information, see \l {UI Files}. + + By default, this is the main file in the project, but you can + change that in the .qmlproject file. While the custom component + is a good starting point for new users, you don't have to use it. + Specifically, if you export and import designs using \QB, your main + file is most likely called something else. For more information, + see \l {Exporting from Design Tools}. + \li The \e CMakeLists.txt project configuration file allowing you to + share your project as a fully working C++ application with + developers. + \li The \e {qtquickcontrols2.conf} file specifies the selected + \l {Styling Qt Quick Controls}{UI style} and some style-specific + arguments. + \li The \e imports folder contains \e {Constants.qml} and + \e {DirectoryFontLoader.qml} files that specify a font loader + and a \e qmldir module definition file that declares the Constant + component. For more information, see + \l {Module Definition qmldir Files}. The \e EventListModel.qml and + \e EventListSimulator.qml files are not used in this example, so + you can ignore them for now. + \endlist + \l{UI Files}{UI files} define a hierarchy of components with a + highly-readable, structured layout. Every UI file consists of two parts: + an imports section and an component declaration section. The components and + functionality most common to UIs are provided in the \c QtQuick import. You + can view the code of a \e .ui.qml file in the \l{Code} view. + + + \section2 Components + + \QDS provides preset \l{glossary-component}{components} for creating + UIs, including components for creating and animating visual components, + receiving user input, and creating data models and views. + + To be able to use the functionality of preset components, the wizard template + adds the following \e import statements to the UI files (.ui.qml) that it + creates: + + \quotefromfile Loginui1/content/Screen01.ui.qml + \skipto import + \printuntil Controls + + You can view the import statements in the \uicontrol {Code} view. + + The \l Components view lists the components in each module that are + supported by \QDS. You can use the basic components to create your own + components, and they will be listed in \uicontrol {My Components}. + This section is only visible if you have created custom components. + + The \l {basic-rectangle}{Rectangle}, \l Text, and \l {Images}{Image} + components used in this tutorial are based on the \l Item component. + It is the base component for all visual elements, with implementation + of basic functions and properties, such as component type, ID, position, + size, and visibility. + + For more information, see \l{Use Case - Visual Elements In QML}. For + descriptions of all components, see \l{All QML Types} in the Qt reference + documentation. + + \section3 Regtangle Properties + + The default \l {basic-rectangle}{Rectangle} component is used for drawing + shapes with four sides and four corners. You can fill rectangles either with + a solid fill color or a gradient. You can specify the border color separately. + By setting the value of the radius property, you can create shapes with + rounded corners. + + If you want to specify the radius of each corner separately, you can use the + \l{studio-rectangle}{Rectangle} component from the + \uicontrol {Qt Quick Studio Components} module instead of the basic rectangle + component. It is available in \uicontrol Components + > \uicontrol {Qt Quick Studio Components}. + + \section3 Text Properties + + The \l Text component is used for adding static text to the UI, such as + titles and labels. You can select the font to use and specify extensive + properties for each text component, such as size in points or pixels, + weight, style, and spacing. + + If you want to create a label with a background, use the \l Label component + from the \uicontrol {Qt Quick Controls} module instead of the Text component. + + \section3 Image Properties + + The \l {Images}{Image} component is used for adding images to the UI in several + supported formats, including bitmap formats such as PNG and JPEG and vector + graphics formats such as SVG. To add an image to \uicontrol Assets, select + \inlineimage icons/plus.png + , and then select the image file. + + If you need to display animated images, use the \l {Animated Image} + component, also available in \uicontrol Components > + \uicontrol {Default Components} > \uicontrol Basic. + + \section2 UI Controls + + The \e {Custom Button} wizard template creates a button component + based on the \l {Button} control in the \l {Qt Quick Controls} module. It + is a push-button control that can be pushed or clicked by the user. Buttons + are normally used to perform an action or to answer a question. The + properties and functionality inherited from the Button component enable + you to set text, display an icon, react to mouse clicks, and so on. + + To be able to use the functionality of the Button control, the wizard template + adds the following \e import statements to the \e EntryField.ui.qml file: + + \quotefromfile Loginui1/content/EntryField.ui.qml + \skipto import + \printuntil Controls + + \section2 Component IDs Each component and each instance of a component has an \e ID that uniquely identifies it and enables other components' properties to be bound to it. From 348bad2fdb1c99cef37cdef2c6c02950e39f6499 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 12 Oct 2022 20:54:24 +0300 Subject: [PATCH 11/24] QmlDesigner: Fix assets library drag glitch When clicking an asset and then moving the mouse, drag is still active. Happens on mac and linux only. Change-Id: Ic61a9316013271e8e16a30629416787c863840a3 Reviewed-by: Miikka Heikkinen --- .../components/assetslibrary/assetslibrarywidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 7c111f80c0b..93057e6733a 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -91,6 +91,8 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) m_assetsToDrag.clear(); } } + } else if (event->type() == QMouseEvent::MouseButtonRelease) { + m_assetsToDrag.clear(); } return QObject::eventFilter(obj, event); From 67ecfd2fdc830afed7074c04dd46ae0c8519d55f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 13 Oct 2022 14:00:39 +0300 Subject: [PATCH 12/24] QmlDesigner: Add required import when creating nodes via 3D view Creating nodes via 3D view context menu now adds required import if it is missing. Fixes: QDS-7950 Change-Id: Ibd4faff9d494a232e0fbf0fd5db3690449516bf6 Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Bot --- .../qmldesigner/components/edit3d/edit3dwidget.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index e05c3dd10a7..dfe8d8c1a72 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -36,6 +36,7 @@ #include "viewmanager.h" #include #include +#include #include #include @@ -231,13 +232,20 @@ void Edit3DWidget::updateCreateSubMenu(const QStringList &keys, void Edit3DWidget::onCreateAction() { QAction *action = qobject_cast(sender()); - if (!action) + if (!action || !m_view || !m_view->model()) return; m_view->executeInTransaction(__FUNCTION__, [&] { - int activeScene = m_view->rootModelNode().auxiliaryData("active3dScene@Internal").toInt(); + ItemLibraryEntry entry = m_nameToEntry.value(action->data().toString()); + Import import = Import::createLibraryImport(entry.requiredImport(), + QString::number(entry.majorVersion()) + + QLatin1Char('.') + + QString::number(entry.minorVersion())); + if (!m_view->model()->hasImport(import)) + m_view->model()->changeImports({import}, {}); - auto modelNode = QmlVisualNode::createQml3DNode(m_view, m_nameToEntry.value(action->data().toString()), + int activeScene = m_view->rootModelNode().auxiliaryData("active3dScene@Internal").toInt(); + auto modelNode = QmlVisualNode::createQml3DNode(m_view, entry, activeScene, m_contextMenuPos3d).modelNode(); QTC_ASSERT(modelNode.isValid(), return); m_view->setSelectedModelNode(modelNode); From b4d0db920a11500b3a29f6f0abaaf9a08aa6fa06 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 12 Oct 2022 11:49:50 +0200 Subject: [PATCH 13/24] Doc: Update instructions for writing documentation For new and updated images, use the display resolution 1920x1080. Change-Id: Ie7a83d23eacfa8ba9b78a4de4ee9046e838fa72c Reviewed-by: Alessandro Portale --- .../src/qtcreator-documentation.qdoc | 85 ++++++++++++------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/doc/qtcreatordev/src/qtcreator-documentation.qdoc b/doc/qtcreatordev/src/qtcreator-documentation.qdoc index 66edefce4c6..62c5c3a2c11 100644 --- a/doc/qtcreatordev/src/qtcreator-documentation.qdoc +++ b/doc/qtcreatordev/src/qtcreator-documentation.qdoc @@ -321,22 +321,26 @@ users, but always place example values also in the text. \list - \li Use the screen resolution of 1366x768 (available on the most + \li Use the screen resolution of 1920x1080 (available on the most commonly used screens, as of this writing). - - \li Use the aspect ratio of 16:9. - - \li Open the application in the maximum size on full screen. + \note Use display scaling 100%. \li Use your favorite tool to take the screen shot. \li Include only the part of the screen that you need (you can crop the - image also in the screen capture tool). + image also in the screen capture tool). In \QDS, close all + unnecessary views to avoid clutter. + + \li Do not scale or resize the images in the tool because it causes + reduced visual quality and bigger file size. Also, the CSS we use + online scales down images if needed (their width is larger than 800 + pixels). \li To highlight parts of the screen shot, use the images of numbers - that are stored in \c{doc/images/numbers} in the \QC repository. + that are stored in \c{qtcreator/doc/qtcreator/images/numbers} in + the \QC repository. - \li Before you submit the images to the repository, optimize them to + \li Before you submit PNG images to the repository, optimize them to save space. \endlist @@ -344,9 +348,9 @@ You can use number icons in screenshots to highlight parts of the screenshot (instead of using red arrows or borders, or something similar). You can then - refer to the numbers in text. For and example, see the - \l{https://doc.qt.io/qt/topics-app-development.html}{Development Tools} - topic in the Qt reference documentation. + refer to the numbers in text. For an example, see the + \l{https://doc.qt.io/qtcreator/creator-quick-tour.html}{User Interface} + topic in the \QC Manual. This improves the consistency of the look and feel of Qt documentation, and eliminates the need to describe parts of the UI in the text because @@ -354,8 +358,8 @@ brackets. You can find a set of images that show the numbers from 1 to 10 in the - \c doc/images/numbers directory (or in the \c qtdoc module sources in - \c doc/images/numbers). + \c qtcreator/doc/qtcreator/images/numbers directory (or in the \c qtdoc + module sources in \c doc/images/numbers). To use the numbers, copy-paste the number images on the screenshot to the places that you want to refer to from text. @@ -380,6 +384,13 @@ recolors icons in \c qtcreator/doc/qtcreator/images/icons. Use the \c -docspath option to specify the path to another icon source directory. + For example, if you saved the new icons in \c {C:\iconconversions}, switch to + the \c {qtcreator\src\tools\icons} folder and enter: + + \badcode + recolordocsicons.py -docspath C:\iconconversions + \endcode + To run the script, you will need to install the following tools and add them to the PATH: @@ -389,20 +400,26 @@ \li optipng \endlist + \section2 Saving Images + + Save images in PNG or WebP format in the \QC project folder in the + \c doc/qtcreator/images or \c doc/qtdesignstudio/images folder. Binary + images can easily add megabytes to the Git + history. To keep the history as small as possible, the Git post-commit hooks + remind you to try to keep image file size below 50 kilobytes. To achieve this + goal, crop images so that only relevant information is visible in them. + + If your screenshot contains lots of colorful content or a photo, for example, + consider saving it in WebP format for a smaller image file size. + \section2 Optimizing Images - Save images in the PNG format in the \QC project folder in the - \c {doc/images} folder. Binary images can easily add megabytes to the Git - history. To keep the history as small as possible, the Git post-commit hooks - remind you to try to keep image size below 50 kilobytes. To achieve this - goal, crop images so that only relevant information is visible in them. - Before committing images, optimize them by using an image optimization tool. - - Optimization should not visibly reduce image quality. If it does, do not do - it. + Before committing PNG images, optimize them by using an image optimization + tool. Optimization should not visibly reduce image quality. If it does, try + saving the image as WebP instead. You can use a web service, such as \l{https://tinypng.com}, or an image - optimization tool to shrink the images. For example, you can use the Radical + optimization tool to shrink PNG images. For example, you can use the Radical Image Optimization Tool (RIOT) or OptiPNG on Windows, ImageOptim on \macos, or some other tool available on Linux. @@ -447,6 +464,16 @@ optipng -o 7 -strip all doc/images/ \endcode + \section2 Creating GIF Videos + + Sometimes it is easier to explain how something works by recording + a short GIF video. You can use any tool you like, for example + \l {https://www.screentogif.com/}{ScreenToGif}. GIF videos are typically + bigger than screenshots, so try to make them as short and to the point as + you can. + + Use the \c {\image} command to add GIF files to the documentation. + \section2 Linking to Youtube Videos You can use the \c {\youtube} macro to link to a video on Youtube. The HTML @@ -499,11 +526,7 @@ \section2 Setting Up Documentation Builds - For more information about setting up the build environment with a - self-built Qt if you do not want to build the whole Qt, see - \l{https://wiki.qt.io/Building_Qt_Documentation}{Building Qt Documentation} - on the Qt wiki. - + You can use an installed Qt version to build the documentation. The content and formatting of documentation are separated in QDoc. The documentation configuration, style sheets, and templates have changed over time, so they differ between Qt and \QC versions. @@ -554,7 +577,7 @@ For example (all on one line): \badcode C:\dev\qtc-doc-build>cmake -DWITH_DOCS=ON - "-DCMAKE_PREFIX_PATH=C:\Qt\5.15.1\msvc2019_64" + "-DCMAKE_PREFIX_PATH=C:\Qt\6.4.0\msvc2019_64" C:\dev\qtc-super\qtcreator \endcode \li To also build Extending \QC Manual, add the following option: @@ -566,7 +589,7 @@ \badcode C:\dev\qtc-doc-build>cmake -DWITH_DOCS=ON -DBUILD_DEVELOPER_DOCS=ON "-DCMAKE_MODULE_PATH=C:\dev\tqtc-plugin-qtquickdesigner\studiodata\branding" - "-DCMAKE_PREFIX_PATH=C:\Qt\5.15.1\msvc2019_64" + "-DCMAKE_PREFIX_PATH=C:\Qt\6.4.0\msvc2019_64" C:\dev\qtc-super\qtcreator \endcode \li To build the docs using the online style, use the following option @@ -578,7 +601,7 @@ C:\dev\qtc-doc-build>cmake -DWITH_ONLINE_DOCS=ON -DBUILD_DEVELOPER_DOCS=ON "-DCMAKE_MODULE_PATH=C:\dev\tqtc-plugin-qtquickdesigner\studiodata\branding" - "-DCMAKE_PREFIX_PATH=C:\Qt\5.15.1\msvc2019_64" + "-DCMAKE_PREFIX_PATH=C:\Qt\6.4.0\msvc2019_64" C:\dev\qtc-super\qtcreator \endcode \note If you already ran CMake \c {-DWITH_DOCS=ON} in a folder and From b2dbc0965c5a5a49c6770674458273f26e453137 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 7 Oct 2022 15:44:06 +0200 Subject: [PATCH 14/24] Editor: Fix double click in editor behind content Fixes: QTCREATORBUG-28083 Change-Id: Ie198c2f1c9911ec85ee555ff1058d2528f9e6b7d Reviewed-by: Christian Stenger --- src/plugins/texteditor/texteditor.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 2b55229c6ce..1cda9db17cd 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -5514,8 +5514,8 @@ void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e) } } - QTextCursor oldCursor = multiTextCursor().mainCursor(); - const int oldPosition = oldCursor.position(); + QTextCursor eventCursor = cursorForPosition(QPoint(e->pos().x(), e->pos().y())); + const int eventDocumentPosition = eventCursor.position(); QPlainTextEdit::mouseDoubleClickEvent(e); @@ -5523,19 +5523,19 @@ void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e) // event is triggered on a position that is inbetween two whitespaces this event selects the // previous word or nothing if the whitespaces are at the block start. Replace this behavior // with selecting the whitespaces starting from the previous word end to the next word. - const QChar character = characterAt(oldPosition); - const QChar prevCharacter = characterAt(oldPosition - 1); + const QChar character = characterAt(eventDocumentPosition); + const QChar prevCharacter = characterAt(eventDocumentPosition - 1); if (character.isSpace() && prevCharacter.isSpace()) { if (prevCharacter != QChar::ParagraphSeparator) { - oldCursor.movePosition(QTextCursor::PreviousWord); - oldCursor.movePosition(QTextCursor::EndOfWord); + eventCursor.movePosition(QTextCursor::PreviousWord); + eventCursor.movePosition(QTextCursor::EndOfWord); } else if (character == QChar::ParagraphSeparator) { return; // no special handling for empty lines } - oldCursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + eventCursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); MultiTextCursor cursor = multiTextCursor(); - cursor.replaceMainCursor(oldCursor); + cursor.replaceMainCursor(eventCursor); setMultiTextCursor(cursor); } } From 033ec559b3e73459fb0c2a0d48d5a75dba2ce6d4 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Thu, 13 Oct 2022 10:40:05 +0300 Subject: [PATCH 15/24] Doc: Improve wording for States and Connections pages These topic sets cover more than adding so I change "Adding" to "Working with". Task-number: QDS-7995 Change-Id: I240bce10c6cbfc04a686b719bd74cbd353d3de11 Reviewed-by: Leena Miettinen --- doc/qtdesignstudio/examples/doc/StateTransitions.qdoc | 4 ++-- doc/qtdesignstudio/examples/doc/loginui3.qdoc | 4 ++-- doc/qtdesignstudio/examples/doc/loginui4.qdoc | 2 +- doc/qtdesignstudio/examples/doc/sidemenu.qdoc | 2 +- doc/qtdesignstudio/examples/doc/washingMachineUI.qdoc | 2 +- doc/qtdesignstudio/src/components/qtquick-buttons.qdoc | 2 +- .../src/components/qtquick-component-instances.qdoc | 2 +- doc/qtdesignstudio/src/components/qtquick-components.qdoc | 2 +- .../src/overviews/qtquick-creating-ui-logic.qdoc | 4 ++-- doc/qtdesignstudio/src/qtdesignstudio-app-flows.qdoc | 4 ++-- doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc | 2 +- doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc | 4 ++-- doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc | 4 ++-- doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc | 4 ++-- doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc | 2 +- doc/qtdesignstudio/src/views/qtquick-designer.qdoc | 4 ++-- doc/qtdesignstudio/src/views/qtquick-navigator.qdoc | 4 ++-- doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc | 2 +- doc/qtdesignstudio/src/views/qtquick-properties.qdoc | 2 +- doc/qtdesignstudio/src/views/qtquick-states-view.qdoc | 4 ++-- doc/qtdesignstudio/src/views/qtquick-states.qdoc | 2 +- doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc | 2 +- 22 files changed, 32 insertions(+), 32 deletions(-) diff --git a/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc b/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc index 8c3ad88606f..619f51812d8 100644 --- a/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc +++ b/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc @@ -26,7 +26,7 @@ /*! \page state-transition-animations.html \ingroup gstutorials - \sa States, {Transitions}, {Adding States} + \sa States, {Transitions}, {Working with States} \title Animated State Transitions \brief Illustrates how to create animated state transitions. @@ -34,7 +34,7 @@ \image animated-state-transitions.jpg The \e{Animated State Transitions} tutorial illustrates how you can animate - the transition between \l{Adding States}{states}. + the transition between \l{Working with States}{states}. The starting point of this tutorial is the Car Demo project, you can download it from diff --git a/doc/qtdesignstudio/examples/doc/loginui3.qdoc b/doc/qtdesignstudio/examples/doc/loginui3.qdoc index d4799d199d4..4cdca5f44b3 100644 --- a/doc/qtdesignstudio/examples/doc/loginui3.qdoc +++ b/doc/qtdesignstudio/examples/doc/loginui3.qdoc @@ -99,7 +99,7 @@ \section1 Using States to Simulate Page Changes - You will now add \l{Adding States}{states} to the UI to show and hide UI + You will now add \l{Working with States}{states} to the UI to show and hide UI components in the \uicontrol {2D} view, depending on the current page: \list 1 @@ -177,7 +177,7 @@ \section1 Learn More \section2 States - The \l{Adding States}{state} of a particular visual component is the set of + The \l{Working with States}{state} of a particular visual component is the set of information which describes how and where the individual parts of the visual component are displayed within it, and all the data associated with that state. Most visual components in a UI will have a limited number of states, diff --git a/doc/qtdesignstudio/examples/doc/loginui4.qdoc b/doc/qtdesignstudio/examples/doc/loginui4.qdoc index 35d8c1070e6..a82d9f502cf 100644 --- a/doc/qtdesignstudio/examples/doc/loginui4.qdoc +++ b/doc/qtdesignstudio/examples/doc/loginui4.qdoc @@ -262,7 +262,7 @@ \section1 Binding Animation to States - You will now bring back the \l{Adding States}{states} in the + You will now bring back the \l{Working with States}{states} in the \uicontrol States view and bind them to the animation settings in \uicontrol Timeline: diff --git a/doc/qtdesignstudio/examples/doc/sidemenu.qdoc b/doc/qtdesignstudio/examples/doc/sidemenu.qdoc index 08c4805deb1..c9168844d05 100644 --- a/doc/qtdesignstudio/examples/doc/sidemenu.qdoc +++ b/doc/qtdesignstudio/examples/doc/sidemenu.qdoc @@ -53,7 +53,7 @@ The button can have the following states: checked, hover, pressed, and normal. We construct the button using different images for the button - background, frame, and front. We then add \l{Adding States}{states} in + background, frame, and front. We then add \l{Working with States}{states} in the \l States view for each of the button states. In each state, we turn the visibility of the appropriate images on or off in the button properties, to change the appearance of the button. diff --git a/doc/qtdesignstudio/examples/doc/washingMachineUI.qdoc b/doc/qtdesignstudio/examples/doc/washingMachineUI.qdoc index c08bc016b1a..6f96e370764 100644 --- a/doc/qtdesignstudio/examples/doc/washingMachineUI.qdoc +++ b/doc/qtdesignstudio/examples/doc/washingMachineUI.qdoc @@ -188,7 +188,7 @@ in the top-left corner of the root component. Then, we open the \uicontrol States view to create the \e start, - \e settings, \e presets, and \e running \l{Adding States}{states} for + \e settings, \e presets, and \e running \l{Working with States}{states} for displaying a particular screen by selecting \uicontrol {Create New State}. \image washingmachineui-states.png "States view" diff --git a/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc b/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc index 54dacf9e62a..c5ade1f935f 100644 --- a/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc @@ -139,7 +139,7 @@ PNG file, as a border and a background. Use two border images and suitable graphics to change the appearance of - a button when it is clicked. You can use use \l{Adding States}{states} + a button when it is clicked. You can use use \l{Working with States}{states} to determine which image is visible depending on whether the mouse button is pressed down. You could add more images and states to change the appearance of the button depending on other mouse events, diff --git a/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc b/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc index d3a04f89be4..195874c3b66 100644 --- a/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc @@ -65,7 +65,7 @@ \image qmldesigner-bindings.png "Connections view Bindings tab" \li Add states to apply sets of changes to the property values of one or several component instances in the \uicontrol States view. - For more information, see \l{Adding States}. + For more information, see \l{Working with States}. \li Animate the properties of component instances in the \uicontrol Timeline view. For more information, see \l{Creating Timeline Animations}. diff --git a/doc/qtdesignstudio/src/components/qtquick-components.qdoc b/doc/qtdesignstudio/src/components/qtquick-components.qdoc index 7ea137592ac..7a8c01faa3c 100644 --- a/doc/qtdesignstudio/src/components/qtquick-components.qdoc +++ b/doc/qtdesignstudio/src/components/qtquick-components.qdoc @@ -85,7 +85,7 @@ your UI. \li Use as few components as necessary. To minimize the number of components, use \l{Adding Property Aliases}{alias properties} and - \l{Adding States}{states} to create the differences in your + \l{Working with States}{states} to create the differences in your component instances. We recommend reusing components instead of duplicating them, so the components do not need to be processed as completely new component types. This reduces loading diff --git a/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc index 561eb8c62c3..8774a8ea674 100644 --- a/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc +++ b/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc @@ -54,7 +54,7 @@ exported as a public property of the relevant component. For example, a speedometer should have a property for speed to which the UI is bound. - You can declare various \l{Adding States}{UI states} that describe how + You can declare various \l{Working with States}{UI states} that describe how property values change from a base state. States can be a useful way of organizing your UI logic. You can associate transitions with components to define how their properties will animate when they change due to a @@ -122,7 +122,7 @@ \li \l{Adding Property Aliases} \row \li Referencing a state from within a specific component - \li \l{Adding States} + \li \l{Working with States} \row \li Switching to a state when a particular property changes \li \l{Applying States} diff --git a/doc/qtdesignstudio/src/qtdesignstudio-app-flows.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-app-flows.qdoc index 4b6cfe13777..f57b5870671 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-app-flows.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-app-flows.qdoc @@ -71,7 +71,7 @@ \uicontrol {Flow Decision} components from \uicontrol Components > \uicontrol {Flow View}, as described in \l{Simulating Conditions}. - \li Use \l{Adding States}{states} in flows to modify the appearance + \li Use \l{Working with States}{states} in flows to modify the appearance of components on screens in response to user interaction, as described in \l{Applying States in Flows}. \li Use \uicontrol {Flow Wildcard} components from @@ -642,7 +642,7 @@ \title Applying States in Flows - You can use \l{Adding States}{states} in flows to modify the appearance + You can use \l{Working with States}{states} in flows to modify the appearance of \l{glossary-component}{components} in flow items in response to user interaction, for example. For this purpose, you use the \uicontrol {Flow Item} components available in diff --git a/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc b/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc index 330b2ee7be9..8b378e90955 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc +++ b/doc/qtdesignstudio/src/qtdesignstudio-components.qdocinc @@ -50,7 +50,7 @@ \endtable You can edit the properties of the controls in all the preset - \l{Adding States}{states} to apply your own style to them. + \l{Working with States}{states} to apply your own style to them. \note For buttons and check boxes, you can disable the misbehaving hover effects by selecting \l Properties > \uicontrol Control, and then disabling diff --git a/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc index 15026d2c519..cd9f15bb46e 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc @@ -143,7 +143,7 @@ \list \li \l{Connections} - \li \l{Adding Connections} + \li \l{Working with Connections} \endlist \section1 Device @@ -271,7 +271,7 @@ \list \li \l{States} - \li \l{Adding States} + \li \l{Working with States} \endlist \section1 Transition diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index bcccd0bf399..11ff34f21a4 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -140,13 +140,13 @@ \endlist \li \l{Dynamic Behaviors} \list - \li \l{Adding Connections} + \li \l{Working with Connections} \list \li\l{Connecting Components to Signals} \li\l{Adding Bindings Between Properties} \li\l{Specifying Custom Properties} \endlist - \li \l{Adding States} + \li \l{Working with States} \endlist \li \l{Validating with Target Hardware} \list diff --git a/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc b/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc index 274c205c60b..93fcf16bc34 100644 --- a/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc @@ -35,7 +35,7 @@ when the values of other components or the UI state change. \list - \li \l {Adding Connections} + \li \l {Working with Connections} You can create connections between the UI components and the application to enable them to communicate with each other. For @@ -47,7 +47,7 @@ binding their properties together. This way, when the value of a property changes in a parent component, it can be automatically changed in all the child components, for example. - \li \l {Adding States} + \li \l {Working with States} You can declare various UI states that describe how component properties change from a base state. Therefore, states can be diff --git a/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc index 9c8360f5659..ce30db368f9 100644 --- a/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc @@ -28,7 +28,7 @@ \previouspage qtquick-adding-dynamics.html \nextpage quick-signals.html - \title Adding Connections + \title Working with Connections \list \li \l{Connecting Components to Signals} diff --git a/doc/qtdesignstudio/src/views/qtquick-designer.qdoc b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc index 3e05138e5ee..d1e846a3643 100644 --- a/doc/qtdesignstudio/src/views/qtquick-designer.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc @@ -97,14 +97,14 @@ \li \l{Connections} \li Enables you to add functionality to the UI by creating connections between components, signals, and component properties. - \li \l{Adding Connections} + \li \l{Working with Connections} \row \li \l States \li Displays the different states that can be applied to a component. Typically, states describe UI configurations, such as the visibility and behavior of components and the available user actions. - \li \l{Adding States} + \li \l{Working with States} \row \li \l{Transitions} \li Enables you to make movement between states smooth by animating diff --git a/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc index c2e40b729a0..ce3cb0f27c1 100644 --- a/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc @@ -146,7 +146,7 @@ the \l {3D} view nor access their properties in \uicontrol Properties. - If you attempt to \l{Adding States}{remove a state} that changes the + If you attempt to \l{Working with States}{remove a state} that changes the properties of a locked component, you are prompted to confirm the removal. If you have \l{Editing Animation Curves}{added easing curves} to keyframe @@ -234,7 +234,7 @@ \image qmldesigner-export-item.png You can then use the property alias in other components to - \l{Adding Connections}{create connections} to this component. + \l{Working with Connections}{create connections} to this component. \section1 Moving Within Components diff --git a/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc index 8eb86df3216..7f5f694063d 100644 --- a/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc @@ -108,7 +108,7 @@ The default values of properties are displayed in white color, while the values that you specify explicitly are highlighted with blue color. In - addition, property changes in \l{Adding States}{states} are highlighted + addition, property changes in \l{Working with States}{states} are highlighted with blue. This allows you to easily see which values are set in the component diff --git a/doc/qtdesignstudio/src/views/qtquick-properties.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc index a80201ea3ad..6b10563ccad 100644 --- a/doc/qtdesignstudio/src/views/qtquick-properties.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc @@ -175,7 +175,7 @@ If the \uicontrol Clip check box is selected, the component and its children are clipped to the bounding rectangle of the component. - in the \uicontrol State field, select the \l{Adding States}{state} to + in the \uicontrol State field, select the \l{Working with States}{state} to change the value of a property in that state. \section1 Picking Colors diff --git a/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc index d5894641dbb..fe83102f999 100644 --- a/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc @@ -30,8 +30,8 @@ \title States - The \uicontrol States view displays the different \l{Adding States}{states} - of a UI. + The \uicontrol States view displays the different + \l{Working with States}{states} of a UI. \image qmldesigner-transitions.png "States view" diff --git a/doc/qtdesignstudio/src/views/qtquick-states.qdoc b/doc/qtdesignstudio/src/views/qtquick-states.qdoc index 0ff4f27105e..b92146a7927 100644 --- a/doc/qtdesignstudio/src/views/qtquick-states.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-states.qdoc @@ -33,7 +33,7 @@ \nextpage exporting-3d-assets.html \endif - \title Adding States + \title Working with States You can define states for components and component instances in the \l States view by selecting \inlineimage icons/plus.png diff --git a/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc index 72e0217b2b6..55b5c58cfdd 100644 --- a/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc @@ -34,7 +34,7 @@ \uicontrol {Transitions} to animate the changes between states. - First, you need to \l{Adding States}{add states} in the \l States view + First, you need to \l{Working with States}{add states} in the \l States view and \l{Specifying Component Properties}{edit some properties} that can be animated, such as colors or numbers, in the \l Properties view. For example, you can animate the changes in the position of a component. From 519b6fefe10629c1a09df03b59647c0f1085a806 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 13 Oct 2022 11:56:12 +0200 Subject: [PATCH 16/24] Link with Qt: Prepare for sdktool to move to a different location When linking we should now consider the new sdktool location within the Qt installation first. The new location of QtCreator.ini will be / Tools/sdktool/QtProject/QtCreator.ini on macOS, and /Tools/sdktool/ share/qtcreator/QtProject/QtCreator.ini on Windows/Linux. When resolving an existing install settings path to the old location within the Qt Creator installation (Qt Creator.app/Contents/Resources or Tools/QtCreator/share/qtcreator), the QtCreator.ini at that location will itself redirect to the new sdktool location. So, try to follow that as well, to keep existing setups working. Task-number: QTBUG-28101 Change-Id: Idbb09ad6961f6fd4a4112830959a615d8186a132 Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- src/app/main.cpp | 37 +++++++++++++++++-------- src/plugins/qtsupport/qtoptionspage.cpp | 4 +-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index ee7ddbd2035..d56cc676020 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -244,22 +244,35 @@ static void setupInstallSettings(QString &installSettingspath) QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), QLatin1String(Core::Constants::IDE_CASED_ID))); installSettingspath.clear(); } - // Check if the default install settings contain a setting for the actual install settings. - // This can be an absolute path, or a path relative to applicationDirPath(). - // The result is interpreted like -settingspath, but for SystemScope static const char kInstallSettingsKey[] = "Settings/InstallSettings"; QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, installSettingspath.isEmpty() ? resourcePath() : installSettingspath); - QSettings installSettings(QSettings::IniFormat, QSettings::UserScope, - QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), - QLatin1String(Core::Constants::IDE_CASED_ID)); - if (installSettings.contains(kInstallSettingsKey)) { - QString installSettingsPath = installSettings.value(kInstallSettingsKey).toString(); - if (QDir::isRelativePath(installSettingsPath)) - installSettingsPath = applicationDirPath() + '/' + installSettingsPath; - QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, installSettingsPath); - } + // Check if the default install settings contain a setting for the actual install settings. + // This can be an absolute path, or a path relative to applicationDirPath(). + // The result is interpreted like -settingspath, but for SystemScope. + // + // Through the sdktool split that is upcoming, the new install settings might redirect + // yet a second time. So try this a few times. + // (Only the first time with QSettings::UserScope, to allow setting the install settings path + // in the user settings.) + QSettings::Scope scope = QSettings::UserScope; + int count = 0; + bool containsInstallSettingsKey = false; + do { + QSettings installSettings(QSettings::IniFormat, scope, + QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), + QLatin1String(Core::Constants::IDE_CASED_ID)); + containsInstallSettingsKey = installSettings.contains(kInstallSettingsKey); + if (containsInstallSettingsKey) { + QString newInstallSettingsPath = installSettings.value(kInstallSettingsKey).toString(); + if (QDir::isRelativePath(newInstallSettingsPath)) + newInstallSettingsPath = applicationDirPath() + '/' + newInstallSettingsPath; + QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, newInstallSettingsPath); + } + scope = QSettings::SystemScope; // UserScope only the first time we check + ++count; + } while (containsInstallSettingsKey && count < 3); } static Utils::QtcSettings *createUserSettings() diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index c0049058abd..9df0dd5068f 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -897,9 +897,9 @@ void QtOptionsPageWidget::apply() &QtOptionsPageWidget::updateQtVersions); } -// TODO whenever we move the output of sdktool to a different location in the installer, -// this needs to be adapted accordingly const QStringList kSubdirsToCheck = {"", + "Tools/sdktool", // macOS + "Tools/sdktool/share/qtcreator", // Windows/Linux "Qt Creator.app/Contents/Resources", "Contents/Resources", "Tools/QtCreator/share/qtcreator", From 7a967d385ea903ca8f707dd5d47851085098539c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 13 Oct 2022 16:25:23 +0300 Subject: [PATCH 17/24] QmlDesigner: Add unimportFinished signal to BundleImporter Change-Id: I6d7ab5716f1bf6fe48f454d0c95c29ebd5d181de Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Bot --- .../materialbrowser/bundleimporter.cpp | 51 ++++++++++++++----- .../materialbrowser/bundleimporter.h | 3 +- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp index 67559e08299..77c2c5ed302 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp @@ -97,9 +97,10 @@ QString BundleImporter::importComponent(const QString &qmlFile, FilePath qmlSourceFile = bundleImportPath.resolvePath(FilePath::fromString(qmlFile)); const bool qmlFileExists = qmlSourceFile.exists(); const QString qmlType = qmlSourceFile.baseName(); - m_pendingTypes.append(QStringLiteral("%1.%2.%3") - .arg(QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1), - m_bundleId, qmlType)); + const QString fullTypeName = QStringLiteral("%1.%2.%3") + .arg(QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1), m_bundleId, qmlType); + if (m_pendingTypes.contains(fullTypeName) && !m_pendingTypes[fullTypeName]) + return QStringLiteral("Unable to import while unimporting the same type: '%1'").arg(fullTypeName); if (!qmldirContent.contains(qmlFile)) { qmldirContent.append(qmlType); qmldirContent.append(" 1.0 "); @@ -162,6 +163,7 @@ QString BundleImporter::importComponent(const QString &qmlFile, m_importAddPending = true; } } + m_pendingTypes.insert(fullTypeName, true); m_importTimerCount = 0; m_importTimer.start(); @@ -175,8 +177,16 @@ void BundleImporter::handleImportTimer() m_fullReset = false; m_importAddPending = false; m_importTimerCount = 0; - m_pendingTypes.clear(); - emit importFinished({}); + + // Emit dummy finished signals for all pending types + const QStringList pendingTypes = m_pendingTypes.keys(); + for (const QString &pendingType : pendingTypes) { + m_pendingTypes.remove(pendingType); + if (m_pendingTypes[pendingType]) + emit importFinished({}); + else + emit unimportFinished({}); + } }; auto doc = QmlDesignerPlugin::instance()->currentDesignDocument(); @@ -210,12 +220,17 @@ void BundleImporter::handleImportTimer() } // Detect when the code model has the new material(s) fully available - const QStringList pendingTypes = m_pendingTypes; + const QStringList pendingTypes = m_pendingTypes.keys(); for (const QString &pendingType : pendingTypes) { NodeMetaInfo metaInfo = model->metaInfo(pendingType.toUtf8()); - if (metaInfo.isValid() && !metaInfo.superClasses().isEmpty()) { - m_pendingTypes.removeAll(pendingType); - emit importFinished(metaInfo); + const bool isImport = m_pendingTypes[pendingType]; + const bool typeComplete = metaInfo.isValid() && !metaInfo.superClasses().isEmpty(); + if (isImport == typeComplete) { + m_pendingTypes.remove(pendingType); + if (isImport) + emit importFinished(metaInfo); + else + emit unimportFinished(metaInfo); } } @@ -257,14 +272,14 @@ QString BundleImporter::unimportComponent(const QString &qmlFile) { FilePath bundleImportPath = resolveBundleImportPath(); if (bundleImportPath.isEmpty()) - return "Failed to resolve bundle import folder"; + return QStringLiteral("Failed to resolve bundle import folder for: '%1'").arg(qmlFile); if (!bundleImportPath.exists()) - return {}; + return QStringLiteral("Unable to find bundle path: '%1'").arg(bundleImportPath.toString()); FilePath qmlFilePath = bundleImportPath.resolvePath(qmlFile); if (!qmlFilePath.exists()) - return {}; + return QStringLiteral("Unable to find specified file: '%1'").arg(qmlFilePath.toString()); QStringList removedFiles; removedFiles.append(qmlFile); @@ -272,9 +287,15 @@ QString BundleImporter::unimportComponent(const QString &qmlFile) FilePath qmldirPath = bundleImportPath.resolvePath(QStringLiteral("qmldir")); QByteArray qmldirContent = qmldirPath.fileContents(); QByteArray newContent; + + QString qmlType = qmlFilePath.baseName(); + const QString fullTypeName = QStringLiteral("%1.%2.%3") + .arg(QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1), m_bundleId, qmlType); + if (m_pendingTypes.contains(fullTypeName) && m_pendingTypes[fullTypeName]) + return QStringLiteral("Unable to unimport while importing the same type: '%1'").arg(fullTypeName); + if (!qmldirContent.isEmpty()) { - QByteArray qmlType = qmlFilePath.baseName().toUtf8(); - int typeIndex = qmldirContent.indexOf(qmlType); + int typeIndex = qmldirContent.indexOf(qmlType.toUtf8()); if (typeIndex != -1) { int newLineIndex = qmldirContent.indexOf('\n', typeIndex); newContent = qmldirContent.left(typeIndex); @@ -287,6 +308,8 @@ QString BundleImporter::unimportComponent(const QString &qmlFile) } } + m_pendingTypes.insert(fullTypeName, false); + QVariantHash assetRefMap = loadAssetRefMap(bundleImportPath); bool writeAssetRefs = false; const auto keys = assetRefMap.keys(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h index b22d0edd591..599d4d8e50b 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h +++ b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h @@ -57,6 +57,7 @@ signals: // asynchronous part of the import. In this case all remaining pending imports have been // terminated, and will not receive separate importFinished notifications. void importFinished(const QmlDesigner::NodeMetaInfo &metaInfo); + void unimportFinished(const QmlDesigner::NodeMetaInfo &metaInfo); private: void handleImportTimer(); @@ -72,7 +73,7 @@ private: int m_importTimerCount = 0; bool m_importAddPending = false; bool m_fullReset = false; - QStringList m_pendingTypes; + QHash m_pendingTypes; // }; } // namespace QmlDesigner::Internal From b983b8aa52d9f919f3ed3ee793a30835706a45a8 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 12 Oct 2022 20:46:17 +0300 Subject: [PATCH 18/24] QmlDesigner: Implement unimporting bundle materials Fixes: QDS-7904 Change-Id: I08642c25a2844547d0104a7b3d9fda6afe47cd38 Reviewed-by: Reviewed-by: Miikka Heikkinen --- .../BundleMaterialItem.qml | 46 +++++++++- .../MaterialBrowser.qml | 38 ++++++--- .../UnimportBundleMaterialDialog.qml | 85 +++++++++++++++++++ .../materialbrowser/bundleimporter.h | 2 +- .../materialbrowser/bundlematerial.cpp | 16 ++++ .../materialbrowser/bundlematerial.h | 6 ++ .../bundlematerialcategory.cpp | 10 +++ .../materialbrowser/bundlematerialcategory.h | 1 + .../materialbrowserbundlemodel.cpp | 50 ++++++++++- .../materialbrowserbundlemodel.h | 13 ++- .../materialbrowser/materialbrowserview.cpp | 39 ++++++++- .../materialbrowser/materialbrowserview.h | 2 + 12 files changed, 287 insertions(+), 21 deletions(-) create mode 100644 share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml index 4b8b45be564..59541f47d39 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/BundleMaterialItem.qml @@ -27,6 +27,8 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuickDesignerTheme 1.0 import HelperWidgets 2.0 +import QtQuick.Controls + import StudioTheme 1.0 as StudioTheme Item { @@ -43,7 +45,7 @@ Item { acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: (mouse) => { - if (mouse.button === Qt.LeftButton) + if (mouse.button === Qt.LeftButton && !materialBrowserBundleModel.importerRunning) rootView.startDragBundleMaterial(modelData, mapToGlobal(mouse.x, mouse.y)) else if (mouse.button === Qt.RightButton) root.showContextMenu() @@ -64,6 +66,48 @@ Item { anchors.horizontalCenter: parent.horizontalCenter source: modelData.bundleMaterialIcon cache: false + + Rectangle { // circular indicator for imported bundle materials + width: 10 + height: 10 + radius: 5 + anchors.right: img.right + anchors.top: img.top + anchors.margins: 5 + color: "#00ff00" + border.color: "#555555" + border.width: 1 + visible: modelData.bundleMaterialImported + + ToolTip { + visible: indicatorMouseArea.containsMouse + text: qsTr("Material is imported to project") + delay: 1000 + } + + MouseArea { + id: indicatorMouseArea + anchors.fill: parent + hoverEnabled: true + } + } + + IconButton { + icon: StudioTheme.Constants.plus + tooltip: qsTr("Add an instance to project") + buttonSize: 22 + property color c: StudioTheme.Values.themeIconColor + normalColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .2) + hoverColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .3) + pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4) + anchors.right: img.right + anchors.bottom: img.bottom + enabled: !materialBrowserBundleModel.importerRunning + + onClicked: { + materialBrowserBundleModel.addToProject(modelData) + } + } } TextInput { diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 2fecc7582ad..19458a93f55 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -46,8 +46,8 @@ Item { // Called also from C++ to close context menu on focus out function closeContextMenu() { - cxtMenu.close() - cxtMenuBundle.close() + ctxMenu.close() + ctxMenuBundle.close() } // Called from C++ to refresh a preview material after it changes @@ -79,7 +79,7 @@ Item { if (!materialBrowserModel.hasMaterialRoot && (!materialBrowserBundleModel.matBundleExists || mouse.y < userMatsSecBottom)) { root.currentMaterial = null - cxtMenu.popup() + ctxMenu.popup() } } } @@ -97,8 +97,12 @@ Item { } } + UnimportBundleMaterialDialog { + id: unimportBundleMaterialDialog + } + StudioControls.Menu { - id: cxtMenu + id: ctxMenu closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside @@ -205,7 +209,7 @@ Item { } StudioControls.Menu { - id: cxtMenuBundle + id: ctxMenuBundle closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside @@ -224,9 +228,22 @@ Item { StudioControls.MenuSeparator {} StudioControls.MenuItem { - text: qsTr("Add to project") + enabled: !materialBrowserBundleModel.importerRunning + text: qsTr("Add an instance to project") - onTriggered: materialBrowserBundleModel.addMaterial(root.currentBundleMaterial) + onTriggered: { + materialBrowserBundleModel.addToProject(root.currentBundleMaterial) + } + } + + StudioControls.MenuItem { + enabled: !materialBrowserBundleModel.importerRunning && root.currentBundleMaterial.bundleMaterialImported + text: qsTr("Remove from project") + + onTriggered: { + unimportBundleMaterialDialog.targetBundleMaterial = root.currentBundleMaterial + unimportBundleMaterialDialog.open() + } } } @@ -301,13 +318,14 @@ Item { height: root.height - searchBox.height clip: true visible: materialBrowserModel.hasQuick3DImport && !materialBrowserModel.hasMaterialRoot + interactive: !ctxMenu.opened && !ctxMenuBundle.opened Column { Section { id: userMaterialsSection width: root.width - caption: qsTr("User materials") + caption: qsTr("Materials") hideHeader: !materialBrowserBundleModel.matBundleExists Grid { @@ -329,7 +347,7 @@ Item { onShowContextMenu: { root.currentMaterial = model - cxtMenu.popup() + ctxMenu.popup() } } } @@ -392,7 +410,7 @@ Item { onShowContextMenu: { root.currentBundleMaterial = modelData - cxtMenuBundle.popup() + ctxMenuBundle.popup() } } } diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml new file mode 100644 index 00000000000..82708467a8a --- /dev/null +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/UnimportBundleMaterialDialog.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuickDesignerTheme +import HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +Dialog { + id: root + + title: qsTr("Bundle material might be in use") + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + implicitWidth: 300 + modal: true + + property var targetBundleMaterial + + contentItem: Column { + spacing: 20 + width: parent.width + + Text { + id: folderNotEmpty + + text: qsTr("If the material you are removing is in use, it might cause the project to malfunction.\n\nAre you sure you want to remove the material?") + color: StudioTheme.Values.themeTextColor + wrapMode: Text.WordWrap + anchors.right: parent.right + anchors.left: parent.left + leftPadding: 10 + rightPadding: 10 + + Keys.onEnterPressed: btnRemove.onClicked() + Keys.onReturnPressed: btnRemove.onClicked() + } + + Row { + anchors.right: parent.right + Button { + id: btnRemove + + text: qsTr("Remove") + + onClicked: { + materialBrowserBundleModel.removeFromProject(root.targetBundleMaterial) + root.accept() + } + } + + Button { + text: qsTr("Cancel") + onClicked: root.reject() + } + } + } + + onOpened: folderNotEmpty.forceActiveFocus() +} diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h index 599d4d8e50b..64344915ce1 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h +++ b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.h @@ -51,6 +51,7 @@ public: QString importComponent(const QString &qmlFile, const QStringList &files); QString unimportComponent(const QString &qmlFile); + Utils::FilePath resolveBundleImportPath(); signals: // The metaInfo parameter will be invalid if an error was encountered during @@ -63,7 +64,6 @@ private: void handleImportTimer(); QVariantHash loadAssetRefMap(const Utils::FilePath &bundlePath); void writeAssetRefMap(const Utils::FilePath &bundlePath, const QVariantHash &assetRefMap); - Utils::FilePath resolveBundleImportPath(); Utils::FilePath m_bundleDir; QString m_bundleId; diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp index b5bc19e785c..6cee76475ac 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp @@ -70,4 +70,20 @@ bool BundleMaterial::visible() const return m_visible; } +bool BundleMaterial::setImported(bool imported) +{ + if (m_imported != imported) { + m_imported = imported; + emit materialImportedChanged(); + return true; + } + + return false; +} + +bool BundleMaterial::imported() const +{ + return m_imported; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h index ae74a13d75c..64d79aa65ee 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h @@ -40,6 +40,7 @@ class BundleMaterial : public QObject Q_PROPERTY(QString bundleMaterialName MEMBER m_name CONSTANT) Q_PROPERTY(QUrl bundleMaterialIcon MEMBER m_icon CONSTANT) Q_PROPERTY(bool bundleMaterialVisible MEMBER m_visible NOTIFY materialVisibleChanged) + Q_PROPERTY(bool bundleMaterialImported READ imported WRITE setImported NOTIFY materialImportedChanged) public: BundleMaterial(QObject *parent, @@ -57,8 +58,12 @@ public: QStringList files() const; bool visible() const; + bool setImported(bool imported); + bool imported() const; + signals: void materialVisibleChanged(); + void materialImportedChanged(); private: QString m_name; @@ -68,6 +73,7 @@ private: QStringList m_files; bool m_visible = true; + bool m_imported = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp index 9a18ff75014..716fb57dbf5 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp @@ -37,6 +37,16 @@ void BundleMaterialCategory::addBundleMaterial(BundleMaterial *bundleMat) m_categoryMaterials.append(bundleMat); } +bool BundleMaterialCategory::updateImportedState(const QStringList &importedMats) +{ + bool changed = false; + + for (BundleMaterial *mat : std::as_const(m_categoryMaterials)) + changed |= mat->setImported(importedMats.contains(mat->qml().chopped(4))); + + return changed; +} + bool BundleMaterialCategory::filter(const QString &searchText) { bool visible = false; diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h index 0a3a0f7c028..2336a03d010 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h @@ -42,6 +42,7 @@ public: BundleMaterialCategory(QObject *parent, const QString &name); void addBundleMaterial(BundleMaterial *bundleMat); + bool updateImportedState(const QStringList &importedMats); bool filter(const QString &searchText); QString name() const; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp index 4e70008f1ab..a43a23a1d1d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp @@ -122,7 +122,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle() m_matBundleExists = true; - const QString bundleId = m_matBundleObj.value("id").toString(); + QString bundleId = m_matBundleObj.value("id").toString(); const QJsonObject catsObj = m_matBundleObj.value("categories").toObject(); const QStringList categories = catsObj.keys(); @@ -160,8 +160,17 @@ void MaterialBrowserBundleModel::loadMaterialBundle() m_importer = new Internal::BundleImporter(matBundleDir.path(), bundleId, sharedFiles); connect(m_importer, &Internal::BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) { + m_importerRunning = false; + emit importerRunningChanged(); if (metaInfo.isValid()) - emit addBundleMaterialToProjectRequested(metaInfo); + emit bundleMaterialImported(metaInfo); + }); + + connect(m_importer, &Internal::BundleImporter::unimportFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) { + Q_UNUSED(metaInfo) + m_importerRunning = false; + emit importerRunningChanged(); + emit bundleMaterialUnimported(metaInfo); }); } @@ -193,6 +202,11 @@ void MaterialBrowserBundleModel::setHasMaterialRoot(bool b) emit hasMaterialRootChanged(); } +Internal::BundleImporter *MaterialBrowserBundleModel::bundleImporter() const +{ + return m_importer; +} + void MaterialBrowserBundleModel::setSearchText(const QString &searchText) { QString lowerSearchText = searchText.toLower(); @@ -219,6 +233,16 @@ void MaterialBrowserBundleModel::setSearchText(const QString &searchText) resetModel(); } +void MaterialBrowserBundleModel::updateImportedState(const QStringList &importedMats) +{ + bool changed = false; + for (BundleMaterialCategory *cat : std::as_const(m_bundleCategories)) + changed |= cat->updateImportedState(importedMats); + + if (changed) + resetModel(); +} + void MaterialBrowserBundleModel::resetModel() { beginResetModel(); @@ -230,12 +254,30 @@ void MaterialBrowserBundleModel::applyToSelected(BundleMaterial *mat, bool add) emit applyToSelectedTriggered(mat, add); } -void MaterialBrowserBundleModel::addMaterial(BundleMaterial *mat) +void MaterialBrowserBundleModel::addToProject(BundleMaterial *mat) { QString err = m_importer->importComponent(mat->qml(), mat->files()); - if (!err.isEmpty()) + if (err.isEmpty()) { + m_importerRunning = true; + emit importerRunningChanged(); + } else { qWarning() << __FUNCTION__ << err; + } +} + +void MaterialBrowserBundleModel::removeFromProject(BundleMaterial *mat) +{ + emit bundleMaterialAboutToUnimport(mat->type()); + + QString err = m_importer->unimportComponent(mat->qml()); + + if (err.isEmpty()) { + m_importerRunning = true; + emit importerRunningChanged(); + } else { + qWarning() << __FUNCTION__ << err; + } } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h index 60b48f1c9b9..8197ebd78b0 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h @@ -50,6 +50,7 @@ class MaterialBrowserBundleModel : public QAbstractListModel Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged) Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged) + Q_PROPERTY(bool importerRunning MEMBER m_importerRunning NOTIFY importerRunningChanged) public: MaterialBrowserBundleModel(QObject *parent = nullptr); @@ -59,6 +60,7 @@ public: QHash roleNames() const override; void setSearchText(const QString &searchText); + void updateImportedState(const QStringList &importedMats); bool hasQuick3DImport() const; void setHasQuick3DImport(bool b); @@ -66,10 +68,13 @@ public: bool hasMaterialRoot() const; void setHasMaterialRoot(bool b); + Internal::BundleImporter *bundleImporter() const; + void resetModel(); Q_INVOKABLE void applyToSelected(QmlDesigner::BundleMaterial *mat, bool add = false); - Q_INVOKABLE void addMaterial(QmlDesigner::BundleMaterial *mat); + Q_INVOKABLE void addToProject(QmlDesigner::BundleMaterial *mat); + Q_INVOKABLE void removeFromProject(QmlDesigner::BundleMaterial *mat); signals: void isEmptyChanged(); @@ -77,7 +82,10 @@ signals: void hasMaterialRootChanged(); void materialVisibleChanged(); void applyToSelectedTriggered(QmlDesigner::BundleMaterial *mat, bool add = false); - void addBundleMaterialToProjectRequested(const QmlDesigner::NodeMetaInfo &metaInfo); + void bundleMaterialImported(const QmlDesigner::NodeMetaInfo &metaInfo); + void bundleMaterialAboutToUnimport(const QmlDesigner::TypeName &type); + void bundleMaterialUnimported(const QmlDesigner::NodeMetaInfo &metaInfo); + void importerRunningChanged(); private: void loadMaterialBundle(); @@ -93,6 +101,7 @@ private: bool m_hasMaterialRoot = false; bool m_matBundleExists = false; bool m_probeMatBundleDir = false; + bool m_importerRunning = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 94c75d93a77..ed5ab414649 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -27,6 +27,7 @@ #include "bindingproperty.h" #include "bundlematerial.h" +#include "bundleimporter.h" #include "materialbrowserwidget.h" #include "materialbrowsermodel.h" #include "materialbrowserbundlemodel.h" @@ -178,13 +179,28 @@ WidgetInfo MaterialBrowserView::widgetInfo() if (defaultMat.isValid()) applyBundleMaterialToDropTarget(defaultMat); else - m_widget->materialBrowserBundleModel()->addMaterial(bundleMat); + m_widget->materialBrowserBundleModel()->addToProject(bundleMat); }); - connect(matBrowserBundleModel, &MaterialBrowserBundleModel::addBundleMaterialToProjectRequested, this, + connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialImported, this, [&] (const QmlDesigner::NodeMetaInfo &metaInfo) { applyBundleMaterialToDropTarget({}, metaInfo); + updateBundleMaterialsImportedState(); }); + + connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialAboutToUnimport, this, + [&] (const QmlDesigner::TypeName &type) { + // delete instances of the bundle material that is about to be unimported + executeInTransaction("MaterialBrowserView::widgetInfo", [&] { + Utils::reverseForeach(m_widget->materialBrowserModel()->materials(), [&](const ModelNode &mat) { + if (mat.isValid() && mat.type() == type) + QmlObjectNode(mat).destroy(); + }); + }); + }); + + connect(matBrowserBundleModel, &MaterialBrowserBundleModel::bundleMaterialUnimported, this, + &MaterialBrowserView::updateBundleMaterialsImportedState); } return createWidgetInfo(m_widget.data(), @@ -273,6 +289,7 @@ void MaterialBrowserView::modelAttached(Model *model) m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material")); m_hasQuick3DImport = model->hasImport("QtQuick3D"); + updateBundleMaterialsImportedState(); // Project load is already very busy and may even trigger puppet reset, so let's wait a moment // before refreshing the model @@ -440,6 +457,22 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups() m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath); } +void MaterialBrowserView::updateBundleMaterialsImportedState() +{ + using namespace Utils; + + QStringList importedBundleMats; + + FilePath materialBundlePath = m_widget->materialBrowserBundleModel()->bundleImporter()->resolveBundleImportPath(); + + if (materialBundlePath.exists()) { + importedBundleMats = transform(materialBundlePath.dirEntries({{"*.qml"}, QDir::Files}), + [](const FilePath &f) { return f.fileName().chopped(4); }); + } + + m_widget->materialBrowserBundleModel()->updateImportedState(importedBundleMats); +} + ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type) { const QList materials = m_widget->materialBrowserModel()->materials(); @@ -505,7 +538,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt if (defaultMat.isValid()) applyBundleMaterialToDropTarget(defaultMat); else - m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial); + m_widget->materialBrowserBundleModel()->addToProject(m_draggedBundleMaterial); m_draggedBundleMaterial = nullptr; } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 74eaa3a6e21..8d8e225d349 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -68,6 +68,7 @@ private: void refreshModel(bool updateImages); bool isMaterial(const ModelNode &node) const; void loadPropertyGroups(); + void updateBundleMaterialsImportedState(); void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {}); ModelNode getBundleMaterialDefaultInstance(const TypeName &type); @@ -75,6 +76,7 @@ private: QList m_bundleMaterialTargets; QList m_selectedModels; // selected 3D model nodes BundleMaterial *m_draggedBundleMaterial = nullptr; + bool m_bundleMaterialAddToSelected = false; bool m_hasQuick3DImport = false; bool m_autoSelectModelMaterial = false; // TODO: wire this to some action From fdffb6c7d9a6dd22fd62c3a99b2e31a2d81d1be2 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 17 Oct 2022 12:14:14 +0300 Subject: [PATCH 19/24] QmlDesigner: Fix crash when bundImporter is nullptr Change-Id: I54436b0199babe53dcaec61c74b34ed72e80ea7b Reviewed-by: Miikka Heikkinen --- .../components/materialbrowser/materialbrowserview.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index ed5ab414649..0e13521206a 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -461,6 +461,9 @@ void MaterialBrowserView::updateBundleMaterialsImportedState() { using namespace Utils; + if (!m_widget->materialBrowserBundleModel()->bundleImporter()) + return; + QStringList importedBundleMats; FilePath materialBundlePath = m_widget->materialBrowserBundleModel()->bundleImporter()->resolveBundleImportPath(); From bf45aa4d24f78396a98fa5e2fb4bb2261ee05355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20L=C3=B6hning?= Date: Fri, 14 Oct 2022 15:57:56 +0200 Subject: [PATCH 20/24] SquishTests: Update tst_git_clone Reverts f5f684a609cc802335456dad3868ac874008a2e1 Change-Id: Iad797f87333e8d793e34c4e7df1f68c5f6508f82 Reviewed-by: Christian Stenger --- tests/system/suite_tools/tst_git_clone/test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/system/suite_tools/tst_git_clone/test.py b/tests/system/suite_tools/tst_git_clone/test.py index 3eff4777412..01193cad52f 100644 --- a/tests/system/suite_tools/tst_git_clone/test.py +++ b/tests/system/suite_tools/tst_git_clone/test.py @@ -69,8 +69,8 @@ def verifyVersionControlView(targetDir, canceled): "Searching for target directory in clone log") test.verify(" ".join(["clone", "--progress", cloneUrl, cloneDir]) in vcsLog, "Searching for git parameters in clone log") - test.verify(canceled == (" terminated abnormally" in vcsLog), - "Searching for result in clone log") + test.compare(canceled, " terminated abnormally" in vcsLog, + "Searching for result in clone log") clickButton(waitForObject(":*Qt Creator.Clear_QToolButton")) def verifyFiles(targetDir): @@ -139,5 +139,5 @@ def main(): test.fail("The checked out project was not being opened.", str(waitForObject(":Cannot Open Project_QTextEdit").plainText)) clickButton(waitForObject(":Cannot Open Project.OK_QPushButton")) - verifyVersionControlView(targetDir, button != ":Git Repository Clone.Finish_QPushButton") + verifyVersionControlView(targetDir, button == "Cancel immediately") invokeMenuItem("File", "Exit") From a0e87e458b5af22a81a87f6fe5f3e0775ed8b697 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Mon, 17 Oct 2022 10:35:20 +0300 Subject: [PATCH 21/24] Sections could be non-collapsible A property named collapsible is considered for Sections. The default value is true for this property. The section would be affected by the user collapse request if the collapsible is true (Single collapse by clicking, and colapseAll request). Otherwise, the section will not be affected by user requests. Task-number: QDS-7527 Change-Id: Ic4c9d0489d4b8c9ec90a0c71c755fa4c52935d39 Reviewed-by: Miikka Heikkinen Reviewed-by: Mahmoud Badri --- .../MaterialEditorTopSection.qml | 1 + .../imports/HelperWidgets/Section.qml | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml index afc4be51866..6aaad4eaa13 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorTopSection.qml @@ -197,6 +197,7 @@ Column { // Section with hidden header is used so properties are aligned with the other sections' properties hideHeader: true width: parent.width + collapsible: false SectionLayout { PropertyLabel { text: qsTr("Name") } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml index 143ec349d04..69cf7c77953 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml @@ -51,6 +51,7 @@ Item { property int level: 0 property int levelShift: 10 property bool hideHeader: false + property bool collapsible: true property bool expandOnClick: true // if false, toggleExpand signal will be emitted instead property bool addTopPadding: true property bool addBottomPadding: true @@ -70,7 +71,10 @@ Item { Connections { target: Controller - function onCollapseAll() { section.expanded = false } + function onCollapseAll() { + if (collapsible) + section.expanded = false + } function onExpandAll() { section.expanded = true } } @@ -142,6 +146,9 @@ Item { acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: function(mouse) { if (mouse.button === Qt.LeftButton) { + if (!section.collapsible && section.expanded) + return + transition.enabled = true if (section.expandOnClick) section.expanded = !section.expanded From 88c756258244648c555cd6bb77c3bb4ab53f01d1 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 11 Oct 2022 17:47:20 +0300 Subject: [PATCH 22/24] QmlDesigner: Fix the position of placeholder in FilterComboBox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AutoCompleteString view had a bad position. The text property of the TextMetrics was wrong, which caused the placeholder to have bad position since the position was calculated with wrong text. In addition, I prevented showing the placeholder when the root comboBox is not opened, because otherwise it may show text when no item is selected. The main task was QDS-7662, which is now divided. Task-number: QDS-7912 Change-Id: Ib937d923191ec3c544dae3259774cd2bb5b7adb0 Reviewed-by: Henning Gründl --- .../imports/StudioControls/FilterComboBox.qml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/FilterComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/FilterComboBox.qml index da0850fb14a..fd9ddcc445a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/FilterComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/FilterComboBox.qml @@ -547,20 +547,27 @@ Item { ] Text { - visible: root.autocompleteString !== "" + id: tmpSelectionName + visible: root.autocompleteString !== "" && root.open text: root.autocompleteString x: textInput.leftPadding + textMetrics.advanceWidth - y: (textInput.height - Math.ceil(textMetrics.height)) / 2 + y: (textInput.height - Math.ceil(tmpSelectionTextMetrics.height)) / 2 color: "gray" // TODO proper color value font: textInput.font renderType: textInput.renderType + + TextMetrics { + id: textMetrics + font: textInput.font + text: textInput.text + } + TextMetrics { + id: tmpSelectionTextMetrics + font: tmpSelectionName.font + text: "Xq" + } } - TextMetrics { - id: textMetrics - font: textInput.font - text: textInput.text - } Rectangle { id: checkIndicator From fdf1baecd627c48370df1687d2c486c154d4aefd Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 14 Oct 2022 12:53:01 +0300 Subject: [PATCH 23/24] QmlDesigner: Create asset_imports directory at project creation Some watchers won't be initialized correctly if the folder doesn't exist at project startup. E.g. texture images won't appear in project view when material with textures is imported, unless asset_imports already exists at project load. Task-number: QDS-7813 Change-Id: I79449ae823d9005e74594f08bfa87abf44045caf Reviewed-by: Thomas Hartmann Reviewed-by: Reviewed-by: Eike Ziller --- .../studio_templates/projects/application-3d/wizard.json | 4 ++++ .../studio_templates/projects/application/wizard.json | 4 ++++ .../studio_templates/projects/common/asset_imports.txt | 1 + .../studio_templates/projects/desktop-launcher/wizard.json | 4 ++++ .../studio_templates/projects/mobile-scroll/wizard.json | 4 ++++ .../studio_templates/projects/mobile-stack/wizard.json | 4 ++++ .../studio_templates/projects/mobile-swipe/wizard.json | 4 ++++ 7 files changed, 25 insertions(+) create mode 100644 share/qtcreator/qmldesigner/studio_templates/projects/common/asset_imports.txt diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index 9d60367997a..3510d3e190b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -328,6 +328,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index 6912200c14b..68ffb6cff17 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -324,6 +324,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/asset_imports.txt b/share/qtcreator/qmldesigner/studio_templates/projects/common/asset_imports.txt new file mode 100644 index 00000000000..84c843f100d --- /dev/null +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/asset_imports.txt @@ -0,0 +1 @@ +Imported 3D assets and components imported from bundles will be created in this folder. diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index 20a3baba9c7..ab1830752b1 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -323,6 +323,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 3117c7e0544..1a9e07cb63c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -280,6 +280,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index cb083e84f4b..2e07c4725a1 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -284,6 +284,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 1c1137afddb..422db173497 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -284,6 +284,10 @@ "source": "../common/fonts.txt", "target": "%{ProjectDirectory}/content/fonts/fonts.txt" }, + { + "source": "../common/asset_imports.txt", + "target": "%{ProjectDirectory}/asset_imports/asset_imports.txt" + }, { "source": "../common/CMakeLists.imports.txt.tpl", "target": "%{ProjectDirectory}/imports/CMakeLists.txt" From 6276f5514da089c6f56d6746bd56717f162a8041 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 17 Oct 2022 11:44:07 +0300 Subject: [PATCH 24/24] QmlDesigner: Add QML/QtObjectPane.qml In Qt 6.4 QtObject module resolves as QML, so add corresponding property pane. Fixes: QDS-7059 Change-Id: I115bd871132839dc170add254055022840176989 Reviewed-by: Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../QML/QtObjectPane.qml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QML/QtObjectPane.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QML/QtObjectPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QML/QtObjectPane.qml new file mode 100644 index 00000000000..cac322fcf83 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QML/QtObjectPane.qml @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.15 +import "../QtQuick" as Original + +Original.QtObjectPane {}