File indexing completed on 2024-04-21 03:54:13

0001 /*
0002     SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org>
0003     SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com>
0004     SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KKEYSEQUENCERECORDER_H
0010 #define KKEYSEQUENCERECORDER_H
0011 
0012 #include <kguiaddons_export.h>
0013 
0014 #include <QKeySequence>
0015 #include <QObject>
0016 #include <QWindow>
0017 
0018 #include <memory>
0019 
0020 class KKeySequenceRecorderPrivate;
0021 
0022 /**
0023  * @class KKeySequenceRecorder kkeysequencerecorder.h KKeySequenceRecorder
0024  *
0025  * @short Record a QKeySequence by listening to key events in a window.
0026  *
0027  * After calling startRecording key events in the set window will be captured until a valid
0028  * QKeySequence has been recorded and gotKeySequence is emitted. See multiKeyShortcutsAllowed and
0029  * modifierlessAllowed for what constitutes a valid key sequence.
0030  *
0031  * During recording any shortcuts are inhibited and cannot be triggered. Either by using the
0032  * <a href="https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml">
0033  * keyboard-shortcuts-inhibit protocol </a> on Wayland or grabbing the keyboard.
0034  *
0035  * For graphical elements that record key sequences and can optionally perform conflict checking
0036  * against existing shortcuts see KKeySequenceWidget and KeySequenceItem.
0037  *
0038  * Porting from KF5 to KF6:
0039  *
0040  * The class KeySequenceRecorder was renamed to KKeySequenceRecorder.
0041  *
0042  * @see KKeySequenceWidget, KeySequenceItem
0043  * @since 6.0
0044  */
0045 class KGUIADDONS_EXPORT KKeySequenceRecorder : public QObject
0046 {
0047     Q_OBJECT
0048 
0049     /**
0050      * Whether key events are currently recorded
0051      */
0052     Q_PROPERTY(bool isRecording READ isRecording NOTIFY recordingChanged)
0053     /**
0054      * The recorded key sequence.
0055      * After construction this is empty.
0056      *
0057      * During recording it is continuously updated with the newest user input.
0058      *
0059      * After recording it contains the last recorded QKeySequence
0060      */
0061     Q_PROPERTY(QKeySequence currentKeySequence READ currentKeySequence WRITE setCurrentKeySequence NOTIFY currentKeySequenceChanged)
0062     /**
0063      * The window in which the key events are happening that should be recorded
0064      */
0065     Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged)
0066     /**
0067      * If key presses of "plain" keys without a modifier are considered to be a valid finished
0068      * key combination.
0069      * Plain keys  include letter and symbol keys and text editing keys (Return, Space, Tab,
0070      * Backspace, Delete). Other keys like F1, Cursor keys, Insert, PageDown will always work.
0071      *
0072      * By default this is `false`.
0073      */
0074     Q_PROPERTY(bool modifierlessAllowed READ modifierlessAllowed WRITE setModifierlessAllowed NOTIFY modifierlessAllowedChanged)
0075     /** Controls the amount of key combinations that are captured until recording stops and gotKeySequence
0076      * is emitted.
0077      * By default  this is `true` and "Emacs-style" key sequences are recorded. Recording does not
0078      * stop until four valid key combination have been recorded. Afterwards `currentKeySequence().count()`
0079      * will be 4.
0080      *
0081      * Otherwise only one key combination is recorded before gotKeySequence is emitted with a
0082      * QKeySequence with a `count()` of  1.
0083      * @see QKeySequence
0084      */
0085     Q_PROPERTY(bool multiKeyShortcutsAllowed READ multiKeyShortcutsAllowed WRITE setMultiKeyShortcutsAllowed NOTIFY multiKeyShortcutsAllowedChanged)
0086 
0087     /**
0088      * It makes it acceptable for the key sequence to be just a modifier (e.g. Shift or Control)
0089      *
0090      * By default, if only a modifier is pressed and then released, the component will remain waiting for the sequence.
0091      * When enabled, it will take the modifier key as the key sequence.
0092      *
0093      * By default this is `false`.
0094      */
0095     Q_PROPERTY(bool modifierOnlyAllowed READ modifierOnlyAllowed WRITE setModifierOnlyAllowed NOTIFY modifierOnlyAllowedChanged)
0096 public:
0097     /**
0098      * Constructor.
0099      *
0100      * @par window The window whose key events will be recorded.
0101      * @see window
0102      */
0103     explicit KKeySequenceRecorder(QWindow *window, QObject *parent = nullptr);
0104     ~KKeySequenceRecorder() override;
0105 
0106     /**
0107      * Start recording.
0108      * Calling startRecording when window() is `nullptr` has no effect.
0109      */
0110     Q_INVOKABLE void startRecording();
0111 
0112     bool isRecording() const;
0113 
0114     QKeySequence currentKeySequence() const;
0115     void setCurrentKeySequence(const QKeySequence &sequence);
0116 
0117     QWindow *window() const;
0118     void setWindow(QWindow *window);
0119 
0120     bool multiKeyShortcutsAllowed() const;
0121     void setMultiKeyShortcutsAllowed(bool allowed);
0122 
0123     void setModifierlessAllowed(bool allowed);
0124     bool modifierlessAllowed() const;
0125 
0126     void setModifierOnlyAllowed(bool allowed);
0127     bool modifierOnlyAllowed() const;
0128 
0129 public Q_SLOTS:
0130     /**
0131      * Stops the recording session
0132      */
0133     void cancelRecording();
0134 
0135 Q_SIGNALS:
0136     /**
0137      * This signal is emitted when a key sequence has been recorded.
0138      *
0139      * Compared to currentKeySequenceChanged and currentKeySequence this is signal is not emitted
0140      * continuously during recording but only after recording has finished.
0141      */
0142     void gotKeySequence(const QKeySequence &keySequence);
0143 
0144     void recordingChanged();
0145     void windowChanged();
0146     void currentKeySequenceChanged();
0147     void multiKeyShortcutsAllowedChanged();
0148     void modifierlessAllowedChanged();
0149     void modifierOnlyAllowedChanged();
0150 
0151 private:
0152     friend class KKeySequenceRecorderPrivate;
0153     std::unique_ptr<KKeySequenceRecorderPrivate> const d;
0154 };
0155 
0156 #endif