summaryrefslogtreecommitdiff
path: root/share/qtcreator/qmldesigner/itemLibraryQmlSources
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2022-10-18 10:48:46 +0200
committerEike Ziller <eike.ziller@qt.io>2022-10-18 10:48:46 +0200
commitea5a050c5cddc72572d15c092217451f224c4153 (patch)
tree59aa1b38a6ba31757ac8443352683c1b36585838 /share/qtcreator/qmldesigner/itemLibraryQmlSources
parentce6ab1a14d59acdf19860a446055130a179b76f6 (diff)
parent6276f5514da089c6f56d6746bd56717f162a8041 (diff)
downloadqt-creator-ea5a050c5cddc72572d15c092217451f224c4153.tar.gz
Merge remote-tracking branch 'origin/8.0' into 9.0
Conflicts: src/plugins/mcusupport/mcusupportsdk.cpp src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp Change-Id: I9317da0fc1243b9ce6d87f577aa843c51f132ad7
Diffstat (limited to 'share/qtcreator/qmldesigner/itemLibraryQmlSources')
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml512
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml120
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml246
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/ConfirmDeleteFolderDialog.qml92
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/NewFolderDialog.qml102
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/RenameFolderDialog.qml124
6 files changed, 689 insertions, 507 deletions
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
index 1b9a284ce1..f8c0605734 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
@@ -24,6 +24,10 @@ Item {
// Array of supported externally dropped files that trigger custom import process
property var dropComplexExtFiles: []
+ AssetsContextMenu {
+ id: contextMenu
+ }
+
function clearSearchFilter()
{
searchBox.clear();
@@ -103,307 +107,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[^*/><?\\|:]*)$/
}
- 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
- }
- }
-
- 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 = "New folder"
- folderName.selectAll()
- folderName.forceActiveFocus()
- }
- }
-
- 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()
- }
-
Column {
anchors.fill: parent
anchors.topMargin: 5
@@ -507,220 +215,10 @@ Item {
}
}
- ScrollView { // TODO: experiment using ListView instead of ScrollView + Column
+ AssetsView {
id: assetsView
width: parent.width
height: parent.height - y
- 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/AssetsContextMenu.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsContextMenu.qml
new file mode 100644
index 0000000000..5caa139651
--- /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 0000000000..e1c017814d
--- /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 0000000000..a4fd300975
--- /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 0000000000..130026ddce
--- /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 0000000000..351c0a35fc
--- /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
+ }
+}