Files
qt-creator/share/qtcreator/qmldesigner/collectionEditorQmlSource/ModelSourceItem.qml
Ali Kianian 01a4f087c6 QmlDesigner: Use Studio.Models as the source of the CollectionEditor
QtQuick.Studio.Models JSON and CSV components are used as the source
of the Collection Editor.
Collections are placed underneath the sources in the collections view

Task-number: QDS-10809
Task-number: QDS-10462
Change-Id: Ia0c9cb587c462fcba98934b15068582f3f9c19c5
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
2023-10-02 09:52:42 +00:00

332 lines
9.0 KiB
QML

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Controls
import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
import StudioTheme as StudioTheme
Item {
id: root
implicitWidth: 300
implicitHeight: wholeColumn.height + 6
property color textColor
property var collectionModel
property bool expanded: false
signal selectItem(int itemIndex)
signal deleteItem()
Column {
id: wholeColumn
Item {
id: boundingRect
anchors.centerIn: root
width: root.width - 24
height: nameHolder.height
clip: true
MouseArea {
id: itemMouse
anchors.fill: parent
acceptedButtons: Qt.LeftButton
propagateComposedEvents: true
hoverEnabled: true
onClicked: (event) => {
if (!sourceIsSelected) {
sourceIsSelected = true
event.accepted = true
}
}
onDoubleClicked: (event) => {
if (collectionListView.count > 0)
root.expanded = !root.expanded;
}
}
Rectangle {
id: innerRect
anchors.fill: parent
}
Row {
width: parent.width - threeDots.width
leftPadding: 20
Text {
id: expandButton
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
width: expandButton.style.squareControlSize.width
height: nameHolder.height
text: StudioTheme.Constants.startNode
font.family: StudioTheme.Constants.iconFont.family
font.pixelSize: expandButton.style.baseIconFontSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: textColor
rotation: root.expanded ? 90 : 0
Behavior on rotation {
SpringAnimation { spring: 2; damping: 0.2 }
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton + Qt.LeftButton
onClicked: (event) => {
root.expanded = !root.expanded
event.accepted = true
}
}
visible: collectionListView.count > 0
}
Text {
id: nameHolder
text: sourceName
font.pixelSize: StudioTheme.Values.baseFontSize
color: textColor
leftPadding: 5
topPadding: 8
rightPadding: 8
bottomPadding: 8
elide: Text.ElideMiddle
verticalAlignment: Text.AlignVCenter
}
}
Text {
id: threeDots
text: StudioTheme.Constants.more_medium
font.family: StudioTheme.Constants.iconFont.family
font.pixelSize: StudioTheme.Values.baseIconFontSize
color: textColor
anchors.right: boundingRect.right
anchors.verticalCenter: parent.verticalCenter
rightPadding: 12
topPadding: nameHolder.topPadding
bottomPadding: nameHolder.bottomPadding
verticalAlignment: Text.AlignVCenter
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton + Qt.LeftButton
onClicked: (event) => {
collectionMenu.popup()
event.accepted = true
}
}
}
}
ListView {
id: collectionListView
width: parent.width
height: root.expanded ? contentHeight : 0
model: collections
clip: true
Behavior on height {
NumberAnimation {duration: 500}
}
delegate: CollectionItem {
width: parent.width
onDeleteItem: root.model.removeRow(index)
}
}
}
StudioControls.Menu {
id: collectionMenu
StudioControls.MenuItem {
text: qsTr("Delete")
shortcut: StandardKey.Delete
onTriggered: deleteDialog.open()
}
StudioControls.MenuItem {
text: qsTr("Rename")
shortcut: StandardKey.Replace
onTriggered: renameDialog.open()
}
}
StudioControls.Dialog {
id: deleteDialog
title: qsTr("Deleting source")
contentItem: Column {
spacing: 2
Text {
text: qsTr("Are you sure that you want to delete source \"" + sourceName + "\"?")
color: StudioTheme.Values.themeTextColor
}
Item { // spacer
width: 1
height: 20
}
Row {
anchors.right: parent.right
spacing: 10
HelperWidgets.Button {
id: btnDelete
text: qsTr("Delete")
onClicked: root.deleteItem(index)
}
HelperWidgets.Button {
text: qsTr("Cancel")
onClicked: deleteDialog.reject()
}
}
}
}
StudioControls.Dialog {
id: renameDialog
title: qsTr("Rename source")
onAccepted: {
if (newNameField.text !== "")
sourceName = newNameField.text
}
onOpened: {
newNameField.text = sourceName
}
contentItem: Column {
spacing: 2
Text {
text: qsTr("Previous name: " + sourceName)
color: StudioTheme.Values.themeTextColor
}
Row {
spacing: 10
Text {
text: qsTr("New name:")
color: StudioTheme.Values.themeTextColor
}
StudioControls.TextField {
id: newNameField
actionIndicator.visible: false
translationIndicator.visible: false
validator: newNameValidator
Keys.onEnterPressed: renameDialog.accept()
Keys.onReturnPressed: renameDialog.accept()
Keys.onEscapePressed: renameDialog.reject()
onTextChanged: {
btnRename.enabled = newNameField.text !== ""
}
}
}
Item { // spacer
width: 1
height: 20
}
Row {
anchors.right: parent.right
spacing: 10
HelperWidgets.Button {
id: btnRename
text: qsTr("Rename")
onClicked: renameDialog.accept()
}
HelperWidgets.Button {
text: qsTr("Cancel")
onClicked: renameDialog.reject()
}
}
}
}
HelperWidgets.RegExpValidator {
id: newNameValidator
regExp: /^\w+$/
}
states: [
State {
name: "default"
when: !sourceIsSelected && !itemMouse.containsMouse
PropertyChanges {
target: innerRect
opacity: 0.4
color: StudioTheme.Values.themeControlBackground
}
PropertyChanges {
target: root
textColor: StudioTheme.Values.themeTextColor
}
},
State {
name: "hovered"
when: !sourceIsSelected && itemMouse.containsMouse
PropertyChanges {
target: innerRect
opacity: 0.5
color: StudioTheme.Values.themeControlBackgroundHover
}
PropertyChanges {
target: root
textColor: StudioTheme.Values.themeTextColor
}
},
State {
name: "selected"
when: sourceIsSelected
PropertyChanges {
target: innerRect
opacity: 0.6
color: StudioTheme.Values.themeControlBackgroundInteraction
}
PropertyChanges {
target: root
textColor: StudioTheme.Values.themeIconColorSelected
}
}
]
}