| 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(ch: 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(ch: 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(ch: QLatin1Char('>'), from: i) - i).toLower(); |
| 580 | if (keys.indexOf(ch: 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(ch: 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 | |