File indexing completed on 2024-04-28 16:44:54

0001 /*
0002    SPDX-FileCopyrightText: 1999-2001 Lubos Lunak <l.lunak@kde.org>
0003    SPDX-FileCopyrightText: 2008 Michael Jansen <kde@michael-jansen.biz>
0004 
0005    SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #ifndef _TRIGGERS_H_
0009 #define _TRIGGERS_H_
0010 
0011 #include <QList>
0012 #include <QMap>
0013 #include <QUuid>
0014 
0015 #include <QKeySequence>
0016 
0017 #include "khotkeysglobal.h"
0018 
0019 #include "input.h"
0020 #include "triggers/gestures.h"
0021 #include "windows_handler.h"
0022 
0023 class QKeySequence;
0024 class KConfigGroup;
0025 
0026 namespace KHotKeys
0027 {
0028 class Windowdef_list;
0029 class ActionData;
0030 
0031 class TriggerVisitor
0032 {
0033 public:
0034     virtual ~TriggerVisitor();
0035 };
0036 
0037 class Q_DECL_EXPORT Trigger
0038 {
0039     Q_DISABLE_COPY(Trigger)
0040 
0041 public:
0042     enum TriggerType {
0043         GestureTriggerType = 0x01, //!< @see GestureTrigger
0044         ShortcutTriggerType = 0x02, //!< @see ShortcutTrigger
0045         WindowTriggerType = 0x04, //!< @see WindowTrigger
0046         TriggerListType = 0x08, //!< @see Trigger_list
0047         AllTypes = 0xFF, //!< All types. For convenience.
0048     };
0049 
0050     Q_DECLARE_FLAGS(TriggerTypes, TriggerType)
0051 
0052     Trigger(ActionData *data_P);
0053     virtual ~Trigger();
0054     virtual void cfg_write(KConfigGroup &cfg_P) const = 0;
0055     virtual Trigger *copy(ActionData *data_P) const = 0;
0056     virtual const QString description() const = 0;
0057     virtual void activate(bool activate_P) = 0;
0058 
0059     //! Disable the trigger
0060     virtual void disable();
0061 
0062     //! Enable the trigger
0063     virtual void enable();
0064 
0065     /**
0066      * The trigger will be erased permanently
0067      */
0068     virtual void aboutToBeErased();
0069 
0070     /**
0071      * The actual type for this trigger
0072      */
0073     virtual TriggerType type() const = 0;
0074 
0075     /**
0076      * Acyclic visitor pattern
0077      */
0078     virtual void accept(TriggerVisitor &) = 0;
0079 
0080 protected:
0081     ActionData *const data;
0082 };
0083 
0084 Q_DECLARE_OPERATORS_FOR_FLAGS(Trigger::TriggerTypes)
0085 
0086 class Q_DECL_EXPORT Trigger_list : public QList<Trigger *>
0087 {
0088     Q_DISABLE_COPY(Trigger_list)
0089 
0090 public:
0091     Trigger_list(const QString &comment = QString());
0092     virtual ~Trigger_list();
0093 
0094     void activate(bool activate_P);
0095     void cfg_write(KConfigGroup &cfg_P) const;
0096     //! Some convenience typedef
0097     typedef QList<Trigger *>::Iterator Iterator;
0098     typedef QList<Trigger *>::ConstIterator ConstIterator;
0099     const QString comment() const;
0100     void set_comment(const QString &);
0101     Trigger_list *copy(ActionData *data_P) const;
0102 
0103     //! Disable the trigger
0104     virtual void disable();
0105 
0106     //! Enable the trigger
0107     virtual void enable();
0108 
0109     /**
0110      * @reimp
0111      */
0112     void aboutToBeErased();
0113 
0114 private:
0115     QString _comment;
0116 };
0117 
0118 class ShortcutTrigger;
0119 class ShortcutTriggerVisitor
0120 {
0121 public:
0122     virtual ~ShortcutTriggerVisitor();
0123     virtual void visit(ShortcutTrigger &) = 0;
0124 };
0125 
0126 class Q_DECL_EXPORT ShortcutTrigger : public QObject, public Trigger
0127 {
0128     Q_OBJECT
0129 
0130     typedef Trigger base;
0131 
0132 public:
0133     ShortcutTrigger(ActionData *data, const QKeySequence &shortcut = QKeySequence(), const QUuid &uuid = QUuid::createUuid());
0134 
0135     ~ShortcutTrigger() override;
0136     void cfg_write(KConfigGroup &cfg_P) const override;
0137     ShortcutTrigger *copy(ActionData *data_P) const override;
0138     const QString description() const override;
0139     QList<QKeySequence> shortcut() const;
0140     void activate(bool activate_P) override;
0141 
0142     void set_key_sequence(const QKeySequence &seq);
0143 
0144     TriggerType type() const override
0145     {
0146         return ShortcutTriggerType;
0147     }
0148 
0149     /**
0150      * @reimp
0151      */
0152     void aboutToBeErased() override;
0153 
0154     //! Disable the trigger
0155     void disable() override;
0156 
0157     //! Enable the trigger
0158     void enable() override;
0159 
0160     /**
0161      * Acyclic visitor pattern
0162      */
0163     void accept(TriggerVisitor &) override;
0164 
0165     QString primaryShortcut() const;
0166 
0167 public Q_SLOTS:
0168 
0169     void trigger();
0170 
0171 private:
0172     QString shortcuts() const;
0173 
0174     //! A persistent identifier for this shortcut
0175     QUuid _uuid;
0176 
0177     //! Are the conditions met?
0178     bool _active;
0179 
0180     /**
0181      * The Key Sequence associated with this Trigger. This is needed
0182      * because a inactive trigger doesn't register it's shortcut with
0183      * kde's global shortcuts registry so we have to remember the shortcut
0184      * ourselves. Beware of synchronizing saved state, global shortcuts
0185      * registry state and state of this var :-) .
0186      */
0187     QKeySequence _shortcut;
0188 };
0189 
0190 class WindowTrigger;
0191 class WindowTriggerVisitor
0192 {
0193 public:
0194     virtual ~WindowTriggerVisitor();
0195     virtual void visit(WindowTrigger &) = 0;
0196 };
0197 
0198 class Q_DECL_EXPORT WindowTrigger : public QObject, public Trigger
0199 {
0200     Q_OBJECT
0201 
0202     Q_FLAGS(WindowEvents)
0203 
0204     typedef Trigger base;
0205 
0206 public:
0207     enum window_action_t {
0208         NONE = 0,
0209         WINDOW_APPEARS = (1 << 0), //!< The window is opened
0210         WINDOW_DISAPPEARS = (1 << 1), //!< The window is closed
0211         WINDOW_ACTIVATES = (1 << 2), //!< The window gets the focus
0212         WINDOW_DEACTIVATES = (1 << 3), //!< The window loses the focus
0213     };
0214 
0215     Q_DECLARE_FLAGS(WindowEvents, window_action_t)
0216 
0217     WindowTrigger(ActionData *data, Windowdef_list *windowslist = nullptr, WindowEvents window_actions = NONE);
0218 
0219     void setOnWindowEvents(WindowEvents events);
0220 
0221     ~WindowTrigger() override;
0222     void cfg_write(KConfigGroup &cfg_P) const override;
0223     WindowTrigger *copy(ActionData *data_P) const override;
0224     const QString description() const override;
0225     const Windowdef_list *windows() const;
0226     void set_window_rules(Windowdef_list *list);
0227     Windowdef_list *windows();
0228     bool triggers_on(window_action_t w_action_P) const;
0229     void activate(bool activate_P) override;
0230 
0231     TriggerType type() const override
0232     {
0233         return WindowTriggerType;
0234     }
0235 
0236     /**
0237      * Acyclic visitor pattern
0238      */
0239     void accept(TriggerVisitor &) override;
0240 
0241 protected Q_SLOTS:
0242     void window_added(WId window_P);
0243     void window_removed(WId window_P);
0244     void active_window_changed(WId window_P);
0245     void window_changed(WId window_P, unsigned int dirty_P);
0246 
0247 private:
0248     //! Useful code for all constructors
0249     void init();
0250 
0251     Windowdef_list *_windows;
0252 
0253     WindowEvents window_actions;
0254 
0255     typedef QMap<WId, bool> Windows_map;
0256 
0257     //! Internal cache. Remembers if a window is a match or not,
0258     Windows_map existing_windows;
0259 
0260     //! The last active window
0261     WId last_active_window;
0262 
0263     //! Is the trigger active?
0264     bool active;
0265 };
0266 
0267 Q_DECLARE_OPERATORS_FOR_FLAGS(WindowTrigger::WindowEvents)
0268 
0269 /**
0270  * This class handles the storage of gesture data; it also matches gestures
0271  * and links the gesture to an action.
0272  * One object equals one configured gesture.
0273  */
0274 class GestureTrigger;
0275 class GestureTriggerVisitor
0276 {
0277 public:
0278     virtual ~GestureTriggerVisitor();
0279     virtual void visit(GestureTrigger &) = 0;
0280 };
0281 
0282 class Q_DECL_EXPORT GestureTrigger : public QObject, public Trigger
0283 {
0284     Q_OBJECT
0285     typedef Trigger base;
0286 
0287 public:
0288     GestureTrigger(ActionData *data, const StrokePoints &pointdata_P = StrokePoints());
0289 
0290     ~GestureTrigger() override;
0291     void cfg_write(KConfigGroup &cfg_P) const override;
0292     Trigger *copy(ActionData *data_P) const override;
0293     const QString description() const override;
0294     const StrokePoints &pointData() const;
0295 
0296     //! Set the point data of the gesture
0297     void setPointData(const StrokePoints &data);
0298     void setPointData(const QStringList &strings);
0299     void setKDE3Gesture(const QString &gestureCode);
0300 
0301     void activate(bool activate_P) override;
0302 
0303     TriggerType type() const override
0304     {
0305         return GestureTriggerType;
0306     }
0307 
0308     /**
0309      * Acyclic visitor pattern
0310      */
0311     void accept(TriggerVisitor &) override;
0312 
0313 protected Q_SLOTS:
0314     void handle_gesture(const StrokePoints &gesture_P);
0315 Q_SIGNALS:
0316     void gotScore(ActionData *const data, const qreal score);
0317 
0318 private:
0319     qreal comparePointData(const StrokePoints &a, const StrokePoints &b) const;
0320     inline qreal angleSquareDifference(qreal alpha, qreal beta) const;
0321 
0322     StrokePoints _pointdata;
0323 };
0324 
0325 } // namespace KHotKeys
0326 
0327 #endif