🏡 index : quine-global-labs/mirror-kde-plasma-desktop.git

/*
    SPDX-FileCopyrightText: 2020 David Redondo <david@david-redondo.de>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as QQC2

import org.kde.kirigami as Kirigami
import org.kde.kquickcontrols
import org.kde.kcmutils as KCM

QQC2.ItemDelegate {
    id: root

    property bool showExpandButton: true

    readonly property bool selected: highlighted || down

    highlighted: false
    // If it's the only one in the list, clicking it won't do anything, so don't provide any visual feedback.
    hoverEnabled: showExpandButton
    down: showExpandButton ? undefined : false

    width: shortcutsList.width
    action: QQC2.Action {
        id: expandAction
        text: root.state === "expanded"
            ? i18nc("@action:button Collapse shortcuts view", "Collapse")
            : i18nc("@action:button", "Expand to configure shortcuts")
        icon.name: root.state === "expanded" ? "collapse" : "expand"
        onTriggered: {
            shortcutsList.selectedIndex = (root.state === "expanded") ? -1 : index;
        }
    }
    Accessible.name: root.state === "expanded" ? i18nc("@info:whatsthis accessible name %1 is shortcut label (not sequence)", "Editing shortcut: %1", displayLabel.text) : displayLabel.text + keySequenceList.text
    Accessible.onPressAction: action.trigger()

    Kirigami.Theme.useAlternateBackgroundColor: true

    contentItem: ColumnLayout {
        clip: true

        Kirigami.Theme.textColor: root.selected ? root.Kirigami.Theme.highlightedTextColor : undefined
        Kirigami.Theme.inherit: !root.selected

        spacing: Kirigami.Units.smallSpacing

        Item {
            Layout.alignment: Qt.AlignTop
            Layout.preferredHeight: topRow.implicitHeight
            Layout.fillWidth: true
            RowLayout {
                id: topRow
                anchors.fill: parent
                spacing: Kirigami.Units.smallSpacing
                Kirigami.Heading {
                    id: displayLabel
                    Layout.minimumWidth: Kirigami.Units.gridUnit * 8
                    Layout.fillWidth: true
                    text: i18nc("%1 is the name action that is triggered by the key sequences following after :", "%1:", model.display)
                    wrapMode: Text.Wrap
                    textFormat: Text.PlainText
                    level: 5
                }
                QQC2.Label {
                    id: keySequenceList
                    Layout.fillWidth: true
                    Layout.horizontalStretchFactor: 1
                    color: {
                        if (root.selected) {
                            return Kirigami.Theme.highlightedTextColor;
                        } else if (model?.activeShortcuts?.length !== 0) {
                            return Kirigami.Theme.textColor;
                        } else {
                            return Kirigami.Theme.disabledTextColor;
                        }
                    }

                    elide: Text.ElideRight
                    horizontalAlignment: Text.AlignRight
                    text: {
                        let noShortcuts = i18nc("@info:status", "No active shortcuts")
                        if (model?.activeShortcuts?.length !== 0) {
                            return model?.activeShortcuts?.map(s => kcm.keySequenceToString(s)).join(", ") ?? noShortcuts
                        } else {
                            return noShortcuts
                        }
                    }
                    textFormat: Text.PlainText
                }
                Rectangle {
                    id: defaultIndicator
                    radius: width * 0.5
                    implicitWidth: Kirigami.Units.largeSpacing
                    implicitHeight: Kirigami.Units.largeSpacing
                    visible: kcm.defaultsIndicatorsVisible
                    opacity: !model.isDefault
                    color: Kirigami.Theme.neutralTextColor
                }
                QQC2.Button {
                    Layout.alignment: Qt.AlignRight
                    visible: root.showExpandButton
                    display: QQC2.AbstractButton.IconOnly
                    action: expandAction
                    activeFocusOnTab: false

                    QQC2.ToolTip.text: text
                    QQC2.ToolTip.visible: hovered || activeFocus
                    QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
                }
            }
        }
        Loader {
            id: editLoader
            active: false
            visible: false
            Layout.fillWidth: true
            sourceComponent: ColumnLayout {
                readonly property var originalIndex : {
                    const concatenatedIndex = kcm.filteredModel.mapToSource(dm.modelIndex(index))
                    return kcm.shortcutsModel.mapToSource(concatenatedIndex)
                }
                spacing: Kirigami.Units.smallSpacing

                RowLayout {
                    Layout.fillWidth: true
                    spacing: 0

                    Kirigami.Heading {
                        Layout.fillWidth: true
                        level: 4
                        text: model.defaultShortcuts &&  model.defaultShortcuts.length !== 0 ?
                        i18ncp("@title:column %1 decides if singular or plural will be used", "Default shortcut",
                               "Default shortcuts", model.defaultShortcuts.length) :
                               i18nc("@label for shortcut with no default bindings", "No default shortcuts")
                        textFormat: Text.PlainText
                        elide: Text.ElideRight
                    }

                    Kirigami.Heading {
                        Layout.fillWidth: true
                        Layout.alignment: Qt.AlignRight
                        level: 4
                        text: i18nc("@title:column", "Custom shortcuts")
                        textFormat: Text.PlainText
                        elide: Text.ElideRight
                        horizontalAlignment: Text.AlignRight
                    }
                }

                Kirigami.Separator {
                    Layout.fillWidth: true
                }

                RowLayout {
                    Layout.fillWidth: true
                    spacing: 0


                    ColumnLayout {
                        Layout.alignment: Qt.AlignTop
                        Layout.fillWidth: true
                        spacing: Kirigami.Units.smallSpacing

                        Repeater {
                            model: defaultShortcuts
                            QQC2.CheckBox {
                                Layout.fillWidth: true
                                Accessible.name: checked ? i18nc("@info:whatsthis accessible name", "Default shortcut %1 is enabled.", modelData) : i18nc("@info:whatsthis accessible name", "Default shortcut %1 is disabled.", modelData)
                                checked: activeShortcuts.indexOf(modelData) !== -1
                                text: modelData
                                onToggled: {
                                    if (checked) {
                                        kcm.requestKeySequence(this, originalIndex, modelData)
                                    } else {
                                        originalIndex.model.disableShortcut(originalIndex, modelData)
                                    }
                                }
                                KCM.SettingHighlighter {
                                    highlight: !checked
                                }
                            }
                        }
                    }

                    ColumnLayout {
                        Layout.alignment: Qt.AlignTop | Qt.AlignRight
                        Layout.fillWidth: true
                        spacing: Kirigami.Units.smallSpacing
                        Repeater {
                            model: customShortcuts
                            RowLayout {
                                spacing: Kirigami.Units.smallSpacing
                                Layout.alignment: Qt.AlignRight
                                KeySequenceItem {
                                    id: keySequenceEditor
                                    Layout.alignment: Qt.AlignRight
                                    keySequence: modelData
                                    showClearButton: false
                                    patterns: ShortcutPattern.ModifierAndKey | ShortcutPattern.Modifier
                                    multiKeyShortcutsAllowed: supportsMultipleKeys
                                    checkForConflictsAgainst: ShortcutType.None
                                    onCaptureFinished: {
                                        kcm.requestKeySequence(this, originalIndex, keySequence, modelData)
                                    }
                                    KCM.SettingHighlighter {
                                        highlight: true
                                    }
                                    Connections {
                                        target: kcm
                                        function onShortcutChangeRejected() {
                                            if (keySequenceEditor.keySequence !== modelData) {
                                                keySequenceEditor.keySequence = Qt.binding(() => modelData)
                                            }
                                        }
                                    }
                                }
                                QQC2.Button {
                                    icon.name: "edit-delete"
                                    text: i18nc("@action:button accessible", "Delete shortcut")
                                    display: QQC2.AbstractButton.IconOnly
                                    onClicked: originalIndex.model.disableShortcut(originalIndex, modelData)

                                    QQC2.ToolTip.text: text
                                    QQC2.ToolTip.visible: hovered || activeFocus
                                    QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
                                }
                            }
                        }
                        QQC2.Button {
                            text: i18nc("@action:button Add custom shortcut", "Add…")
                            Accessible.name: i18nc("@action:button accessible", "Add custom shortcut")
                            icon.name: "list-add-symbolic"
                            Layout.alignment: Qt.AlignRight
                            onClicked: {
                                this.visible = false
                                var newKeySequenceItem = newKeySequenceComponent.createObject(parent)
                                for (var i = 0; i < newKeySequenceItem.children.length; i++) {
                                    if (newKeySequenceItem.children[i] instanceof KeySequenceItem) {
                                        var keySequenceItem = newKeySequenceItem.children[i]
                                    }
                                }
                                newKeySequenceItem.finished.connect(() => {
                                    newKeySequenceItem.destroy()
                                    this.visible = true
                                })
                                keySequenceItem.startCapturing()
                            }
                        }
                        Component {
                            id: newKeySequenceComponent
                            RowLayout {
                                signal finished
                                Layout.alignment: Qt.AlignRight
                                spacing: Kirigami.Units.smallSpacing
                                KeySequenceItem {
                                    showClearButton: false
                                    patterns: ShortcutPattern.Modifier | ShortcutPattern.ModifierAndKey
                                    multiKeyShortcutsAllowed: model.supportsMultipleKeys
                                    checkForConflictsAgainst: ShortcutType.None
                                    onCaptureFinished: {
                                        kcm.requestKeySequence(this, originalIndex, keySequence)
                                        parent.finished()
                                    }
                                }
                                QQC2.Button {
                                    icon.name: "dialog-cancel"
                                    text: i18nc("@action:button accessible", "Cancel capturing shortcut")
                                    display: QQC2.AbstractButton.IconOnly
                                    onClicked: parent.finished()

                                    QQC2.ToolTip.text: text
                                    QQC2.ToolTip.visible: hovered || activeFocus
                                    QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    states: [
        State {
            name: "expanded"
            when: shortcutsList.selectedIndex === index || shortcutsList.count == 1
            PropertyChanges {
                target: root
                hoverEnabled: false
            }
            PropertyChanges {
                target: displayLabel
                level: 3
                Layout.fillWidth: true
            }
            PropertyChanges {
                target: keySequenceList
                visible: false
            }
            PropertyChanges {
                target: editLoader
                active: true
                visible: true
            }
        }
    ]
    Behavior on height {
        NumberAnimation {
            properties: "height"
            duration: Kirigami.Units.shortDuration
        }
    }
}