1 /*
2     Actiona
3     Copyright (C) 2005 Jonathan Mercier-Ganady
4 
5     Actiona is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     Actiona is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18     Contact : jmgr@jmgr.info
19 */
20 
21 #pragma once
22 
23 #include "actiontools_global.h"
24 
25 #include <QString>
26 #include <QHash>
27 
28 #include <functional>
29 
30 class QKeyEvent;
31 
32 namespace ActionTools
33 {
34     class ACTIONTOOLSSHARED_EXPORT KeyboardKey final
35     {
36     public:
37         enum class KeyType
38         {
39             Invalid,
40             Standard,
41             Native,
42             Character
43         };
44 
45         enum class StandardKey
46         {
47             Backspace,
48             Tabulation,
49             Clear,
50             Enter,
51             LeftShift,
52             RightShift,
53             LeftControl,
54             RightControl,
55             LeftAlt,
56             RightAlt,
57             AltGr,
58             Pause,
59             CapsLock,
60             Escape,
61             Space,
62             Prior,
63             Next,
64             End,
65             Home,
66             LeftArrow,
67             UpArrow,
68             RightArrow,
69             DownArrow,
70             Select,
71             Execute,
72             Snapshot,
73             Insert,
74             Delete,
75             Help,
76             LeftWindows,
77             RightWindows,
78             Applications,
79             Sleep,
80             Numpad0,
81             Numpad1,
82             Numpad2,
83             Numpad3,
84             Numpad4,
85             Numpad5,
86             Numpad6,
87             Numpad7,
88             Numpad8,
89             Numpad9,
90             Multiply,
91             Add,
92             Separator,
93             Subtract,
94             Decimal,
95             Divide,
96             NumpadEnter,
97             NumpadDelete,
98             NumpadPrior,
99             NumpadNext,
100             NumpadEnd,
101             NumpadHome,
102             NumpadLeftArrow,
103             NumpadUpArrow,
104             NumpadRightArrow,
105             NumpadDownArrow,
106             NumpadInsert,
107             NumpadClear,
108             F1,
109             F2,
110             F3,
111             F4,
112             F5,
113             F6,
114             F7,
115             F8,
116             F9,
117             F10,
118             F11,
119             F12,
120             F13,
121             F14,
122             F15,
123             F16,
124             F17,
125             F18,
126             F19,
127             F20,
128             F21,
129             F22,
130             F23,
131             F24,
132             NumLock,
133             ScrollLock,
134             BrowserBack,
135             BrowserForward,
136             BrowserRefresh,
137             BrowserStop,
138             BrowserSearch,
139             BrowserFavorites,
140             BrowserHome,
141             VolumeMute,
142             VolumeDown,
143             VolumeUp,
144             MediaNextTrack,
145             MediaPreviousTrack,
146             MediaStop,
147             MediaPlayPause,
148             LaunchMail,
149             LaunchMediaSelect,
150             LaunchApp1,
151             LaunchApp2,
152             Play,
153 
154             Count,
155         };
156 
157         KeyboardKey();
158         KeyboardKey(StandardKey standardKey);
159         explicit KeyboardKey(unsigned int nativeKey);
160         explicit KeyboardKey(QChar unicodeCharacter);
161         explicit KeyboardKey(QKeyEvent *keyEvent);
162 
163         bool isValid() const;
164         QString name() const;
165         bool isPressed() const;
keyType() const166         KeyType keyType() const { return mKeyType; }
standardKey() const167         StandardKey standardKey() const { Q_ASSERT(mKeyType == KeyType::Standard); return mStandardKey; }
nativeKey() const168         unsigned int nativeKey() const { Q_ASSERT(mKeyType == KeyType::Native); return mNativeKey; }
character() const169         QChar character() const { Q_ASSERT(mKeyType == KeyType::Character); return mNativeKey; }
170 
171         void save(std::function<void(const QString &, const QString &)> keyValueCallback) const;
172         static KeyboardKey load(std::function<QString(const QString &)> keyValueCallback);
173 
174         static QList<KeyboardKey> loadKeyListFromJson(const QString &json);
175         static QString saveKeyListToJson(const QList<KeyboardKey> &keyList);
176 
177         static QList<KeyboardKey> findPressedKeys();
178 
179     private:
180         KeyboardKey(KeyType keyType, unsigned int key);
181 
182         static void initialize();
183 
184         static KeyboardKey fromNativeKey(unsigned int virtualKey, unsigned int scanCode, const QString &text = {});
185         static QString nativeKeyName(unsigned int key);
186 
187         KeyType mKeyType{KeyType::Invalid};
188         StandardKey mStandardKey{StandardKey::Backspace};
189         unsigned int mNativeKey{0};
190 
191         static bool mInitializationDone;
192 
193         friend bool operator==(const KeyboardKey &first, const KeyboardKey &second);
194         friend uint qHash(const KeyboardKey &key, uint seed);
195     };
196 
operator ==(const KeyboardKey & first,const KeyboardKey & second)197     inline bool operator==(const KeyboardKey &first, const KeyboardKey &second)
198     {
199         return first.mKeyType == second.mKeyType &&
200                 first.mStandardKey == second.mStandardKey &&
201                 first.mNativeKey == second.mNativeKey;
202     }
203 
qHash(const KeyboardKey & key,uint seed)204     inline uint qHash(const KeyboardKey &key, uint seed)
205     {
206         return ::qHash(static_cast<int>(key.mKeyType), seed) ^ ::qHash(static_cast<unsigned int>(key.mStandardKey), seed) ^ ::qHash(key.mNativeKey, seed);
207     }
208 }
209