2 * \file qt/GuiKeySymbol.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Asger & Jürgen
8 * Full author contact details are available in file CREDITS.
13 #include "GuiKeySymbol.h"
14 #if defined(Q_OS_MAC) && QT_VERSION > 0x050000
15 #include "GuiApplication.h"
17 #include "qt_helpers.h"
19 #include "support/lassert.h"
20 #include "support/debug.h"
26 #include <QKeySequence>
39 * Return true if the key event is a modifier.
41 static bool isModifier(int qkey)
60 * Return the numeric Qt Key corresponding to the
63 static int string_to_qkey(std::string const & str)
67 if (str == "Escape") return Qt::Key_Escape;
68 if (str == "Tab") return Qt::Key_Tab;
69 if (str == "ISO_Left_Tab") return Qt::Key_Backtab;
70 if (str == "BackSpace") return Qt::Key_Backspace;
71 if (str == "Return") return Qt::Key_Return;
72 if (str == "KP_Enter") return Qt::Key_Enter; // correct ?
73 if (str == "Insert") return Qt::Key_Insert;
74 if (str == "KP_Insert") return Qt::Key_Insert;
75 if (str == "Delete") return Qt::Key_Delete;
76 if (str == "KP_Delete") return Qt::Key_Delete;
77 if (str == "Pause") return Qt::Key_Pause;
78 if (str == "Print") return Qt::Key_Print;
79 if (str == "Sys_Req") return Qt::Key_SysReq;
80 if (str == "Home") return Qt::Key_Home;
81 if (str == "End") return Qt::Key_End;
82 if (str == "Left") return Qt::Key_Left;
83 if (str == "Up") return Qt::Key_Up;
84 if (str == "Right") return Qt::Key_Right;
85 if (str == "Down") return Qt::Key_Down;
86 if (str == "Prior") return Qt::Key_PageUp;
87 if (str == "Next") return Qt::Key_PageDown;
88 if (str == "KP_Home") return Qt::Key_Home;
89 if (str == "KP_End") return Qt::Key_End;
90 if (str == "KP_Left") return Qt::Key_Left;
91 if (str == "KP_Up") return Qt::Key_Up;
92 if (str == "KP_Right") return Qt::Key_Right;
93 if (str == "KP_Down") return Qt::Key_Down;
94 if (str == "KP_Prior") return Qt::Key_PageUp;
95 if (str == "KP_Next") return Qt::Key_PageDown;
96 if (str == "Shift_L") return Qt::Key_Shift;
97 if (str == "Control_L") return Qt::Key_Control;
98 if (str == "Alt_L") return Qt::Key_Meta; // correct ?
99 if (str == "Alt_R") return Qt::Key_Alt;
100 if (str == "Caps_Lock") return Qt::Key_CapsLock;
101 if (str == "Num_Lock") return Qt::Key_NumLock;
102 if (str == "Scroll_Lock") return Qt::Key_ScrollLock;
103 if (str == "F1") return Qt::Key_F1;
104 if (str == "F2") return Qt::Key_F2;
105 if (str == "F3") return Qt::Key_F3;
106 if (str == "F4") return Qt::Key_F4;
107 if (str == "F5") return Qt::Key_F5;
108 if (str == "F6") return Qt::Key_F6;
109 if (str == "F7") return Qt::Key_F7;
110 if (str == "F8") return Qt::Key_F8;
111 if (str == "F9") return Qt::Key_F9;
112 if (str == "F10") return Qt::Key_F10;
113 if (str == "F11") return Qt::Key_F11;
114 if (str == "F12") return Qt::Key_F12;
115 if (str == "F13") return Qt::Key_F13;
116 if (str == "F14") return Qt::Key_F14;
117 if (str == "F15") return Qt::Key_F15;
118 if (str == "F16") return Qt::Key_F16;
119 if (str == "F17") return Qt::Key_F17;
120 if (str == "F18") return Qt::Key_F18;
121 if (str == "F19") return Qt::Key_F19;
122 if (str == "F20") return Qt::Key_F20;
123 if (str == "F21") return Qt::Key_F21;
124 if (str == "F22") return Qt::Key_F22;
125 if (str == "F23") return Qt::Key_F23;
126 if (str == "F24") return Qt::Key_F24;
127 if (str == "F25") return Qt::Key_F25;
128 if (str == "F26") return Qt::Key_F26;
129 if (str == "F27") return Qt::Key_F27;
130 if (str == "F28") return Qt::Key_F28;
131 if (str == "F29") return Qt::Key_F29;
132 if (str == "F30") return Qt::Key_F30;
133 if (str == "F31") return Qt::Key_F31;
134 if (str == "F32") return Qt::Key_F32;
135 if (str == "F33") return Qt::Key_F33;
136 if (str == "F34") return Qt::Key_F34;
137 if (str == "F35") return Qt::Key_F35;
138 if (str == "0") return Qt::Key_0;
139 if (str == "1") return Qt::Key_1;
140 if (str == "2") return Qt::Key_2;
141 if (str == "3") return Qt::Key_3;
142 if (str == "4") return Qt::Key_4;
143 if (str == "5") return Qt::Key_5;
144 if (str == "6") return Qt::Key_6;
145 if (str == "7") return Qt::Key_7;
146 if (str == "8") return Qt::Key_8;
147 if (str == "9") return Qt::Key_9;
148 if (str == "KP_0") return Qt::Key_0;
149 if (str == "KP_1") return Qt::Key_1;
150 if (str == "KP_2") return Qt::Key_2;
151 if (str == "KP_3") return Qt::Key_3;
152 if (str == "KP_4") return Qt::Key_4;
153 if (str == "KP_5") return Qt::Key_5;
154 if (str == "KP_6") return Qt::Key_6;
155 if (str == "KP_7") return Qt::Key_7;
156 if (str == "KP_8") return Qt::Key_8;
157 if (str == "KP_9") return Qt::Key_9;
158 if (str == "colon") return Qt::Key_Colon;
159 if (str == "semicolon") return Qt::Key_Semicolon;
160 if (str == "less") return Qt::Key_Less;
161 if (str == "equal") return Qt::Key_Equal;
162 if (str == "greater") return Qt::Key_Greater;
163 if (str == "question") return Qt::Key_Question;
164 if (str == "at") return Qt::Key_At;
165 if (str == "A") return Qt::Key_A;
166 if (str == "B") return Qt::Key_B;
167 if (str == "C") return Qt::Key_C;
168 if (str == "D") return Qt::Key_D;
169 if (str == "E") return Qt::Key_E;
170 if (str == "F") return Qt::Key_F;
171 if (str == "G") return Qt::Key_G;
172 if (str == "H") return Qt::Key_H;
173 if (str == "I") return Qt::Key_I;
174 if (str == "J") return Qt::Key_J;
175 if (str == "K") return Qt::Key_K;
176 if (str == "L") return Qt::Key_L;
177 if (str == "M") return Qt::Key_M;
178 if (str == "N") return Qt::Key_N;
179 if (str == "O") return Qt::Key_O;
180 if (str == "P") return Qt::Key_P;
181 if (str == "Q") return Qt::Key_Q;
182 if (str == "R") return Qt::Key_R;
183 if (str == "S") return Qt::Key_S;
184 if (str == "T") return Qt::Key_T;
185 if (str == "U") return Qt::Key_U;
186 if (str == "V") return Qt::Key_V;
187 if (str == "W") return Qt::Key_W;
188 if (str == "X") return Qt::Key_X;
189 if (str == "Y") return Qt::Key_Y;
190 if (str == "Z") return Qt::Key_Z;
191 if (str == "a") return Qt::Key_A;
192 if (str == "b") return Qt::Key_B;
193 if (str == "c") return Qt::Key_C;
194 if (str == "d") return Qt::Key_D;
195 if (str == "e") return Qt::Key_E;
196 if (str == "f") return Qt::Key_F;
197 if (str == "g") return Qt::Key_G;
198 if (str == "h") return Qt::Key_H;
199 if (str == "i") return Qt::Key_I;
200 if (str == "j") return Qt::Key_J;
201 if (str == "k") return Qt::Key_K;
202 if (str == "l") return Qt::Key_L;
203 if (str == "m") return Qt::Key_M;
204 if (str == "n") return Qt::Key_N;
205 if (str == "o") return Qt::Key_O;
206 if (str == "p") return Qt::Key_P;
207 if (str == "q") return Qt::Key_Q;
208 if (str == "r") return Qt::Key_R;
209 if (str == "s") return Qt::Key_S;
210 if (str == "t") return Qt::Key_T;
211 if (str == "u") return Qt::Key_U;
212 if (str == "v") return Qt::Key_V;
213 if (str == "w") return Qt::Key_W;
214 if (str == "x") return Qt::Key_X;
215 if (str == "y") return Qt::Key_Y;
216 if (str == "z") return Qt::Key_Z;
217 if (str == "bracketleft") return Qt::Key_BracketLeft;
218 if (str == "backslash") return Qt::Key_Backslash;
219 if (str == "bracketright") return Qt::Key_BracketRight;
220 if (str == "bar") return Qt::Key_Bar;
221 if (str == "underscore") return Qt::Key_Underscore;
222 if (str == "space") return Qt::Key_Space;
223 if (str == "parenleft") return Qt::Key_ParenLeft;
224 if (str == "parenright") return Qt::Key_ParenRight;
225 if (str == "quotedbl") return Qt::Key_QuoteDbl;
226 if (str == "quoteright") return Qt::Key_Apostrophe;
227 if (str == "quoteleft") return Qt::Key_QuoteLeft;
228 if (str == "exclam") return Qt::Key_Exclam;
229 if (str == "numbersign") return Qt::Key_NumberSign;
230 if (str == "asciicircum") return Qt::Key_AsciiCircum;
231 if (str == "dollar") return Qt::Key_Dollar;
232 if (str == "percent") return Qt::Key_Percent;
233 if (str == "ampersand") return Qt::Key_Ampersand;
234 if (str == "asterisk") return Qt::Key_Asterisk;
235 if (str == "KP_Multiply") return Qt::Key_Asterisk;
236 if (str == "apostrophe") return Qt::Key_Apostrophe;
237 if (str == "plus") return Qt::Key_Plus;
238 if (str == "KP_Add") return Qt::Key_Plus;
239 if (str == "minus") return Qt::Key_Minus;
240 if (str == "KP_Subtract") return Qt::Key_Minus;
241 if (str == "comma") return Qt::Key_Comma;
242 if (str == "period") return Qt::Key_Period;
243 if (str == "KP_Decimal") return Qt::Key_Period;
244 if (str == "slash") return Qt::Key_Slash;
245 if (str == "KP_Divide") return Qt::Key_Slash;
246 if (str == "asciitilde") return Qt::Key_AsciiTilde;
247 if (str == "braceleft") return Qt::Key_BraceLeft;
248 if (str == "braceright") return Qt::Key_BraceRight;
249 if (str == "grave") return Qt::Key_QuoteLeft; // ???
250 if (str == "notsign") return Qt::Key_notsign;
251 if (str == "nobreakspace") return Qt::Key_nobreakspace;
252 if (str == "exclamdown") return Qt::Key_exclamdown;
253 if (str == "cent") return Qt::Key_cent;
254 if (str == "sterling") return Qt::Key_sterling;
255 if (str == "currency") return Qt::Key_currency;
256 if (str == "yen") return Qt::Key_yen;
257 if (str == "brokenbar") return Qt::Key_brokenbar;
258 if (str == "section") return Qt::Key_section;
259 if (str == "diaeresis") return Qt::Key_diaeresis;
260 if (str == "copyright") return Qt::Key_copyright;
261 if (str == "ordfeminine") return Qt::Key_ordfeminine;
262 if (str == "guillemotleft") return Qt::Key_guillemotleft;
263 if (str == "hyphen") return Qt::Key_hyphen;
264 if (str == "registered") return Qt::Key_registered;
265 if (str == "macron") return Qt::Key_macron;
266 if (str == "degree") return Qt::Key_degree;
267 if (str == "plusminus") return Qt::Key_plusminus;
268 if (str == "twosuperior") return Qt::Key_twosuperior;
269 if (str == "threesuperior") return Qt::Key_threesuperior;
270 if (str == "acute") return Qt::Key_acute;
271 if (str == "mu") return Qt::Key_mu;
272 if (str == "paragraph") return Qt::Key_paragraph;
273 if (str == "periodcentered") return Qt::Key_periodcentered;
274 if (str == "cedilla") return Qt::Key_cedilla;
275 if (str == "onesuperior") return Qt::Key_onesuperior;
276 if (str == "masculine") return Qt::Key_masculine;
277 if (str == "guillemotright") return Qt::Key_guillemotright;
278 if (str == "onequarter") return Qt::Key_onequarter;
279 if (str == "onehalf") return Qt::Key_onehalf;
280 if (str == "threequarters") return Qt::Key_threequarters;
281 if (str == "questiondown") return Qt::Key_questiondown;
282 if (str == "Agrave") return Qt::Key_Agrave;
283 if (str == "Aacute") return Qt::Key_Aacute;
284 if (str == "Acircumflex") return Qt::Key_Acircumflex;
285 if (str == "Atilde") return Qt::Key_Atilde;
286 if (str == "Adiaeresis") return Qt::Key_Adiaeresis;
287 if (str == "Aring") return Qt::Key_Aring;
288 if (str == "AE") return Qt::Key_AE;
289 if (str == "Ccedilla") return Qt::Key_Ccedilla;
290 if (str == "Egrave") return Qt::Key_Egrave;
291 if (str == "Eacute") return Qt::Key_Eacute;
292 if (str == "Ecircumflex") return Qt::Key_Ecircumflex;
293 if (str == "Ediaeresis") return Qt::Key_Ediaeresis;
294 if (str == "Igrave") return Qt::Key_Igrave;
295 if (str == "Iacute") return Qt::Key_Iacute;
296 if (str == "Icircumflex") return Qt::Key_Icircumflex;
297 if (str == "Idiaeresis") return Qt::Key_Idiaeresis;
298 if (str == "ETH") return Qt::Key_ETH;
299 if (str == "Ntilde") return Qt::Key_Ntilde;
300 if (str == "Ograve") return Qt::Key_Ograve;
301 if (str == "Oacute") return Qt::Key_Oacute;
302 if (str == "Ocircumflex") return Qt::Key_Ocircumflex;
303 if (str == "Otilde") return Qt::Key_Otilde;
304 if (str == "Odiaeresis") return Qt::Key_Odiaeresis;
305 if (str == "multiply") return Qt::Key_multiply;
306 if (str == "Ooblique") return Qt::Key_Ooblique;
307 if (str == "Ugrave") return Qt::Key_Ugrave;
308 if (str == "Uacute") return Qt::Key_Uacute;
309 if (str == "Ucircumflex") return Qt::Key_Ucircumflex;
310 if (str == "Udiaeresis") return Qt::Key_Udiaeresis;
311 if (str == "Yacute") return Qt::Key_Yacute;
312 if (str == "THORN") return Qt::Key_THORN;
313 if (str == "ssharp") return Qt::Key_ssharp;
314 if (str == "agrave") return Qt::Key_Agrave;
315 if (str == "aacute") return Qt::Key_Aacute;
316 if (str == "acircumflex") return Qt::Key_Acircumflex;
317 if (str == "atilde") return Qt::Key_Atilde;
318 if (str == "adiaeresis") return Qt::Key_Adiaeresis;
319 if (str == "aring") return Qt::Key_Aring;
320 if (str == "ae") return Qt::Key_AE;
321 if (str == "ccedilla") return Qt::Key_Ccedilla;
322 if (str == "egrave") return Qt::Key_Egrave;
323 if (str == "eacute") return Qt::Key_Eacute;
324 if (str == "ecircumflex") return Qt::Key_Ecircumflex;
325 if (str == "ediaeresis") return Qt::Key_Ediaeresis;
326 if (str == "igrave") return Qt::Key_Igrave;
327 if (str == "iacute") return Qt::Key_Iacute;
328 if (str == "icircumflex") return Qt::Key_Icircumflex;
329 if (str == "idiaeresis") return Qt::Key_Idiaeresis;
330 if (str == "eth") return Qt::Key_ETH;
331 if (str == "ntilde") return Qt::Key_Ntilde;
332 if (str == "ograve") return Qt::Key_Ograve;
333 if (str == "oacute") return Qt::Key_Oacute;
334 if (str == "ocircumflex") return Qt::Key_Ocircumflex;
335 if (str == "otilde") return Qt::Key_Otilde;
336 if (str == "odiaeresis") return Qt::Key_Odiaeresis;
337 if (str == "division") return Qt::Key_division;
338 if (str == "oslash") return Qt::Key_Ooblique;
339 if (str == "ugrave") return Qt::Key_Ugrave;
340 if (str == "uacute") return Qt::Key_Uacute;
341 if (str == "ucircumflex") return Qt::Key_Ucircumflex;
342 if (str == "udiaeresis") return Qt::Key_Udiaeresis;
343 if (str == "yacute") return Qt::Key_Yacute;
344 if (str == "thorn") return Qt::Key_THORN;
345 if (str == "ydiaeresis") return Qt::Key_ydiaeresis;
346 if (str == "Dead_Caron") return Qt::Key_Dead_Caron;
348 // FIXME, correct for all these ?
349 if (str == "Super_L") return Qt::Key_Super_L;
350 if (str == "Super_R") return Qt::Key_Super_R;
351 if (str == "Menu") return Qt::Key_Menu;
352 if (str == "Hyper_L") return Qt::Key_Hyper_L;
353 if (str == "Hyper_R") return Qt::Key_Hyper_R;
354 if (str == "Help") return Qt::Key_Help;
355 if (str == "BackTab") return Qt::Key_Backtab;
357 // Keyboard codes for Cyrillic letters
358 if (str == "А") return 1040;
359 if (str == "Б") return 1041;
360 if (str == "В") return 1042;
361 if (str == "Г") return 1043;
362 if (str == "Д") return 1044;
363 if (str == "Е") return 1045;
364 if (str == "Є") return 1028;
365 if (str == "Ё") return 1025;
366 if (str == "Ж") return 1046;
367 if (str == "З") return 1047;
368 if (str == "И") return 1048;
369 if (str == "І") return 1030;
370 if (str == "Ї") return 1031;
371 if (str == "Й") return 1049;
372 if (str == "К") return 1050;
373 if (str == "Л") return 1051;
374 if (str == "М") return 1052;
375 if (str == "Н") return 1053;
376 if (str == "О") return 1054;
377 if (str == "П") return 1055;
378 if (str == "Р") return 1056;
379 if (str == "С") return 1057;
380 if (str == "Т") return 1058;
381 if (str == "У") return 1059;
382 if (str == "Ф") return 1060;
383 if (str == "Х") return 1061;
384 if (str == "Ц") return 1062;
385 if (str == "Ч") return 1063;
386 if (str == "Ш") return 1064;
387 if (str == "Щ") return 1065;
388 if (str == "Ъ") return 1066;
389 if (str == "Ы") return 1067;
390 if (str == "Ь") return 1068;
391 if (str == "Э") return 1069;
392 if (str == "Ю") return 1070;
393 if (str == "Я") return 1071;
394 if (str == "а") return 1040;
395 if (str == "б") return 1041;
396 if (str == "в") return 1042;
397 if (str == "г") return 1043;
398 if (str == "д") return 1044;
399 if (str == "е") return 1045;
400 if (str == "є") return 1028;
401 if (str == "ё") return 1025;
402 if (str == "ж") return 1046;
403 if (str == "з") return 1047;
404 if (str == "и") return 1048;
405 if (str == "і") return 1030;
406 if (str == "ї") return 1031;
407 if (str == "й") return 1049;
408 if (str == "к") return 1050;
409 if (str == "л") return 1051;
410 if (str == "м") return 1052;
411 if (str == "н") return 1053;
412 if (str == "о") return 1054;
413 if (str == "п") return 1055;
414 if (str == "р") return 1056;
415 if (str == "с") return 1057;
416 if (str == "т") return 1058;
417 if (str == "у") return 1059;
418 if (str == "ф") return 1060;
419 if (str == "х") return 1061;
420 if (str == "ц") return 1062;
421 if (str == "ч") return 1063;
422 if (str == "ш") return 1064;
423 if (str == "щ") return 1065;
424 if (str == "ъ") return 1066;
425 if (str == "ы") return 1067;
426 if (str == "ь") return 1068;
427 if (str == "э") return 1069;
428 if (str == "ю") return 1070;
429 if (str == "я") return 1071;
431 return Qt::Key_unknown;
436 * qkey_to_string - convert Qt keypress into LyX
438 * Convert the Qt keypress into a string understandable
439 * by the LyX core (same as XKeysymToString).
441 static std::string const qkey_to_string(int lkey)
444 case Qt::Key_0: return "0";
445 case Qt::Key_1: return "1";
446 case Qt::Key_2: return "2";
447 case Qt::Key_3: return "3";
448 case Qt::Key_4: return "4";
449 case Qt::Key_5: return "5";
450 case Qt::Key_6: return "6";
451 case Qt::Key_7: return "7";
452 case Qt::Key_8: return "8";
453 case Qt::Key_9: return "9";
455 case Qt::Key_A: return "a";
456 case Qt::Key_B: return "b";
457 case Qt::Key_C: return "c";
458 case Qt::Key_D: return "d";
459 case Qt::Key_E: return "e";
460 case Qt::Key_F: return "f";
461 case Qt::Key_G: return "g";
462 case Qt::Key_H: return "h";
463 case Qt::Key_I: return "i";
464 case Qt::Key_J: return "j";
465 case Qt::Key_K: return "k";
466 case Qt::Key_L: return "l";
467 case Qt::Key_M: return "m";
468 case Qt::Key_N: return "n";
469 case Qt::Key_O: return "o";
470 case Qt::Key_P: return "p";
471 case Qt::Key_Q: return "q";
472 case Qt::Key_R: return "r";
473 case Qt::Key_S: return "s";
474 case Qt::Key_T: return "t";
475 case Qt::Key_U: return "u";
476 case Qt::Key_V: return "v";
477 case Qt::Key_W: return "w";
478 case Qt::Key_X: return "x";
479 case Qt::Key_Y: return "y";
480 case Qt::Key_Z: return "z";
482 case Qt::Key_Return: return "Return";
483 case Qt::Key_Escape: return "Escape";
484 case Qt::Key_Tab: return "Tab";
485 case Qt::Key_Backspace: return "BackSpace";
486 case Qt::Key_Insert: return "Insert";
487 case Qt::Key_Delete: return "Delete";
488 case Qt::Key_Pause: return "Pause";
489 case Qt::Key_Print: return "Print";
490 case Qt::Key_SysReq: return "Sys_Req";
491 case Qt::Key_Home: return "Home";
492 case Qt::Key_End: return "End";
493 case Qt::Key_Left: return "Left";
494 case Qt::Key_Up: return "Up";
495 case Qt::Key_Right: return "Right";
496 case Qt::Key_Down: return "Down";
497 case Qt::Key_PageUp: return "Prior";
498 case Qt::Key_PageDown: return "Next";
499 case Qt::Key_Shift: return "Shift_L";
500 case Qt::Key_Control: return "Control_L";
501 case Qt::Key_Meta: return "Alt_L"; // correct ?
502 case Qt::Key_Alt: return "Alt_R";
503 case Qt::Key_CapsLock: return "Caps_Lock";
504 case Qt::Key_NumLock: return "Num_Lock";
505 case Qt::Key_ScrollLock: return "Scroll_Lock";
506 case Qt::Key_F1: return "F1";
507 case Qt::Key_F2: return "F2";
508 case Qt::Key_F3: return "F3";
509 case Qt::Key_F4: return "F4";
510 case Qt::Key_F5: return "F5";
511 case Qt::Key_F6: return "F6";
512 case Qt::Key_F7: return "F7";
513 case Qt::Key_F8: return "F8";
514 case Qt::Key_F9: return "F9";
515 case Qt::Key_F10: return "F10";
516 case Qt::Key_F11: return "F11";
517 case Qt::Key_F12: return "F12";
518 case Qt::Key_F13: return "F13";
519 case Qt::Key_F14: return "F14";
520 case Qt::Key_F15: return "F15";
521 case Qt::Key_F16: return "F16";
522 case Qt::Key_F17: return "F17";
523 case Qt::Key_F18: return "F18";
524 case Qt::Key_F19: return "F19";
525 case Qt::Key_F20: return "F20";
526 case Qt::Key_F21: return "F21";
527 case Qt::Key_F22: return "F22";
528 case Qt::Key_F23: return "F23";
529 case Qt::Key_F24: return "F24";
530 case Qt::Key_F25: return "F25";
531 case Qt::Key_F26: return "F26";
532 case Qt::Key_F27: return "F27";
533 case Qt::Key_F28: return "F28";
534 case Qt::Key_F29: return "F29";
535 case Qt::Key_F30: return "F30";
536 case Qt::Key_F31: return "F31";
537 case Qt::Key_F32: return "F32";
538 case Qt::Key_F33: return "F33";
539 case Qt::Key_F34: return "F34";
540 case Qt::Key_F35: return "F35";
541 case Qt::Key_Colon: return "colon";
542 case Qt::Key_Semicolon: return "semicolon";
543 case Qt::Key_Less: return "less";
544 case Qt::Key_Equal: return "equal";
545 case Qt::Key_Greater: return "greater";
546 case Qt::Key_Question: return "question";
547 case Qt::Key_At: return "at";
548 case Qt::Key_BracketLeft: return "bracketleft";
549 case Qt::Key_Backslash: return "backslash";
550 case Qt::Key_BracketRight: return "bracketright";
551 case Qt::Key_Underscore: return "underscore";
552 case Qt::Key_Space: return "space";
553 case Qt::Key_ParenLeft: return "parenleft";
554 case Qt::Key_ParenRight: return "parenright";
555 case Qt::Key_QuoteDbl: return "quotedbl";
556 case Qt::Key_Exclam: return "exclam";
557 case Qt::Key_NumberSign: return "numbersign";
558 case Qt::Key_AsciiCircum: return "asciicircum";
559 case Qt::Key_Dollar: return "dollar";
560 case Qt::Key_Percent: return "percent";
561 case Qt::Key_Ampersand: return "ampersand";
562 case Qt::Key_Asterisk: return "asterisk";
563 case Qt::Key_Apostrophe: return "apostrophe";
564 case Qt::Key_Plus: return "plus";
565 case Qt::Key_Minus: return "minus";
566 case Qt::Key_Comma: return "comma";
567 case Qt::Key_Period: return "period";
568 case Qt::Key_Slash: return "slash";
569 case Qt::Key_AsciiTilde: return "asciitilde";
570 case Qt::Key_BraceLeft: return "braceleft";
571 case Qt::Key_BraceRight: return "braceright";
572 case Qt::Key_QuoteLeft: return "grave"; // ???
573 case Qt::Key_notsign: return "notsign";
574 case Qt::Key_nobreakspace: return "nobreakspace";
575 case Qt::Key_exclamdown: return "exclamdown";
576 case Qt::Key_cent: return "cent";
577 case Qt::Key_sterling: return "sterling";
578 case Qt::Key_currency: return "currency";
579 case Qt::Key_yen: return "yen";
580 case Qt::Key_brokenbar: return "brokenbar";
581 case Qt::Key_section: return "section";
582 case Qt::Key_diaeresis: return "diaeresis";
583 case Qt::Key_copyright: return "copyright";
584 case Qt::Key_ordfeminine: return "ordfeminine";
585 case Qt::Key_guillemotleft: return "guillemotleft";
586 case Qt::Key_hyphen: return "hyphen";
587 case Qt::Key_registered: return "registered";
588 case Qt::Key_macron: return "macron";
589 case Qt::Key_degree: return "degree";
590 case Qt::Key_plusminus: return "plusminus";
591 case Qt::Key_twosuperior: return "twosuperior";
592 case Qt::Key_threesuperior: return "threesuperior";
593 case Qt::Key_acute: return "acute";
594 case Qt::Key_mu: return "mu";
595 case Qt::Key_paragraph: return "paragraph";
596 case Qt::Key_periodcentered: return "periodcentered";
597 case Qt::Key_cedilla: return "cedilla";
598 case Qt::Key_onesuperior: return "onesuperior";
599 case Qt::Key_masculine: return "masculine";
600 case Qt::Key_guillemotright: return "guillemotright";
601 case Qt::Key_onequarter: return "onequarter";
602 case Qt::Key_onehalf: return "onehalf";
603 case Qt::Key_threequarters: return "threequarters";
604 case Qt::Key_questiondown: return "questiondown";
605 case Qt::Key_Agrave: return "Agrave";
606 case Qt::Key_Aacute: return "Aacute";
607 case Qt::Key_Acircumflex: return "Acircumflex";
608 case Qt::Key_Atilde: return "Atilde";
609 case Qt::Key_Adiaeresis: return "Adiaeresis";
610 case Qt::Key_Aring: return "Aring";
611 case Qt::Key_AE: return "AE";
612 case Qt::Key_Ccedilla: return "Ccedilla";
613 case Qt::Key_Egrave: return "Egrave";
614 case Qt::Key_Eacute: return "Eacute";
615 case Qt::Key_Ecircumflex: return "Ecircumflex";
616 case Qt::Key_Ediaeresis: return "Ediaeresis";
617 case Qt::Key_Igrave: return "Igrave";
618 case Qt::Key_Iacute: return "Iacute";
619 case Qt::Key_Icircumflex: return "Icircumflex";
620 case Qt::Key_Idiaeresis: return "Idiaeresis";
621 case Qt::Key_ETH: return "ETH";
622 case Qt::Key_Ntilde: return "Ntilde";
623 case Qt::Key_Ograve: return "Ograve";
624 case Qt::Key_Oacute: return "Oacute";
625 case Qt::Key_Ocircumflex: return "Ocircumflex";
626 case Qt::Key_Otilde: return "Otilde";
627 case Qt::Key_Odiaeresis: return "Odiaeresis";
628 case Qt::Key_multiply: return "multiply";
629 case Qt::Key_Ooblique: return "Ooblique";
630 case Qt::Key_Ugrave: return "Ugrave";
631 case Qt::Key_Uacute: return "Uacute";
632 case Qt::Key_Ucircumflex: return "Ucircumflex";
633 case Qt::Key_Udiaeresis: return "Udiaeresis";
634 case Qt::Key_Yacute: return "Yacute";
635 case Qt::Key_THORN: return "THORN";
636 case Qt::Key_ssharp: return "ssharp";
637 case Qt::Key_ydiaeresis: return "ydiaeresis";
638 case Qt::Key_Bar: return "bar";
639 case Qt::Key_Dead_Caron: return "Dead_Caron";
641 // FIXME: these ones I don't know the names of ... help !
642 // what's here is basically guesses ...
643 case Qt::Key_Super_L: return "Super_L";
644 case Qt::Key_Super_R: return "Super_R";
645 case Qt::Key_Menu: return "Menu";
646 case Qt::Key_Hyper_L: return "Hyper_L";
647 case Qt::Key_Hyper_R: return "Hyper_R";
648 case Qt::Key_Help: return "Help";
649 case Qt::Key_Backtab: return "BackTab";
652 case 1040: return "а";
653 case 1041: return "б";
654 case 1042: return "в";
655 case 1043: return "г";
656 case 1044: return "д";
657 case 1045: return "е";
658 case 1028: return "є";
659 case 1025: return "ё";
660 case 1046: return "ж";
661 case 1047: return "з";
662 case 1048: return "и";
663 case 1030: return "і";
664 case 1031: return "ї";
665 case 1049: return "й";
666 case 1050: return "к";
667 case 1051: return "л";
668 case 1052: return "м";
669 case 1053: return "н";
670 case 1054: return "о";
671 case 1055: return "п";
672 case 1056: return "р";
673 case 1057: return "с";
674 case 1058: return "т";
675 case 1059: return "у";
676 case 1060: return "ф";
677 case 1061: return "х";
678 case 1062: return "ц";
679 case 1063: return "ч";
680 case 1064: return "ш";
681 case 1065: return "щ";
682 case 1066: return "ъ";
683 case 1067: return "ы";
684 case 1068: return "ь";
685 case 1069: return "э";
686 case 1070: return "ю";
687 case 1071: return "я";
690 case Qt::Key_unknown: return "";
696 static char encode(string const & encoding, QString const & str)
698 typedef map<string, QTextCodec *> EncodingMap;
699 EncodingMap encoding_map;
701 QTextCodec * codec = 0;
703 EncodingMap::const_iterator cit = encoding_map.find(encoding);
704 if (cit == encoding_map.end()) {
705 LYXERR(Debug::KEY, "Unrecognised encoding '" << encoding << "'.");
706 codec = encoding_map.find("")->second;
712 LYXERR(Debug::KEY, "No codec for encoding '" << encoding << "' found.");
716 LYXERR(Debug::KEY, "Using codec " << codec->name());
718 if (!codec->canEncode(str)) {
719 LYXERR(Debug::KEY, "Oof. Can't encode the text !");
723 return codec->fromUnicode(str).data()[0];
728 void setKeySymbol(KeySymbol * sym, QKeyEvent const * ev)
730 sym->setKey(ev->key());
731 if (ev->text().isNull()) {
732 LYXERR(Debug::KEY, "keyevent has isNull() text !");
733 sym->setText(docstring());
736 LYXERR(Debug::KEY, "Getting key " << ev->key() << ", with text '"
737 << ev->text() << "'");
738 // This is unsafe because ev->text() is the unicode representation of the
739 // key, not the name of the key. For example, Ctrl-x and Alt-x produce
741 sym->setText(qstring_to_ucs4(ev->text()));
742 LYXERR(Debug::KEY, "Setting key to " << sym->key() << ", "
743 << to_utf8(sym->text()));
747 void KeySymbol::init(string const & symbolname)
749 key_ = string_to_qkey(symbolname);
750 text_ = from_utf8(symbolname);
751 LYXERR(Debug::KEY, "Init key to " << key_ << ", " << to_utf8(text_));
755 void KeySymbol::init(int key)
758 text_ = from_utf8(qkey_to_string(key));
759 LYXERR(Debug::KEY, "Init key to " << key_ << ", " << to_utf8(text_));
763 bool KeySymbol::isOK() const
765 bool const ok = !(text_.empty() && qkey_to_string(key_).empty());
766 LYXERR(Debug::KEY, "isOK is " << ok);
771 bool KeySymbol::isModifier() const
773 bool const mod = lyx::isModifier(key_);
774 LYXERR(Debug::KEY, "isModifier is " << mod);
779 string KeySymbol::getSymbolName() const
781 string name = qkey_to_string(key_);
785 name = to_utf8(text_);
791 char_type KeySymbol::getUCSEncoded() const
796 // UTF16 has a maximum of two characters.
797 LASSERT(text_.size() <= 2, return 0);
799 if (lyxerr.debugging() && text_.size() > 1) {
800 // We don't know yet how well support the full ucs4 range.
801 LYXERR(Debug::KEY, "KeySymbol::getUCSEncoded()");
802 for (int i = 0; i != int(text_.size()); ++i)
803 LYXERR(Debug::KEY, "char " << i << ": " << int(text_[i]));
810 docstring const KeySymbol::print(KeyModifier mod, bool forgui, bool untranslated) const
814 if (mod & ShiftModifier && !(tmpkey == Qt::Key_Shift))
815 tmpkey += Qt::ShiftModifier;
816 if (mod & ControlModifier && !(tmpkey == Qt::Key_Control))
817 tmpkey += Qt::ControlModifier;
818 if (mod & AltModifier && !(tmpkey == Qt::Key_Alt))
819 tmpkey += Qt::AltModifier;
820 if (mod & MetaModifier && !(tmpkey == Qt::Key_Meta))
821 tmpkey += Qt::MetaModifier;
823 QKeySequence seq(tmpkey);
827 str = untranslated ? seq.toString(QKeySequence::PortableText)
828 : seq.toString(QKeySequence::NativeText);
831 // Qt/Mac does not use Command and friends in the
832 // portable case, but the windows-like Control+x (bug 5421).
833 str = seq.toString(QKeySequence::NativeText);
834 str.replace(QChar(0x21E7), qt_("Shift-"));
835 str.replace(QChar(0x2303), qt_("Control-"));
836 str.replace(QChar(0x2325), qt_("Option-"));
837 str.replace(QChar(0x2318), qt_("Command-"));
839 str = seq.toString(QKeySequence::PortableText);
843 return qstring_to_ucs4(str);
847 bool KeySymbol::isText() const
851 LYXERR(Debug::KEY, "text_ empty, isText() == false");
856 bool KeySymbol::operator==(KeySymbol const & ks) const
858 // we do not have enough info for a fair comparison, so return
859 // false. This works out OK because unknown text from Qt will
860 // get inserted anyway after the isText() check
861 if (key_ == Qt::Key_unknown || ks.key_ == Qt::Key_unknown)
863 return key_ == ks.key_;
867 KeyModifier q_key_state(Qt::KeyboardModifiers state)
869 KeyModifier k = NoModifier;
870 #if defined(Q_OS_MAC) && (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
871 /// Additional check for Control and Meta modifier swap state.
872 /// Starting with Qt 5 the modifiers aren't reported correctly.
873 /// Until this is fixed a correction is required.
874 /// AFAIK it is fixed at least with Qt 5.12.0
875 const bool dontSwapCtrlAndMeta =
876 frontend::theGuiApp()->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
878 const bool dontSwapCtrlAndMeta = false;
881 if (state & (dontSwapCtrlAndMeta ? Qt::MetaModifier : Qt::ControlModifier))
882 k |= ControlModifier;
883 if (state & Qt::ShiftModifier)
885 if (state & Qt::AltModifier)
887 #if defined(USE_MACOSX_PACKAGING) || defined(USE_META_KEYBINDING)
888 if (state & (dontSwapCtrlAndMeta ? Qt::ControlModifier : Qt::MetaModifier))
891 if (state & Qt::MetaModifier)