KDeclarative

KeySequenceItem.qml
1// SPDX-FileCopyright: 2014 David Edmundson <kde@davidedmundson.co.uk
2// SPDX-FileCopyright: 2020 David Redondo <kde@david-redondo.de
3// SPDX-FileCopyright: 2022 Aleix Pol <aleixpol@kde.org>
4// SPDX-FileCopyright: 2024 ivan tkachenko <me@ratijas.tk>
5// SPDX-License-Identifier: LGPL-2.1-or-later
6
7import QtQuick
8import QtQuick.Controls as QQC2
9import QtQuick.Layouts
10
11import org.kde.private.kquickcontrols as KQuickControlsPrivate
12
13RowLayout {
14 id: root
15
16 property bool showClearButton: true
17 property bool showCancelButton: false /// TODO KF6 default to true
18 property alias modifierOnlyAllowed: helper.modifierOnlyAllowed
19 property alias modifierlessAllowed: helper.modifierlessAllowed
20 property alias multiKeyShortcutsAllowed: helper.multiKeyShortcutsAllowed
21 property alias keySequence: helper.currentKeySequence
22
23 /**
24 * This property controls which types of shortcuts are checked for conflicts when the keySequence
25 * is set. If a conflict is detected, a messagebox will be shown asking the user to confirm their
26 * input. Valid values are combinations of the following flags:
27 * - @p ShortcutType.None Do not check for conflicts.
28 * - @p ShortcutType.StandardShortcuts Check against standard shortcuts. @see KStandardshortcut
29 * - @p ShortcutType.GlobalShortcuts Check against global shortcuts. @see KGlobalAccel
30 *
31 * The default is `ShortcutType.GlobalShortcuts | ShortcutType.StandardShortcut`
32 * @since 5.74
33 */
34 property alias checkForConflictsAgainst: helper.checkAgainstShortcutTypes
35
36 /**
37 * This signal is emitted after the user introduces a new key sequence
38 *
39 * @since 5.68
40 * @deprecated Use keySequenceModified()
41 */
42 signal captureFinished()
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 * @since 5.99
50 */
51 signal keySequenceModified()
52
53 /**
54 * Start capturing a key sequence. This equivalent to the user clicking on the main button of the item
55 * @since 5.70
56 */
57 function startCapturing() {
58 mainButton.checked = true;
59 }
60
61 // A layout like RowLayout would automatically and implicitly fillHeight
62 // if placed inside a ColumnLayout, so an explicit binding should prevent
63 // that behavior. On the contrary, filling width wouldn't hurt, although
64 // it doesn't make much sense, as this component is not really adaptive.
65 Layout.fillHeight: false
66
67 KQuickControlsPrivate.KeySequenceHelper {
68 id: helper
69
70 onGotKeySequence: keySequence => {
71 validator.validateSequence(keySequence)
72 }
73
74 onQuestionDialogAccepted: validator.accept()
75 onQuestionDialogRejected: validator.reject()
76 }
77
78 KQuickControlsPrivate.KeySequenceValidator {
79 id: validator
80
81 validateTypes: helper.checkAgainstShortcutTypes
82
83 onError: (title, message) => {
84 helper.showErrorDialog(title, message)
85 }
86
87 onQuestion: (title, message) => {
88 helper.showQuestionDialog(title, message)
89 }
90
91 onFinished: keySequence => {
92 helper.updateKeySequence(keySequence)
93 mainButton.checked = false
94 root.captureFinished()
95 root.keySequenceModified()
96 }
97 }
98
99 KQuickControlsPrivate.TranslationContext {
100 id: _tr
101 domain: "kdeclarative6"
102 }
103
104 QQC2.Button {
105 id: mainButton
106
107 Layout.fillHeight: true
108
109 icon.name: "configure"
110
111 checkable: true
112 focus: checked
113
114 hoverEnabled: true
115
116 text: {
117 const keySequence = helper.currentKeySequence;
118 const text = helper.keySequenceIsEmpty(keySequence)
119 ? (helper.isRecording
120 ? _tr.i18nc("What the user inputs now will be taken as the new shortcut", "Input")
121 : _tr.i18nc("No shortcut defined", "None"))
122 // Single ampersand gets interpreted by the button as a mnemonic
123 // and removed; replace it with a double ampersand so that it
124 // will be displayed by the button as a single ampersand, or
125 // else shortcuts with the actual ampersand character will
126 // appear to be partially empty.
127 : helper.keySequenceNativeText(keySequence).replace('&', '&&');
128 // These spaces are intentional
129 return " " + text + (helper.isRecording ? " ... " : " ");
130 }
131
132 Accessible.description: _tr.i18n("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.")
133 Accessible.role: Accessible.Button
134
135 QQC2.ToolTip {
136 visible: mainButton.hovered
137 text: mainButton.Accessible.description
138 }
139
140 onCheckedChanged: {
141 if (checked) {
142 validator.currentKeySequence = root.keySequence
143 helper.window = helper.renderWindow(parent.Window.window)
144 mainButton.forceActiveFocus()
145 helper.startRecording()
146 } else if (helper.isRecording) {
147 helper.cancelRecording()
148 }
149 }
150
151 onFocusChanged: {
152 if (!focus) {
153 mainButton.checked = false
154 }
155 }
156 }
157
158 QQC2.Button {
159 id: clearButton
160 Layout.fillHeight: true
161 Layout.preferredWidth: height
162 visible: root.showClearButton && !helper.isRecording
163 onClicked: {
164 root.keySequence = "";
165 root.keySequenceModified();
166 root.captureFinished(); // Not really capturing, but otherwise we cannot track this state, hence apps should use keySequenceModified
167 }
168
169 enabled: !helper.keySequenceIsEmpty(helper.currentKeySequence)
170
171 hoverEnabled: true
172 // icon name determines the direction of the arrow, NOT the direction of the app layout
173 icon.name: Qt.application.layoutDirection === Qt.LeftToRight ? "edit-clear-locationbar-rtl" : "edit-clear-locationbar-ltr"
174
175 Accessible.name: _tr.i18nc("@info:tooltip", "Clear Key Sequence")
176
177 QQC2.ToolTip {
178 visible: clearButton.hovered
179 text: clearButton.Accessible.name
180 }
181 }
182
183 QQC2.Button {
184 Layout.fillHeight: true
185 Layout.preferredWidth: height
186 onClicked: helper.cancelRecording()
187 visible: root.showCancelButton && helper.isRecording
188
189 icon.name: "dialog-cancel"
190
191 Accessible.name: _tr.i18nc("@info:tooltip", "Cancel Key Sequence Recording")
192
193 QQC2.ToolTip {
194 visible: parent.hovered
195 text: parent.Accessible.name
196 }
197 }
198}
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 Oct 11 2024 12:14:27 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.