1 | /* |
2 | SPDX-FileCopyrightText: 2008 Erlend Hamberg <ehamberg@gmail.com> |
3 | SPDX-FileCopyrightText: 2008 Evgeniy Ivanov <powerfox@kde.ru> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "definitions.h" |
9 | #include <QKeyEvent> |
10 | #include <QStringList> |
11 | #include <vimode/keyevent.h> |
12 | #include <vimode/keyparser.h> |
13 | |
14 | using namespace KateVi; |
15 | |
16 | KeyParser *KeyParser::m_instance = nullptr; |
17 | |
18 | KeyParser::KeyParser() |
19 | { |
20 | initKeyTables(); |
21 | } |
22 | |
23 | KeyParser *KeyParser::self() |
24 | { |
25 | if (m_instance == nullptr) { |
26 | m_instance = new KeyParser(); |
27 | } |
28 | |
29 | return m_instance; |
30 | } |
31 | |
32 | void KeyParser::initKeyTables() |
33 | { |
34 | m_qt2katevi = { |
35 | {Qt::Key_Escape, QStringLiteral("esc" )}, |
36 | {Qt::Key_Tab, QStringLiteral("tab" )}, |
37 | {Qt::Key_Backtab, QStringLiteral("backtab" )}, |
38 | {Qt::Key_Backspace, QStringLiteral("backspace" )}, |
39 | {Qt::Key_Return, QStringLiteral("return" )}, |
40 | {Qt::Key_Enter, QStringLiteral("enter" )}, |
41 | {Qt::Key_Insert, QStringLiteral("insert" )}, |
42 | {Qt::Key_Delete, QStringLiteral("delete" )}, |
43 | {Qt::Key_Pause, QStringLiteral("pause" )}, |
44 | {Qt::Key_Print, QStringLiteral("print" )}, |
45 | {Qt::Key_SysReq, QStringLiteral("sysreq" )}, |
46 | {Qt::Key_Clear, QStringLiteral("clear" )}, |
47 | {Qt::Key_Home, QStringLiteral("home" )}, |
48 | {Qt::Key_End, QStringLiteral("end" )}, |
49 | {Qt::Key_Left, QStringLiteral("left" )}, |
50 | {Qt::Key_Up, QStringLiteral("up" )}, |
51 | {Qt::Key_Right, QStringLiteral("right" )}, |
52 | {Qt::Key_Down, QStringLiteral("down" )}, |
53 | {Qt::Key_PageUp, QStringLiteral("pageup" )}, |
54 | {Qt::Key_PageDown, QStringLiteral("pagedown" )}, |
55 | {Qt::Key_Shift, QStringLiteral("shift" )}, |
56 | {Qt::Key_Control, QStringLiteral("control" )}, |
57 | {Qt::Key_Meta, QStringLiteral("meta" )}, |
58 | {Qt::Key_Alt, QStringLiteral("alt" )}, |
59 | {Qt::Key_AltGr, QStringLiteral("altgr" )}, |
60 | {Qt::Key_CapsLock, QStringLiteral("capslock" )}, |
61 | {Qt::Key_NumLock, QStringLiteral("numlock" )}, |
62 | {Qt::Key_ScrollLock, QStringLiteral("scrolllock" )}, |
63 | {Qt::Key_F1, QStringLiteral("f1" )}, |
64 | {Qt::Key_F2, QStringLiteral("f2" )}, |
65 | {Qt::Key_F3, QStringLiteral("f3" )}, |
66 | {Qt::Key_F4, QStringLiteral("f4" )}, |
67 | {Qt::Key_F5, QStringLiteral("f5" )}, |
68 | {Qt::Key_F6, QStringLiteral("f6" )}, |
69 | {Qt::Key_F7, QStringLiteral("f7" )}, |
70 | {Qt::Key_F8, QStringLiteral("f8" )}, |
71 | {Qt::Key_F9, QStringLiteral("f9" )}, |
72 | {Qt::Key_F10, QStringLiteral("f10" )}, |
73 | {Qt::Key_F11, QStringLiteral("f11" )}, |
74 | {Qt::Key_F12, QStringLiteral("f12" )}, |
75 | {Qt::Key_F13, QStringLiteral("f13" )}, |
76 | {Qt::Key_F14, QStringLiteral("f14" )}, |
77 | {Qt::Key_F15, QStringLiteral("f15" )}, |
78 | {Qt::Key_F16, QStringLiteral("f16" )}, |
79 | {Qt::Key_F17, QStringLiteral("f17" )}, |
80 | {Qt::Key_F18, QStringLiteral("f18" )}, |
81 | {Qt::Key_F19, QStringLiteral("f19" )}, |
82 | {Qt::Key_F20, QStringLiteral("f20" )}, |
83 | {Qt::Key_F21, QStringLiteral("f21" )}, |
84 | {Qt::Key_F22, QStringLiteral("f22" )}, |
85 | {Qt::Key_F23, QStringLiteral("f23" )}, |
86 | {Qt::Key_F24, QStringLiteral("f24" )}, |
87 | {Qt::Key_F25, QStringLiteral("f25" )}, |
88 | {Qt::Key_F26, QStringLiteral("f26" )}, |
89 | {Qt::Key_F27, QStringLiteral("f27" )}, |
90 | {Qt::Key_F28, QStringLiteral("f28" )}, |
91 | {Qt::Key_F29, QStringLiteral("f29" )}, |
92 | {Qt::Key_F30, QStringLiteral("f30" )}, |
93 | {Qt::Key_F31, QStringLiteral("f31" )}, |
94 | {Qt::Key_F32, QStringLiteral("f32" )}, |
95 | {Qt::Key_F33, QStringLiteral("f33" )}, |
96 | {Qt::Key_F34, QStringLiteral("f34" )}, |
97 | {Qt::Key_F35, QStringLiteral("f35" )}, |
98 | {Qt::Key_Super_L, QStringLiteral("super_l" )}, |
99 | {Qt::Key_Super_R, QStringLiteral("super_r" )}, |
100 | {Qt::Key_Menu, QStringLiteral("menu" )}, |
101 | {Qt::Key_Hyper_L, QStringLiteral("hyper_l" )}, |
102 | {Qt::Key_Hyper_R, QStringLiteral("hyper_r" )}, |
103 | {Qt::Key_Help, QStringLiteral("help" )}, |
104 | {Qt::Key_Direction_L, QStringLiteral("direction_l" )}, |
105 | {Qt::Key_Direction_R, QStringLiteral("direction_r" )}, |
106 | {Qt::Key_Multi_key, QStringLiteral("multi_key" )}, |
107 | {Qt::Key_Codeinput, QStringLiteral("codeinput" )}, |
108 | {Qt::Key_SingleCandidate, QStringLiteral("singlecandidate" )}, |
109 | {Qt::Key_MultipleCandidate, QStringLiteral("multiplecandidate" )}, |
110 | {Qt::Key_PreviousCandidate, QStringLiteral("previouscandidate" )}, |
111 | {Qt::Key_Mode_switch, QStringLiteral("mode_switch" )}, |
112 | {Qt::Key_Kanji, QStringLiteral("kanji" )}, |
113 | {Qt::Key_Muhenkan, QStringLiteral("muhenkan" )}, |
114 | {Qt::Key_Henkan, QStringLiteral("henkan" )}, |
115 | {Qt::Key_Romaji, QStringLiteral("romaji" )}, |
116 | {Qt::Key_Hiragana, QStringLiteral("hiragana" )}, |
117 | {Qt::Key_Katakana, QStringLiteral("katakana" )}, |
118 | {Qt::Key_Hiragana_Katakana, QStringLiteral("hiragana_katakana" )}, |
119 | {Qt::Key_Zenkaku, QStringLiteral("zenkaku" )}, |
120 | {Qt::Key_Hankaku, QStringLiteral("hankaku" )}, |
121 | {Qt::Key_Zenkaku_Hankaku, QStringLiteral("zenkaku_hankaku" )}, |
122 | {Qt::Key_Touroku, QStringLiteral("touroku" )}, |
123 | {Qt::Key_Massyo, QStringLiteral("massyo" )}, |
124 | {Qt::Key_Kana_Lock, QStringLiteral("kana_lock" )}, |
125 | {Qt::Key_Kana_Shift, QStringLiteral("kana_shift" )}, |
126 | {Qt::Key_Eisu_Shift, QStringLiteral("eisu_shift" )}, |
127 | {Qt::Key_Eisu_toggle, QStringLiteral("eisu_toggle" )}, |
128 | {Qt::Key_Hangul, QStringLiteral("hangul" )}, |
129 | {Qt::Key_Hangul_Start, QStringLiteral("hangul_start" )}, |
130 | {Qt::Key_Hangul_End, QStringLiteral("hangul_end" )}, |
131 | {Qt::Key_Hangul_Hanja, QStringLiteral("hangul_hanja" )}, |
132 | {Qt::Key_Hangul_Jamo, QStringLiteral("hangul_jamo" )}, |
133 | {Qt::Key_Hangul_Romaja, QStringLiteral("hangul_romaja" )}, |
134 | {Qt::Key_Hangul_Jeonja, QStringLiteral("hangul_jeonja" )}, |
135 | {Qt::Key_Hangul_Banja, QStringLiteral("hangul_banja" )}, |
136 | {Qt::Key_Hangul_PreHanja, QStringLiteral("hangul_prehanja" )}, |
137 | {Qt::Key_Hangul_PostHanja, QStringLiteral("hangul_posthanja" )}, |
138 | {Qt::Key_Hangul_Special, QStringLiteral("hangul_special" )}, |
139 | {Qt::Key_Dead_Grave, QStringLiteral("dead_grave" )}, |
140 | {Qt::Key_Dead_Acute, QStringLiteral("dead_acute" )}, |
141 | {Qt::Key_Dead_Circumflex, QStringLiteral("dead_circumflex" )}, |
142 | {Qt::Key_Dead_Tilde, QStringLiteral("dead_tilde" )}, |
143 | {Qt::Key_Dead_Macron, QStringLiteral("dead_macron" )}, |
144 | {Qt::Key_Dead_Breve, QStringLiteral("dead_breve" )}, |
145 | {Qt::Key_Dead_Abovedot, QStringLiteral("dead_abovedot" )}, |
146 | {Qt::Key_Dead_Diaeresis, QStringLiteral("dead_diaeresis" )}, |
147 | {Qt::Key_Dead_Abovering, QStringLiteral("dead_abovering" )}, |
148 | {Qt::Key_Dead_Doubleacute, QStringLiteral("dead_doubleacute" )}, |
149 | {Qt::Key_Dead_Caron, QStringLiteral("dead_caron" )}, |
150 | {Qt::Key_Dead_Cedilla, QStringLiteral("dead_cedilla" )}, |
151 | {Qt::Key_Dead_Ogonek, QStringLiteral("dead_ogonek" )}, |
152 | {Qt::Key_Dead_Iota, QStringLiteral("dead_iota" )}, |
153 | {Qt::Key_Dead_Voiced_Sound, QStringLiteral("dead_voiced_sound" )}, |
154 | {Qt::Key_Dead_Semivoiced_Sound, QStringLiteral("dead_semivoiced_sound" )}, |
155 | {Qt::Key_Dead_Belowdot, QStringLiteral("dead_belowdot" )}, |
156 | {Qt::Key_Dead_Hook, QStringLiteral("dead_hook" )}, |
157 | {Qt::Key_Dead_Horn, QStringLiteral("dead_horn" )}, |
158 | {Qt::Key_Back, QStringLiteral("back" )}, |
159 | {Qt::Key_Forward, QStringLiteral("forward" )}, |
160 | {Qt::Key_Stop, QStringLiteral("stop" )}, |
161 | {Qt::Key_Refresh, QStringLiteral("refresh" )}, |
162 | {Qt::Key_VolumeDown, QStringLiteral("volumedown" )}, |
163 | {Qt::Key_VolumeMute, QStringLiteral("volumemute" )}, |
164 | {Qt::Key_VolumeUp, QStringLiteral("volumeup" )}, |
165 | {Qt::Key_BassBoost, QStringLiteral("bassboost" )}, |
166 | {Qt::Key_BassUp, QStringLiteral("bassup" )}, |
167 | {Qt::Key_BassDown, QStringLiteral("bassdown" )}, |
168 | {Qt::Key_TrebleUp, QStringLiteral("trebleup" )}, |
169 | {Qt::Key_TrebleDown, QStringLiteral("trebledown" )}, |
170 | {Qt::Key_MediaPlay, QStringLiteral("mediaplay" )}, |
171 | {Qt::Key_MediaStop, QStringLiteral("mediastop" )}, |
172 | {Qt::Key_MediaPrevious, QStringLiteral("mediaprevious" )}, |
173 | {Qt::Key_MediaNext, QStringLiteral("medianext" )}, |
174 | {Qt::Key_MediaRecord, QStringLiteral("mediarecord" )}, |
175 | {Qt::Key_HomePage, QStringLiteral("homepage" )}, |
176 | {Qt::Key_Favorites, QStringLiteral("favorites" )}, |
177 | {Qt::Key_Search, QStringLiteral("search" )}, |
178 | {Qt::Key_Standby, QStringLiteral("standby" )}, |
179 | {Qt::Key_OpenUrl, QStringLiteral("openurl" )}, |
180 | {Qt::Key_LaunchMail, QStringLiteral("launchmail" )}, |
181 | {Qt::Key_LaunchMedia, QStringLiteral("launchmedia" )}, |
182 | {Qt::Key_Launch0, QStringLiteral("launch0" )}, |
183 | {Qt::Key_Launch1, QStringLiteral("launch1" )}, |
184 | {Qt::Key_Launch2, QStringLiteral("launch2" )}, |
185 | {Qt::Key_Launch3, QStringLiteral("launch3" )}, |
186 | {Qt::Key_Launch4, QStringLiteral("launch4" )}, |
187 | {Qt::Key_Launch5, QStringLiteral("launch5" )}, |
188 | {Qt::Key_Launch6, QStringLiteral("launch6" )}, |
189 | {Qt::Key_Launch7, QStringLiteral("launch7" )}, |
190 | {Qt::Key_Launch8, QStringLiteral("launch8" )}, |
191 | {Qt::Key_Launch9, QStringLiteral("launch9" )}, |
192 | {Qt::Key_LaunchA, QStringLiteral("launcha" )}, |
193 | {Qt::Key_LaunchB, QStringLiteral("launchb" )}, |
194 | {Qt::Key_LaunchC, QStringLiteral("launchc" )}, |
195 | {Qt::Key_LaunchD, QStringLiteral("launchd" )}, |
196 | {Qt::Key_LaunchE, QStringLiteral("launche" )}, |
197 | {Qt::Key_LaunchF, QStringLiteral("launchf" )}, |
198 | {Qt::Key_MediaLast, QStringLiteral("medialast" )}, |
199 | {Qt::Key_unknown, QStringLiteral("unknown" )}, |
200 | {Qt::Key_Call, QStringLiteral("call" )}, |
201 | {Qt::Key_Context1, QStringLiteral("context1" )}, |
202 | {Qt::Key_Context2, QStringLiteral("context2" )}, |
203 | {Qt::Key_Context3, QStringLiteral("context3" )}, |
204 | {Qt::Key_Context4, QStringLiteral("context4" )}, |
205 | {Qt::Key_Flip, QStringLiteral("flip" )}, |
206 | {Qt::Key_Hangup, QStringLiteral("hangup" )}, |
207 | {Qt::Key_No, QStringLiteral("no" )}, |
208 | {Qt::Key_Select, QStringLiteral("select" )}, |
209 | {Qt::Key_Yes, QStringLiteral("yes" )}, |
210 | {Qt::Key_Execute, QStringLiteral("execute" )}, |
211 | {Qt::Key_Printer, QStringLiteral("printer" )}, |
212 | {Qt::Key_Play, QStringLiteral("play" )}, |
213 | {Qt::Key_Sleep, QStringLiteral("sleep" )}, |
214 | {Qt::Key_Zoom, QStringLiteral("zoom" )}, |
215 | {Qt::Key_Cancel, QStringLiteral("cancel" )}, |
216 | }; |
217 | |
218 | for (QHash<int, QString>::const_iterator i = m_qt2katevi.constBegin(); i != m_qt2katevi.constEnd(); ++i) { |
219 | m_katevi2qt.insert(key: i.value(), value: i.key()); |
220 | } |
221 | m_katevi2qt.insert(QStringLiteral("cr" ), value: Qt::Key_Enter); |
222 | |
223 | m_nameToKeyCode = { |
224 | {QStringLiteral("invalid" ), -1}, |
225 | {QStringLiteral("esc" ), 1}, |
226 | {QStringLiteral("tab" ), 2}, |
227 | {QStringLiteral("backtab" ), 3}, |
228 | {QStringLiteral("backspace" ), 4}, |
229 | {QStringLiteral("return" ), 5}, |
230 | {QStringLiteral("enter" ), 6}, |
231 | {QStringLiteral("insert" ), 7}, |
232 | {QStringLiteral("delete" ), 8}, |
233 | {QStringLiteral("pause" ), 9}, |
234 | {QStringLiteral("print" ), 10}, |
235 | {QStringLiteral("sysreq" ), 11}, |
236 | {QStringLiteral("clear" ), 12}, |
237 | {QStringLiteral("home" ), 13}, |
238 | {QStringLiteral("end" ), 14}, |
239 | {QStringLiteral("left" ), 15}, |
240 | {QStringLiteral("up" ), 16}, |
241 | {QStringLiteral("right" ), 17}, |
242 | {QStringLiteral("down" ), 18}, |
243 | {QStringLiteral("pageup" ), 19}, |
244 | {QStringLiteral("pagedown" ), 20}, |
245 | {QStringLiteral("shift" ), 21}, |
246 | {QStringLiteral("control" ), 22}, |
247 | {QStringLiteral("meta" ), 23}, |
248 | {QStringLiteral("alt" ), 24}, |
249 | {QStringLiteral("altgr" ), 25}, |
250 | {QStringLiteral("capslock" ), 26}, |
251 | {QStringLiteral("numlock" ), 27}, |
252 | {QStringLiteral("scrolllock" ), 28}, |
253 | {QStringLiteral("f1" ), 29}, |
254 | {QStringLiteral("f2" ), 30}, |
255 | {QStringLiteral("f3" ), 31}, |
256 | {QStringLiteral("f4" ), 32}, |
257 | {QStringLiteral("f5" ), 33}, |
258 | {QStringLiteral("f6" ), 34}, |
259 | {QStringLiteral("f7" ), 35}, |
260 | {QStringLiteral("f8" ), 36}, |
261 | {QStringLiteral("f9" ), 37}, |
262 | {QStringLiteral("f10" ), 38}, |
263 | {QStringLiteral("f11" ), 39}, |
264 | {QStringLiteral("f12" ), 40}, |
265 | {QStringLiteral("f13" ), 41}, |
266 | {QStringLiteral("f14" ), 42}, |
267 | {QStringLiteral("f15" ), 43}, |
268 | {QStringLiteral("f16" ), 44}, |
269 | {QStringLiteral("f17" ), 45}, |
270 | {QStringLiteral("f18" ), 46}, |
271 | {QStringLiteral("f19" ), 47}, |
272 | {QStringLiteral("f20" ), 48}, |
273 | {QStringLiteral("f21" ), 49}, |
274 | {QStringLiteral("f22" ), 50}, |
275 | {QStringLiteral("f23" ), 51}, |
276 | {QStringLiteral("f24" ), 52}, |
277 | {QStringLiteral("f25" ), 53}, |
278 | {QStringLiteral("f26" ), 54}, |
279 | {QStringLiteral("f27" ), 55}, |
280 | {QStringLiteral("f28" ), 56}, |
281 | {QStringLiteral("f29" ), 57}, |
282 | {QStringLiteral("f30" ), 58}, |
283 | {QStringLiteral("f31" ), 59}, |
284 | {QStringLiteral("f32" ), 60}, |
285 | {QStringLiteral("f33" ), 61}, |
286 | {QStringLiteral("f34" ), 62}, |
287 | {QStringLiteral("f35" ), 63}, |
288 | {QStringLiteral("super_l" ), 64}, |
289 | {QStringLiteral("super_r" ), 65}, |
290 | {QStringLiteral("menu" ), 66}, |
291 | {QStringLiteral("hyper_l" ), 67}, |
292 | {QStringLiteral("hyper_r" ), 68}, |
293 | {QStringLiteral("help" ), 69}, |
294 | {QStringLiteral("direction_l" ), 70}, |
295 | {QStringLiteral("direction_r" ), 71}, |
296 | {QStringLiteral("multi_key" ), 172}, |
297 | {QStringLiteral("codeinput" ), 173}, |
298 | {QStringLiteral("singlecandidate" ), 174}, |
299 | {QStringLiteral("multiplecandidate" ), 175}, |
300 | {QStringLiteral("previouscandidate" ), 176}, |
301 | {QStringLiteral("mode_switch" ), 177}, |
302 | {QStringLiteral("kanji" ), 178}, |
303 | {QStringLiteral("muhenkan" ), 179}, |
304 | {QStringLiteral("henkan" ), 180}, |
305 | {QStringLiteral("romaji" ), 181}, |
306 | {QStringLiteral("hiragana" ), 182}, |
307 | {QStringLiteral("katakana" ), 183}, |
308 | {QStringLiteral("hiragana_katakana" ), 184}, |
309 | {QStringLiteral("zenkaku" ), 185}, |
310 | {QStringLiteral("hankaku" ), 186}, |
311 | {QStringLiteral("zenkaku_hankaku" ), 187}, |
312 | {QStringLiteral("touroku" ), 188}, |
313 | {QStringLiteral("massyo" ), 189}, |
314 | {QStringLiteral("kana_lock" ), 190}, |
315 | {QStringLiteral("kana_shift" ), 191}, |
316 | {QStringLiteral("eisu_shift" ), 192}, |
317 | {QStringLiteral("eisu_toggle" ), 193}, |
318 | {QStringLiteral("hangul" ), 194}, |
319 | {QStringLiteral("hangul_start" ), 195}, |
320 | {QStringLiteral("hangul_end" ), 196}, |
321 | {QStringLiteral("hangul_hanja" ), 197}, |
322 | {QStringLiteral("hangul_jamo" ), 198}, |
323 | {QStringLiteral("hangul_romaja" ), 199}, |
324 | {QStringLiteral("hangul_jeonja" ), 200}, |
325 | {QStringLiteral("hangul_banja" ), 201}, |
326 | {QStringLiteral("hangul_prehanja" ), 202}, |
327 | {QStringLiteral("hangul_posthanja" ), 203}, |
328 | {QStringLiteral("hangul_special" ), 204}, |
329 | {QStringLiteral("dead_grave" ), 205}, |
330 | {QStringLiteral("dead_acute" ), 206}, |
331 | {QStringLiteral("dead_circumflex" ), 207}, |
332 | {QStringLiteral("dead_tilde" ), 208}, |
333 | {QStringLiteral("dead_macron" ), 209}, |
334 | {QStringLiteral("dead_breve" ), 210}, |
335 | {QStringLiteral("dead_abovedot" ), 211}, |
336 | {QStringLiteral("dead_diaeresis" ), 212}, |
337 | {QStringLiteral("dead_abovering" ), 213}, |
338 | {QStringLiteral("dead_doubleacute" ), 214}, |
339 | {QStringLiteral("dead_caron" ), 215}, |
340 | {QStringLiteral("dead_cedilla" ), 216}, |
341 | {QStringLiteral("dead_ogonek" ), 217}, |
342 | {QStringLiteral("dead_iota" ), 218}, |
343 | {QStringLiteral("dead_voiced_sound" ), 219}, |
344 | {QStringLiteral("dead_semivoiced_sound" ), 220}, |
345 | {QStringLiteral("dead_belowdot" ), 221}, |
346 | {QStringLiteral("dead_hook" ), 222}, |
347 | {QStringLiteral("dead_horn" ), 223}, |
348 | {QStringLiteral("back" ), 224}, |
349 | {QStringLiteral("forward" ), 225}, |
350 | {QStringLiteral("stop" ), 226}, |
351 | {QStringLiteral("refresh" ), 227}, |
352 | {QStringLiteral("volumedown" ), 228}, |
353 | {QStringLiteral("volumemute" ), 229}, |
354 | {QStringLiteral("volumeup" ), 230}, |
355 | {QStringLiteral("bassboost" ), 231}, |
356 | {QStringLiteral("bassup" ), 232}, |
357 | {QStringLiteral("bassdown" ), 233}, |
358 | {QStringLiteral("trebleup" ), 234}, |
359 | {QStringLiteral("trebledown" ), 235}, |
360 | {QStringLiteral("mediaplay" ), 236}, |
361 | {QStringLiteral("mediastop" ), 237}, |
362 | {QStringLiteral("mediaprevious" ), 238}, |
363 | {QStringLiteral("medianext" ), 239}, |
364 | {QStringLiteral("mediarecord" ), 240}, |
365 | {QStringLiteral("homepage" ), 241}, |
366 | {QStringLiteral("favorites" ), 242}, |
367 | {QStringLiteral("search" ), 243}, |
368 | {QStringLiteral("standby" ), 244}, |
369 | {QStringLiteral("openurl" ), 245}, |
370 | {QStringLiteral("launchmail" ), 246}, |
371 | {QStringLiteral("launchmedia" ), 247}, |
372 | {QStringLiteral("launch0" ), 248}, |
373 | {QStringLiteral("launch1" ), 249}, |
374 | {QStringLiteral("launch2" ), 250}, |
375 | {QStringLiteral("launch3" ), 251}, |
376 | {QStringLiteral("launch4" ), 252}, |
377 | {QStringLiteral("launch5" ), 253}, |
378 | {QStringLiteral("launch6" ), 254}, |
379 | {QStringLiteral("launch7" ), 255}, |
380 | {QStringLiteral("launch8" ), 256}, |
381 | {QStringLiteral("launch9" ), 257}, |
382 | {QStringLiteral("launcha" ), 258}, |
383 | {QStringLiteral("launchb" ), 259}, |
384 | {QStringLiteral("launchc" ), 260}, |
385 | {QStringLiteral("launchd" ), 261}, |
386 | {QStringLiteral("launche" ), 262}, |
387 | {QStringLiteral("launchf" ), 263}, |
388 | {QStringLiteral("medialast" ), 264}, |
389 | {QStringLiteral("unknown" ), 265}, |
390 | {QStringLiteral("call" ), 266}, |
391 | {QStringLiteral("context1" ), 267}, |
392 | {QStringLiteral("context2" ), 268}, |
393 | {QStringLiteral("context3" ), 269}, |
394 | {QStringLiteral("context4" ), 270}, |
395 | {QStringLiteral("flip" ), 271}, |
396 | {QStringLiteral("hangup" ), 272}, |
397 | {QStringLiteral("no" ), 273}, |
398 | {QStringLiteral("select" ), 274}, |
399 | {QStringLiteral("yes" ), 275}, |
400 | {QStringLiteral("execute" ), 276}, |
401 | {QStringLiteral("printer" ), 277}, |
402 | {QStringLiteral("play" ), 278}, |
403 | {QStringLiteral("sleep" ), 279}, |
404 | {QStringLiteral("zoom" ), 280}, |
405 | {QStringLiteral("cancel" ), 281}, |
406 | |
407 | {QStringLiteral("a" ), 282}, |
408 | {QStringLiteral("b" ), 283}, |
409 | {QStringLiteral("c" ), 284}, |
410 | {QStringLiteral("d" ), 285}, |
411 | {QStringLiteral("e" ), 286}, |
412 | {QStringLiteral("f" ), 287}, |
413 | {QStringLiteral("g" ), 288}, |
414 | {QStringLiteral("h" ), 289}, |
415 | {QStringLiteral("i" ), 290}, |
416 | {QStringLiteral("j" ), 291}, |
417 | {QStringLiteral("k" ), 292}, |
418 | {QStringLiteral("l" ), 293}, |
419 | {QStringLiteral("m" ), 294}, |
420 | {QStringLiteral("n" ), 295}, |
421 | {QStringLiteral("o" ), 296}, |
422 | {QStringLiteral("p" ), 297}, |
423 | {QStringLiteral("q" ), 298}, |
424 | {QStringLiteral("r" ), 299}, |
425 | {QStringLiteral("s" ), 300}, |
426 | {QStringLiteral("t" ), 301}, |
427 | {QStringLiteral("u" ), 302}, |
428 | {QStringLiteral("v" ), 303}, |
429 | {QStringLiteral("w" ), 304}, |
430 | {QStringLiteral("x" ), 305}, |
431 | {QStringLiteral("y" ), 306}, |
432 | {QStringLiteral("z" ), 307}, |
433 | {QStringLiteral("`" ), 308}, |
434 | {QStringLiteral("!" ), 309}, |
435 | {QStringLiteral("\"" ), 310}, |
436 | {QStringLiteral("$" ), 311}, |
437 | {QStringLiteral("%" ), 312}, |
438 | {QStringLiteral("^" ), 313}, |
439 | {QStringLiteral("&" ), 314}, |
440 | {QStringLiteral("*" ), 315}, |
441 | {QStringLiteral("(" ), 316}, |
442 | {QStringLiteral(")" ), 317}, |
443 | {QStringLiteral("-" ), 318}, |
444 | {QStringLiteral("_" ), 319}, |
445 | {QStringLiteral("=" ), 320}, |
446 | {QStringLiteral("+" ), 321}, |
447 | {QStringLiteral("[" ), 322}, |
448 | {QStringLiteral("]" ), 323}, |
449 | {QStringLiteral("{" ), 324}, |
450 | {QStringLiteral("}" ), 325}, |
451 | {QStringLiteral(":" ), 326}, |
452 | {QStringLiteral(";" ), 327}, |
453 | {QStringLiteral("@" ), 328}, |
454 | {QStringLiteral("'" ), 329}, |
455 | {QStringLiteral("#" ), 330}, |
456 | {QStringLiteral("~" ), 331}, |
457 | {QStringLiteral("\\" ), 332}, |
458 | {QStringLiteral("|" ), 333}, |
459 | {QStringLiteral("," ), 334}, |
460 | {QStringLiteral("." ), 335}, |
461 | // { QLatin1String( ">" ), 336 }, |
462 | {QStringLiteral("/" ), 337}, |
463 | {QStringLiteral("?" ), 338}, |
464 | {QStringLiteral(" " ), 339}, |
465 | // { QLatin1String( "<" ), 341 }, |
466 | {QStringLiteral("0" ), 340}, |
467 | {QStringLiteral("1" ), 341}, |
468 | {QStringLiteral("2" ), 342}, |
469 | {QStringLiteral("3" ), 343}, |
470 | {QStringLiteral("4" ), 344}, |
471 | {QStringLiteral("5" ), 345}, |
472 | {QStringLiteral("6" ), 346}, |
473 | {QStringLiteral("7" ), 347}, |
474 | {QStringLiteral("8" ), 348}, |
475 | {QStringLiteral("9" ), 349}, |
476 | {QStringLiteral("cr" ), 350}, |
477 | {QStringLiteral("leader" ), 351}, |
478 | {QStringLiteral("nop" ), 352}, |
479 | }; |
480 | |
481 | for (QHash<QString, int>::const_iterator i = m_nameToKeyCode.constBegin(); i != m_nameToKeyCode.constEnd(); ++i) { |
482 | m_keyCodeToName.insert(key: i.value(), value: i.key()); |
483 | } |
484 | } |
485 | |
486 | QString KeyParser::qt2vi(int key) const |
487 | { |
488 | auto it = m_qt2katevi.constFind(key); |
489 | if (it != m_qt2katevi.cend()) { |
490 | return it.value(); |
491 | } |
492 | return QStringLiteral("invalid" ); |
493 | } |
494 | |
495 | int KeyParser::vi2qt(const QString &keypress) const |
496 | { |
497 | auto it = m_katevi2qt.constFind(key: keypress); |
498 | if (it != m_katevi2qt.cend()) { |
499 | return it.value(); |
500 | } |
501 | return -1; |
502 | } |
503 | |
504 | int KeyParser::encoded2qt(const QString &keypress) const |
505 | { |
506 | QString key = KeyParser::self()->decodeKeySequence(keys: keypress); |
507 | |
508 | if (key.length() > 2 && key.at(i: 0) == QLatin1Char('<') && key.at(i: key.length() - 1) == QLatin1Char('>')) { |
509 | key = key.mid(position: 1, n: key.length() - 2); |
510 | } |
511 | auto it = m_katevi2qt.constFind(key); |
512 | if (it != m_katevi2qt.cend()) |
513 | return it.value(); |
514 | return -1; |
515 | } |
516 | |
517 | const QString KeyParser::encodeKeySequence(const QString &keys) const |
518 | { |
519 | QString encodedSequence; |
520 | unsigned int keyCodeTemp = 0; |
521 | |
522 | const QStringView keysView(keys); |
523 | bool insideTag = false; |
524 | QChar c; |
525 | for (int i = 0; i < keys.length(); i++) { |
526 | c = keys.at(i); |
527 | if (insideTag) { |
528 | if (c == QLatin1Char('>')) { |
529 | QChar code(0xE000 + keyCodeTemp); |
530 | encodedSequence.append(c: code); |
531 | keyCodeTemp = 0; |
532 | insideTag = false; |
533 | continue; |
534 | } else { |
535 | // contains modifiers |
536 | if (keysView.mid(pos: i).indexOf(c: QLatin1Char('-')) != -1 && keysView.mid(pos: i).indexOf(c: QLatin1Char('-')) < keysView.mid(pos: i).indexOf(c: QLatin1Char('>'))) { |
537 | // Perform something similar to a split on '-', except that we want to keep the occurrences of '-' |
538 | // e.g. <c-s-a> will equate to the list of tokens "c-", "s-", "a". |
539 | // A straight split on '-' would give us "c", "s", "a", in which case we lose the piece of information that |
540 | // 'a' is just the 'a' key, not the 'alt' modifier. |
541 | const QString untilClosing = keys.mid(position: i, n: keysView.mid(pos: i).indexOf(c: QLatin1Char('>'))).toLower(); |
542 | QStringList tokens; |
543 | int currentPos = 0; |
544 | int nextHypen = -1; |
545 | while ((nextHypen = untilClosing.indexOf(c: QLatin1Char('-'), from: currentPos)) != -1) { |
546 | tokens << untilClosing.mid(position: currentPos, n: nextHypen - currentPos + 1); |
547 | currentPos = nextHypen + 1; |
548 | } |
549 | tokens << untilClosing.mid(position: currentPos); |
550 | |
551 | for (const QString &str : std::as_const(t&: tokens)) { |
552 | if (str == QLatin1String("s-" ) && (keyCodeTemp & 0x01) != 0x1) { |
553 | keyCodeTemp += 0x1; |
554 | } else if (str == QLatin1String("c-" ) && (keyCodeTemp & 0x02) != 0x2) { |
555 | keyCodeTemp += 0x2; |
556 | } else if (str == QLatin1String("a-" ) && (keyCodeTemp & 0x04) != 0x4) { |
557 | keyCodeTemp += 0x4; |
558 | } else if (str == QLatin1String("m-" ) && (keyCodeTemp & 0x08) != 0x8) { |
559 | keyCodeTemp += 0x8; |
560 | } else { |
561 | if (m_nameToKeyCode.contains(key: str) || (str.length() == 1 && str.at(i: 0).isLetterOrNumber())) { |
562 | if (m_nameToKeyCode.contains(key: str)) { |
563 | keyCodeTemp += m_nameToKeyCode.value(key: str) * 0x10; |
564 | } else { |
565 | keyCodeTemp += str.at(i: 0).unicode() * 0x10; |
566 | } |
567 | } else { |
568 | int endOfBlock = keys.indexOf(c: QLatin1Char('>')); |
569 | if (endOfBlock -= -1) { |
570 | endOfBlock = keys.length() - 1; |
571 | } |
572 | encodedSequence.clear(); |
573 | encodedSequence.append(v: QChar::fromUcs4(c: m_nameToKeyCode.value(QStringLiteral("invalid" )))); |
574 | break; |
575 | } |
576 | } |
577 | } |
578 | } else { |
579 | const QString str = keys.mid(position: i, n: keys.indexOf(c: QLatin1Char('>'), from: i) - i).toLower(); |
580 | if (keys.indexOf(c: QLatin1Char('>'), from: i) != -1 && (m_nameToKeyCode.contains(key: str) || (str.length() == 1 && str.at(i: 0).isLetterOrNumber()))) { |
581 | if (m_nameToKeyCode.contains(key: str)) { |
582 | keyCodeTemp += m_nameToKeyCode.value(key: str) * 0x10; |
583 | } else { |
584 | keyCodeTemp += str.at(i: 0).unicode() * 0x10; |
585 | } |
586 | } else { |
587 | int endOfBlock = keys.indexOf(c: QLatin1Char('>')); |
588 | if (endOfBlock -= -1) { |
589 | endOfBlock = keys.length() - 1; |
590 | } |
591 | encodedSequence.clear(); |
592 | keyCodeTemp = m_nameToKeyCode.value(QStringLiteral("invalid" )) * 0x10; |
593 | } |
594 | } |
595 | i += keysView.mid(pos: i, n: keysView.mid(pos: i).indexOf(c: QLatin1Char('>'))).length() - 1; |
596 | } |
597 | } else { |
598 | if (c == QLatin1Char('<')) { |
599 | // If there's no closing '>', or if there is an opening '<' before the next '>', interpret as a literal '<' |
600 | // If we are <space>, encode as a literal " ". |
601 | const QStringView rest = keysView.mid(pos: i); |
602 | if (rest.indexOf(c: QLatin1Char('>'), from: 1) != -1 && rest.mid(pos: 1, n: rest.indexOf(c: QLatin1Char('>'), from: 1) - 1) == QLatin1String("space" )) { |
603 | encodedSequence.append(c: QLatin1Char(' ')); |
604 | i += rest.indexOf(c: QLatin1Char('>'), from: 1); |
605 | continue; |
606 | } else if (rest.indexOf(c: QLatin1Char('>'), from: 1) == -1 |
607 | || (rest.indexOf(c: QLatin1Char('<'), from: 1) < rest.indexOf(c: QLatin1Char('>'), from: 1) && rest.indexOf(c: QLatin1Char('<'), from: 1) != -1)) { |
608 | encodedSequence.append(c); |
609 | continue; |
610 | } |
611 | insideTag = true; |
612 | continue; |
613 | } else { |
614 | encodedSequence.append(c); |
615 | } |
616 | } |
617 | } |
618 | |
619 | return encodedSequence; |
620 | } |
621 | |
622 | const QString KeyParser::decodeKeySequence(const QString &keys) const |
623 | { |
624 | QString ret; |
625 | ret.reserve(asize: keys.length()); |
626 | |
627 | for (int i = 0; i < keys.length(); i++) { |
628 | QChar c = keys.at(i); |
629 | int keycode = c.unicode(); |
630 | |
631 | if ((keycode & 0xE000) != 0xE000) { |
632 | ret.append(c); |
633 | } else { |
634 | ret.append(c: QLatin1Char('<')); |
635 | |
636 | if ((keycode & 0x1) == 0x1) { |
637 | ret.append(s: QLatin1String("s-" )); |
638 | // keycode -= 0x1; |
639 | } |
640 | if ((keycode & 0x2) == 0x2) { |
641 | ret.append(s: QLatin1String("c-" )); |
642 | // keycode -= 0x2; |
643 | } |
644 | if ((keycode & 0x4) == 0x4) { |
645 | ret.append(s: QLatin1String("a-" )); |
646 | // keycode -= 0x4; |
647 | } |
648 | if ((keycode & 0x8) == 0x8) { |
649 | ret.append(s: QLatin1String("m-" )); |
650 | // keycode -= 0x8; |
651 | } |
652 | |
653 | if ((keycode & 0xE000) == 0xE000) { |
654 | ret.append(s: m_keyCodeToName.value(key: (keycode - 0xE000) / 0x10)); |
655 | } else { |
656 | ret.append(v: QChar::fromUcs4(c: keycode)); |
657 | } |
658 | ret.append(c: QLatin1Char('>')); |
659 | } |
660 | } |
661 | |
662 | return ret; |
663 | } |
664 | |
665 | const QChar KeyParser::KeyEventToQChar(const QKeyEvent &keyEvent) |
666 | { |
667 | return KeyEventToQChar(keyCode: keyEvent.key(), text: keyEvent.text(), mods: keyEvent.modifiers()); |
668 | } |
669 | |
670 | const QChar KeyParser::KeyEventToQChar(const KeyEvent &keyEvent) |
671 | { |
672 | return KeyEventToQChar(keyCode: keyEvent.key(), text: keyEvent.text(), mods: keyEvent.modifiers()); |
673 | } |
674 | |
675 | const QChar KeyParser::KeyEventToQChar(int keyCode, const QString &text, Qt::KeyboardModifiers mods) const |
676 | { |
677 | // If previous key press was AltGr, return key value right away and don't go |
678 | // down the "handle modifiers" code path. AltGr is really confusing... |
679 | if (mods & Qt::GroupSwitchModifier) { |
680 | return (!text.isEmpty()) ? text.at(i: 0) : QChar(); |
681 | } |
682 | |
683 | if (text.isEmpty() || (text.length() == 1 && text.at(i: 0) < QChar(0x20)) || keyCode == Qt::Key_Delete |
684 | || (mods != Qt::NoModifier && mods != Qt::ShiftModifier && mods != Qt::KeypadModifier)) { |
685 | QString keyPress; |
686 | keyPress.reserve(asize: 11); |
687 | |
688 | keyPress.append(c: QLatin1Char('<')); |
689 | keyPress.append(s: (mods & Qt::ShiftModifier) ? QStringLiteral("s-" ) : QString()); |
690 | keyPress.append(s: (mods & CONTROL_MODIFIER) ? QStringLiteral("c-" ) : QString()); |
691 | keyPress.append(s: (mods & Qt::AltModifier) ? QStringLiteral("a-" ) : QString()); |
692 | keyPress.append(s: (mods & META_MODIFIER) ? QStringLiteral("m-" ) : QString()); |
693 | keyPress.append(s: keyCode <= 0xFF ? QChar(keyCode) : qt2vi(key: keyCode)); |
694 | keyPress.append(c: QLatin1Char('>')); |
695 | |
696 | return encodeKeySequence(keys: keyPress).at(i: 0); |
697 | } else { |
698 | return text.at(i: 0); |
699 | } |
700 | } |
701 | |