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
134 QQC2.ToolTip {
135 visible: mainButton.hovered
136 text: mainButton.Accessible.description
137 }
138
139 onCheckedChanged: {
140 if (checked) {
141 validator.currentKeySequence = root.keySequence
142 helper.window = helper.renderWindow(parent.Window.window)
143 mainButton.forceActiveFocus()
144 helper.startRecording()
145 } else if (helper.isRecording) {
146 helper.cancelRecording()
147 }
148 }
149
150 onFocusChanged: {
151 if (!focus) {
152 mainButton.checked = false
153 }
154 }
155 }
156
157 QQC2.Button {
158 id: clearButton
159 Layout.fillHeight: true
160 Layout.preferredWidth: height
161 visible: root.showClearButton && !helper.isRecording
162 onClicked: {
163 root.keySequence = "";
164 root.keySequenceModified();
165 root.captureFinished(); // Not really capturing, but otherwise we cannot track this state, hence apps should use keySequenceModified
166 }
167
168 enabled: !helper.keySequenceIsEmpty(helper.currentKeySequence)
169
170 hoverEnabled: true
171 // icon name determines the direction of the arrow, NOT the direction of the app layout
172 icon.name: Qt.application.layoutDirection === Qt.LeftToRight ? "edit-clear-locationbar-rtl" : "edit-clear-locationbar-ltr"
173
174 Accessible.name: _tr.i18nc("@info:tooltip", "Clear Key Sequence")
175
176 QQC2.ToolTip {
177 visible: clearButton.hovered
178 text: clearButton.Accessible.name
179 }
180 }
181
182 QQC2.Button {
183 Layout.fillHeight: true
184 Layout.preferredWidth: height
185 onClicked: helper.cancelRecording()
186 visible: root.showCancelButton && helper.isRecording
187
188 icon.name: "dialog-cancel"
189
190 Accessible.name: _tr.i18nc("@info:tooltip", "Cancel Key Sequence Recording")
191
192 QQC2.ToolTip {
193 visible: parent.hovered
194 text: parent.Accessible.name
195 }
196 }
197}
QAction * replace(const QObject *recvr, const char *slot, QObject *parent)
void hovered()
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 19 2024 11:51:26 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.