Kirigami-addons

KeySequenceItem.qml
1// SPDX-FileCopyrightText: 2014 David Edmundson <kde@davidedmundson.co.uk>
2// SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de>
3// SPDX-FileCopyrightText: 2022 Aleix Pol <aleixpol@kde.org>
4// SPDX-FileCopyrightText: 2024 ivan tkachenko <me@ratijas.tk>
5// SPDX-FileCopyrightText: 2024 Carl Schwan <carl@carlschwan.eu>
6// SPDX-License-Identifier: LGPL-2.1-or-later
7
8import QtQuick
9import QtQuick.Controls as QQC2
10import QtQuick.Layouts
11
12import org.kde.kirigami as Kirigami
13import org.kde.kirigamiaddons.statefulapp.private
14import org.kde.kirigamiaddons.formcard as FormCard
15
16/**
17 * @internal
18 */
19FormCard.AbstractFormDelegate {
20 id: root
21
22 required property string label
23 property bool showClearButton: true
24 property bool showCancelButton: true
25 property alias modifierOnlyAllowed: helper.modifierOnlyAllowed
26 property alias modifierlessAllowed: helper.modifierlessAllowed
27 property alias multiKeyShortcutsAllowed: helper.multiKeyShortcutsAllowed
28 property alias keySequence: helper.currentKeySequence
29
30 /**
31 * This property controls which types of shortcuts are checked for conflicts when the keySequence
32 * is set. If a conflict is detected, a messagebox will be shown asking the user to confirm their
33 * input. Valid values are combinations of the following flags:
34 * - @p ShortcutType.None Do not check for conflicts.
35 * - @p ShortcutType.StandardShortcuts Check against standard shortcuts. @see KStandardShortcut
36 * - @p ShortcutType.GlobalShortcuts Check against global shortcuts. Only works when building with KGlobalAccel. @see KGlobalAccel
37 *
38 * The default is `ShortcutType.GlobalShortcuts | ShortcutType.StandardShortcut`
39 */
40 property alias checkForConflictsAgainst: helper.checkAgainstShortcutTypes
41
42 property string __previousSequence: ""
43
44 /**
45 * Emitted whenever the key sequence is modified by the user interacting with the component
46 *
47 * Either by interacting capturing a key sequence or pressing the clear button.
48 */
49 signal keySequenceModified()
50
51 signal errorOccurred(title: string, message: string)
52
53 signal showStealStandardShortcutDialog(title: string, message: string, sequence: var)
54
55 /**
56 * Start capturing a key sequence. This equivalent to the user clicking on the main button of the item.
57 */
58 function startCapturing() {
59 mainButton.checked = true;
60 }
61
62 function stealStandardShortcut(sequence): void {
63 applyStealStandardShortcutTimer.sequence = sequence;
64 applyStealStandardShortcutTimer.start();
65 }
66
67 Timer {
68 id: applyStealStandardShortcutTimer
69
70 property var sequence
71
72 interval: 200
73 onTriggered: {
74 helper.currentKeySequence = sequence;
75 root.keySequenceModified();
76 }
77 }
78
79 background: null
80
81 contentItem: ColumnLayout {
82 spacing: Kirigami.Units.smallSpacing
83
84 QQC2.Label {
85 text: root.label
86 visible: text.length > 0
87 Layout.fillWidth: true
88 }
89
90 RowLayout {
91 Layout.fillWidth: true
92
93 KeySequenceHelper {
94 id: helper
95 onGotKeySequence: keySequence => {
96 if (!isKeySequenceAvailable(keySequence)) {
97 currentKeySequence = root.__previousSequence;
98 }
99 mainButton.checked = false;
100 root.keySequenceModified();
101 }
102
103 onErrorOccurred: (title, message) => {
104 root.errorOccurred(title, message);
105 }
106
107 onShowStealStandardShortcutDialog: (title, message, seq) => {
108 root.showStealStandardShortcutDialog(title, message, seq);
109 }
110 }
111
112 QQC2.Button {
113 id: mainButton
114
115 Layout.fillHeight: true
116 Layout.fillWidth: true
117
118 icon.name: "configure"
119
120 checkable: true
121 focus: checked
122
123 hoverEnabled: true
124
125 text: {
126 const keySequence = helper.currentKeySequence;
127 const text = helper.keySequenceIsEmpty(keySequence)
128 ? (helper.isRecording
129 ? i18ndc("kirigami-addons6", "What the user inputs now will be taken as the new shortcut", "Input")
130 : i18ndc("kirigami-addons6", "No shortcut defined", "None"))
131 // Single ampersand gets interpreted by the button as a mnemonic
132 // and removed; replace it with a double ampersand so that it
133 // will be displayed by the button as a single ampersand, or
134 // else shortcuts with the actual ampersand character will
135 // appear to be partially empty.
136 : helper.keySequenceNativeText(keySequence).replace('&', '&&');
137 // These spaces are intentional
138 return " " + text + (helper.isRecording ? " ... " : " ");
139 }
140
141 Accessible.description: i18nd("kirigami-addons6", "Click on the button, then enter the shortcut like you would in the program.\nExample for Ctrl+A: hold the Ctrl key and press A.")
142
143 QQC2.ToolTip.visible: hovered
144 QQC2.ToolTip.text: Accessible.description
145 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
146
147 onCheckedChanged: {
148 if (checked) {
149 root.__previousSequence = helper.keySequenceNativeText(root.keySequence)
150 helper.window = helper.renderWindow(parent.Window.window)
151 mainButton.forceActiveFocus()
152 helper.startRecording()
153 } else if (helper.isRecording) {
154 helper.cancelRecording()
155 }
156 }
157
158 onFocusChanged: {
159 if (!focus) {
160 mainButton.checked = false
161 }
162 }
163 }
164
165 QQC2.Button {
166 id: clearButton
167 Layout.fillHeight: true
168 Layout.preferredWidth: height
169 visible: root.showClearButton && !helper.isRecording
170 onClicked: {
171 root.keySequence = "";
172 root.keySequenceModified();
173 }
174
175 enabled: !helper.keySequenceIsEmpty(helper.currentKeySequence)
176
177 hoverEnabled: true
178 // icon name determines the direction of the arrow, NOT the direction of the app layout
179 icon.name: Qt.application.layoutDirection === Qt.LeftToRight ? "edit-clear-locationbar-rtl" : "edit-clear-locationbar-ltr"
180
181 display: QQC2.Button.IconOnly
182 text: i18ndc("kirigami-addons6", "@info:tooltip", "Clear Key Sequence")
183
184 QQC2.ToolTip.visible: hovered
185 QQC2.ToolTip.text: text
186 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
187 }
188
189 QQC2.Button {
190 Layout.fillHeight: true
191 Layout.preferredWidth: height
192 onClicked: helper.cancelRecording()
193 visible: root.showCancelButton && helper.isRecording
194
195 icon.name: "dialog-cancel"
196
197 display: QQC2.Button.IconOnly
198 text: i18ndc("kirigami-addons6", "@info:tooltip", "Cancel Key Sequence Recording")
199
200 QQC2.ToolTip.visible: hovered
201 QQC2.ToolTip.text: Accessible.name
202 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
203 }
204 }
205 }
206}
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
QAction * replace(const QObject *recvr, const char *slot, QObject *parent)
void keySequence(QWidget *widget, const QKeySequence &keySequence)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:54:39 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.