1 | /* |
2 | SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org> |
3 | SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com> |
4 | SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #ifndef KKEYSEQUENCERECORDER_H |
10 | #define KKEYSEQUENCERECORDER_H |
11 | |
12 | #include <kguiaddons_export.h> |
13 | |
14 | #include <QKeySequence> |
15 | #include <QObject> |
16 | #include <QWindow> |
17 | |
18 | #include <memory> |
19 | |
20 | class KKeySequenceRecorderPrivate; |
21 | |
22 | /** |
23 | * @class KKeySequenceRecorder kkeysequencerecorder.h KKeySequenceRecorder |
24 | * |
25 | * @short Record a QKeySequence by listening to key events in a window. |
26 | * |
27 | * After calling startRecording key events in the set window will be captured until a valid |
28 | * QKeySequence has been recorded and gotKeySequence is emitted. See multiKeyShortcutsAllowed and |
29 | * modifierlessAllowed for what constitutes a valid key sequence. |
30 | * |
31 | * During recording any shortcuts are inhibited and cannot be triggered. Either by using the |
32 | * <a href="https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml"> |
33 | * keyboard-shortcuts-inhibit protocol </a> on Wayland or grabbing the keyboard. |
34 | * |
35 | * For graphical elements that record key sequences and can optionally perform conflict checking |
36 | * against existing shortcuts see KKeySequenceWidget and KeySequenceItem. |
37 | * |
38 | * Porting from KF5 to KF6: |
39 | * |
40 | * The class KeySequenceRecorder was renamed to KKeySequenceRecorder. |
41 | * |
42 | * @see KKeySequenceWidget, KeySequenceItem |
43 | * @since 6.0 |
44 | */ |
45 | class KGUIADDONS_EXPORT KKeySequenceRecorder : public QObject |
46 | { |
47 | Q_OBJECT |
48 | |
49 | /** |
50 | * Whether key events are currently recorded |
51 | */ |
52 | Q_PROPERTY(bool isRecording READ isRecording NOTIFY recordingChanged) |
53 | /** |
54 | * The recorded key sequence. |
55 | * After construction this is empty. |
56 | * |
57 | * During recording it is continuously updated with the newest user input. |
58 | * |
59 | * After recording it contains the last recorded QKeySequence |
60 | */ |
61 | Q_PROPERTY(QKeySequence currentKeySequence READ currentKeySequence WRITE setCurrentKeySequence NOTIFY currentKeySequenceChanged) |
62 | /** |
63 | * The window in which the key events are happening that should be recorded |
64 | */ |
65 | Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged) |
66 | /** |
67 | * If key presses of "plain" keys without a modifier are considered to be a valid finished |
68 | * key combination. |
69 | * Plain keys include letter and symbol keys and text editing keys (Return, Space, Tab, |
70 | * Backspace, Delete). Other keys like F1, Cursor keys, Insert, PageDown will always work. |
71 | * |
72 | * By default this is `false`. |
73 | */ |
74 | Q_PROPERTY(bool modifierlessAllowed READ modifierlessAllowed WRITE setModifierlessAllowed NOTIFY modifierlessAllowedChanged) |
75 | /** Controls the amount of key combinations that are captured until recording stops and gotKeySequence |
76 | * is emitted. |
77 | * By default this is `true` and "Emacs-style" key sequences are recorded. Recording does not |
78 | * stop until four valid key combination have been recorded. Afterwards `currentKeySequence().count()` |
79 | * will be 4. |
80 | * |
81 | * Otherwise only one key combination is recorded before gotKeySequence is emitted with a |
82 | * QKeySequence with a `count()` of 1. |
83 | * @see QKeySequence |
84 | */ |
85 | Q_PROPERTY(bool multiKeyShortcutsAllowed READ multiKeyShortcutsAllowed WRITE setMultiKeyShortcutsAllowed NOTIFY multiKeyShortcutsAllowedChanged) |
86 | |
87 | /** |
88 | * It makes it acceptable for the key sequence to be just a modifier (e.g. Shift or Control) |
89 | * |
90 | * By default, if only a modifier is pressed and then released, the component will remain waiting for the sequence. |
91 | * When enabled, it will take the modifier key as the key sequence. |
92 | * |
93 | * By default this is `false`. |
94 | */ |
95 | Q_PROPERTY(bool modifierOnlyAllowed READ modifierOnlyAllowed WRITE setModifierOnlyAllowed NOTIFY modifierOnlyAllowedChanged) |
96 | public: |
97 | /** |
98 | * Constructor. |
99 | * |
100 | * @par window The window whose key events will be recorded. |
101 | * @see window |
102 | */ |
103 | explicit KKeySequenceRecorder(QWindow *window, QObject *parent = nullptr); |
104 | ~KKeySequenceRecorder() override; |
105 | |
106 | /** |
107 | * Start recording. |
108 | * Calling startRecording when window() is `nullptr` has no effect. |
109 | */ |
110 | Q_INVOKABLE void startRecording(); |
111 | |
112 | bool isRecording() const; |
113 | |
114 | QKeySequence currentKeySequence() const; |
115 | void setCurrentKeySequence(const QKeySequence &sequence); |
116 | |
117 | QWindow *window() const; |
118 | void setWindow(QWindow *window); |
119 | |
120 | bool multiKeyShortcutsAllowed() const; |
121 | void setMultiKeyShortcutsAllowed(bool allowed); |
122 | |
123 | void setModifierlessAllowed(bool allowed); |
124 | bool modifierlessAllowed() const; |
125 | |
126 | void setModifierOnlyAllowed(bool allowed); |
127 | bool modifierOnlyAllowed() const; |
128 | |
129 | public Q_SLOTS: |
130 | /** |
131 | * Stops the recording session |
132 | */ |
133 | void cancelRecording(); |
134 | |
135 | Q_SIGNALS: |
136 | /** |
137 | * This signal is emitted when a key sequence has been recorded. |
138 | * |
139 | * Compared to currentKeySequenceChanged and currentKeySequence this is signal is not emitted |
140 | * continuously during recording but only after recording has finished. |
141 | */ |
142 | void gotKeySequence(const QKeySequence &keySequence); |
143 | |
144 | void recordingChanged(); |
145 | void windowChanged(); |
146 | void currentKeySequenceChanged(); |
147 | void multiKeyShortcutsAllowedChanged(); |
148 | void modifierlessAllowedChanged(); |
149 | void modifierOnlyAllowedChanged(); |
150 | |
151 | private: |
152 | friend class KKeySequenceRecorderPrivate; |
153 | std::unique_ptr<KKeySequenceRecorderPrivate> const d; |
154 | }; |
155 | |
156 | #endif |
157 | |