Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwasmkeytranslator.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include "qwasmevent.h"
7
8#include <QtCore/private/qmakearray_p.h>
9#include <QtCore/qglobal.h>
10#include <QtCore/qobject.h>
11
12#include <algorithm>
13
14QT_BEGIN_NAMESPACE
15
16namespace {
18{
19 static constexpr char StringTerminator = '\0';
20
21 const char *web;
22 unsigned int qt;
23
24 constexpr bool operator<=(const WebKb2QtData &that) const noexcept
25 {
26 return !(strcmp(that) > 0);
27 }
28
29 bool operator<(const WebKb2QtData &that) const noexcept { return ::strcmp(web, that.web) < 0; }
30
31 constexpr bool operator==(const WebKb2QtData &that) const noexcept { return strcmp(that) == 0; }
32
33 constexpr int strcmp(const WebKb2QtData &that, const int i = 0) const
34 {
35 return web[i] == StringTerminator && that.web[i] == StringTerminator ? 0
36 : web[i] == StringTerminator ? -1
37 : that.web[i] == StringTerminator ? 1
38 : web[i] < that.web[i] ? -1
39 : web[i] > that.web[i] ? 1
40 : strcmp(that, i + 1);
41 }
42};
43
44template<unsigned int Qt, char... WebChar>
45struct Web2Qt
46{
47 static constexpr const char storage[sizeof...(WebChar) + 1] = { WebChar..., '\0' };
49 static constexpr Type data() noexcept { return Type{ storage, Qt }; }
50};
51
52template<unsigned int Qt, char... WebChar>
53constexpr char Web2Qt<Qt, WebChar...>::storage[];
54
55static constexpr const auto WebToQtKeyCodeMappings = qMakeArray(
56 QSortedData<Web2Qt<Qt::Key_Alt, 'A', 'l', 't', 'L', 'e', 'f', 't'>,
57 Web2Qt<Qt::Key_Alt, 'A', 'l', 't'>,
58 Web2Qt<Qt::Key_AltGr, 'A', 'l', 't', 'R', 'i', 'g', 'h', 't'>,
59 Web2Qt<Qt::Key_Apostrophe, 'Q', 'u', 'o', 't', 'e'>,
60 Web2Qt<Qt::Key_Backspace, 'B', 'a', 'c', 'k', 's', 'p', 'a', 'c', 'e'>,
61 Web2Qt<Qt::Key_CapsLock, 'C', 'a', 'p', 's', 'L', 'o', 'c', 'k'>,
62 Web2Qt<Qt::Key_Control, 'C', 'o', 'n', 't', 'r', 'o', 'l'>,
63 Web2Qt<Qt::Key_Delete, 'D', 'e', 'l', 'e', 't', 'e'>,
64 Web2Qt<Qt::Key_Down, 'A', 'r', 'r', 'o', 'w', 'D', 'o', 'w', 'n'>,
65 Web2Qt<Qt::Key_Escape, 'E', 's', 'c', 'a', 'p', 'e'>,
66 Web2Qt<Qt::Key_F1, 'F', '1'>, Web2Qt<Qt::Key_F2, 'F', '2'>,
67 Web2Qt<Qt::Key_F11, 'F', '1', '1'>, Web2Qt<Qt::Key_F12, 'F', '1', '2'>,
68 Web2Qt<Qt::Key_F13, 'F', '1', '3'>, Web2Qt<Qt::Key_F14, 'F', '1', '4'>,
69 Web2Qt<Qt::Key_F15, 'F', '1', '5'>, Web2Qt<Qt::Key_F16, 'F', '1', '6'>,
70 Web2Qt<Qt::Key_F17, 'F', '1', '7'>, Web2Qt<Qt::Key_F18, 'F', '1', '8'>,
71 Web2Qt<Qt::Key_F19, 'F', '1', '9'>, Web2Qt<Qt::Key_F20, 'F', '2', '0'>,
72 Web2Qt<Qt::Key_F21, 'F', '2', '1'>, Web2Qt<Qt::Key_F22, 'F', '2', '2'>,
73 Web2Qt<Qt::Key_F23, 'F', '2', '3'>,
74 Web2Qt<Qt::Key_F3, 'F', '3'>, Web2Qt<Qt::Key_F4, 'F', '4'>,
75 Web2Qt<Qt::Key_F5, 'F', '5'>, Web2Qt<Qt::Key_F6, 'F', '6'>,
76 Web2Qt<Qt::Key_F7, 'F', '7'>, Web2Qt<Qt::Key_F8, 'F', '8'>,
77 Web2Qt<Qt::Key_F9, 'F', '9'>, Web2Qt<Qt::Key_F10, 'F', '1', '0'>,
78 Web2Qt<Qt::Key_Help, 'H', 'e', 'l', 'p'>,
79 Web2Qt<Qt::Key_Home, 'H', 'o', 'm', 'e'>, Web2Qt<Qt::Key_End, 'E', 'n', 'd'>,
80 Web2Qt<Qt::Key_Insert, 'I', 'n', 's', 'e', 'r', 't'>,
81 Web2Qt<Qt::Key_Left, 'A', 'r', 'r', 'o', 'w', 'L', 'e', 'f', 't'>,
82 Web2Qt<Qt::Key_Meta, 'M', 'e', 't', 'a'>, Web2Qt<Qt::Key_Meta, 'O', 'S'>,
83 Web2Qt<Qt::Key_Menu, 'C', 'o', 'n', 't', 'e', 'x', 't', 'M', 'e', 'n', 'u'>,
84 Web2Qt<Qt::Key_NumLock, 'N', 'u', 'm', 'L', 'o', 'c', 'k'>,
85 Web2Qt<Qt::Key_PageDown, 'P', 'a', 'g', 'e', 'D', 'o', 'w', 'n'>,
86 Web2Qt<Qt::Key_PageUp, 'P', 'a', 'g', 'e', 'U', 'p'>,
87 Web2Qt<Qt::Key_Paste, 'P', 'a', 's', 't', 'e'>,
88 Web2Qt<Qt::Key_Pause, 'C', 'l', 'e', 'a', 'r'>,
89 Web2Qt<Qt::Key_Pause, 'P', 'a', 'u', 's', 'e'>,
90 Web2Qt<Qt::Key_QuoteLeft, 'B', 'a', 'c', 'k', 'q', 'u', 'o', 't', 'e'>,
91 Web2Qt<Qt::Key_QuoteLeft, 'I', 'n', 't', 'l', 'B', 'a', 'c', 'k', 's', 'l', 'a', 's', 'h'>,
92 Web2Qt<Qt::Key_Return, 'E', 'n', 't', 'e', 'r'>,
93 Web2Qt<Qt::Key_Right, 'A', 'r', 'r', 'o', 'w', 'R', 'i', 'g', 'h', 't'>,
94 Web2Qt<Qt::Key_ScrollLock, 'S', 'c', 'r', 'o', 'l', 'l', 'L', 'o', 'c', 'k'>,
95 Web2Qt<Qt::Key_Shift, 'S', 'h', 'i', 'f', 't'>,
96 Web2Qt<Qt::Key_Tab, 'T', 'a', 'b'>,
97 Web2Qt<Qt::Key_Up, 'A', 'r', 'r', 'o', 'w', 'U', 'p'>,
98 Web2Qt<Qt::Key_yen, 'I', 'n', 't', 'l', 'Y', 'e', 'n'>>::Data{});
99
100static constexpr const auto DiacriticalCharsKeyToTextLowercase = qMakeArray(
101 QSortedData<
102 Web2Qt<Qt::Key_Aacute, '\xc3', '\xa1'>,
103 Web2Qt<Qt::Key_Acircumflex, '\xc3', '\xa2'>,
104 Web2Qt<Qt::Key_Adiaeresis, '\xc3', '\xa4'>,
105 Web2Qt<Qt::Key_AE, '\xc3', '\xa6'>,
106 Web2Qt<Qt::Key_Agrave, '\xc3', '\xa0'>,
107 Web2Qt<Qt::Key_Aring, '\xc3', '\xa5'>,
108 Web2Qt<Qt::Key_Atilde, '\xc3', '\xa3'>,
109 Web2Qt<Qt::Key_Ccedilla, '\xc3', '\xa7'>,
110 Web2Qt<Qt::Key_Eacute, '\xc3', '\xa9'>,
111 Web2Qt<Qt::Key_Ecircumflex, '\xc3', '\xaa'>,
112 Web2Qt<Qt::Key_Ediaeresis, '\xc3', '\xab'>,
113 Web2Qt<Qt::Key_Egrave, '\xc3', '\xa8'>,
114 Web2Qt<Qt::Key_Iacute, '\xc3', '\xad'>,
115 Web2Qt<Qt::Key_Icircumflex, '\xc3', '\xae'>,
116 Web2Qt<Qt::Key_Idiaeresis, '\xc3', '\xaf'>,
117 Web2Qt<Qt::Key_Igrave, '\xc3', '\xac'>,
118 Web2Qt<Qt::Key_Ntilde, '\xc3', '\xb1'>,
119 Web2Qt<Qt::Key_Oacute, '\xc3', '\xb3'>,
120 Web2Qt<Qt::Key_Ocircumflex, '\xc3', '\xb4'>,
121 Web2Qt<Qt::Key_Odiaeresis, '\xc3', '\xb6'>,
122 Web2Qt<Qt::Key_Ograve, '\xc3', '\xb2'>,
123 Web2Qt<Qt::Key_Ooblique, '\xc3', '\xb8'>,
124 Web2Qt<Qt::Key_Otilde, '\xc3', '\xb5'>,
125 Web2Qt<Qt::Key_Uacute, '\xc3', '\xba'>,
126 Web2Qt<Qt::Key_Ucircumflex, '\xc3', '\xbb'>,
127 Web2Qt<Qt::Key_Udiaeresis, '\xc3', '\xbc'>,
128 Web2Qt<Qt::Key_Ugrave, '\xc3', '\xb9'>,
129 Web2Qt<Qt::Key_Yacute, '\xc3', '\xbd'>,
130 Web2Qt<Qt::Key_ydiaeresis, '\xc3', '\xbf'>>::Data{});
131
132static constexpr const auto DiacriticalCharsKeyToTextUppercase = qMakeArray(
133 QSortedData<
134 Web2Qt<Qt::Key_Aacute, '\xc3', '\x81'>,
135 Web2Qt<Qt::Key_Acircumflex, '\xc3', '\x82'>,
136 Web2Qt<Qt::Key_Adiaeresis, '\xc3', '\x84'>,
137 Web2Qt<Qt::Key_AE, '\xc3', '\x86'>,
138 Web2Qt<Qt::Key_Agrave, '\xc3', '\x80'>,
139 Web2Qt<Qt::Key_Aring, '\xc3', '\x85'>,
140 Web2Qt<Qt::Key_Atilde, '\xc3', '\x83'>,
141 Web2Qt<Qt::Key_Ccedilla, '\xc3', '\x87'>,
142 Web2Qt<Qt::Key_Eacute, '\xc3', '\x89'>,
143 Web2Qt<Qt::Key_Ecircumflex, '\xc3', '\x8a'>,
144 Web2Qt<Qt::Key_Ediaeresis, '\xc3', '\x8b'>,
145 Web2Qt<Qt::Key_Egrave, '\xc3', '\x88'>,
146 Web2Qt<Qt::Key_Iacute, '\xc3', '\x8d'>,
147 Web2Qt<Qt::Key_Icircumflex, '\xc3', '\x8e'>,
148 Web2Qt<Qt::Key_Idiaeresis, '\xc3', '\x8f'>,
149 Web2Qt<Qt::Key_Igrave, '\xc3', '\x8c'>,
150 Web2Qt<Qt::Key_Ntilde, '\xc3', '\x91'>,
151 Web2Qt<Qt::Key_Oacute, '\xc3', '\x93'>,
152 Web2Qt<Qt::Key_Ocircumflex, '\xc3', '\x94'>,
153 Web2Qt<Qt::Key_Odiaeresis, '\xc3', '\x96'>,
154 Web2Qt<Qt::Key_Ograve, '\xc3', '\x92'>,
155 Web2Qt<Qt::Key_Ooblique, '\xc3', '\x98'>,
156 Web2Qt<Qt::Key_Otilde, '\xc3', '\x95'>,
157 Web2Qt<Qt::Key_Uacute, '\xc3', '\x9a'>,
158 Web2Qt<Qt::Key_Ucircumflex, '\xc3', '\x9b'>,
159 Web2Qt<Qt::Key_Udiaeresis, '\xc3', '\x9c'>,
160 Web2Qt<Qt::Key_Ugrave, '\xc3', '\x99'>,
161 Web2Qt<Qt::Key_Yacute, '\xc3', '\x9d'>,
162 Web2Qt<Qt::Key_ydiaeresis, '\xc5', '\xb8'>>::Data{});
163
164static_assert(DiacriticalCharsKeyToTextLowercase.size()
165 == DiacriticalCharsKeyToTextUppercase.size(),
166 "Add the new key to both arrays");
167
169{
171};
172
174 // ~
175 { Qt::Key_A, Qt::Key_Atilde },
176 { Qt::Key_N, Qt::Key_Ntilde },
177 { Qt::Key_O, Qt::Key_Otilde },
178};
180 // `
181 { Qt::Key_A, Qt::Key_Agrave }, { Qt::Key_E, Qt::Key_Egrave }, { Qt::Key_I, Qt::Key_Igrave },
182 { Qt::Key_O, Qt::Key_Ograve }, { Qt::Key_U, Qt::Key_Ugrave },
183};
185 // '
186 { Qt::Key_A, Qt::Key_Aacute }, { Qt::Key_E, Qt::Key_Eacute }, { Qt::Key_I, Qt::Key_Iacute },
187 { Qt::Key_O, Qt::Key_Oacute }, { Qt::Key_U, Qt::Key_Uacute }, { Qt::Key_Y, Qt::Key_Yacute },
188};
190 // umlaut ยจ
191 { Qt::Key_A, Qt::Key_Adiaeresis }, { Qt::Key_E, Qt::Key_Ediaeresis },
192 { Qt::Key_I, Qt::Key_Idiaeresis }, { Qt::Key_O, Qt::Key_Odiaeresis },
193 { Qt::Key_U, Qt::Key_Udiaeresis }, { Qt::Key_Y, Qt::Key_ydiaeresis },
194};
196 // ^
197 { Qt::Key_A, Qt::Key_Acircumflex }, { Qt::Key_E, Qt::Key_Ecircumflex },
198 { Qt::Key_I, Qt::Key_Icircumflex }, { Qt::Key_O, Qt::Key_Ocircumflex },
199 { Qt::Key_U, Qt::Key_Ucircumflex },
200};
201
202static Qt::Key find_impl(const KeyMapping *first, const KeyMapping *last, Qt::Key key) noexcept
203{
204 while (first != last) {
205 if (first->from == key)
206 return first->to;
207 ++first;
208 }
209 return Qt::Key_unknown;
210}
211
212template<size_t N>
213static Qt::Key find(const KeyMapping (&map)[N], Qt::Key key) noexcept
214{
215 return find_impl(map, map + N, key);
216}
217
218Qt::Key translateBaseKeyUsingDeadKey(Qt::Key accentBaseKey, Qt::Key deadKey)
219{
220 switch (deadKey) {
221 case Qt::Key_Dead_Grave:
222 return find(graveKeyTable, accentBaseKey);
223 case Qt::Key_Dead_Acute:
224 return find(acuteKeyTable, accentBaseKey);
225 case Qt::Key_Dead_Tilde:
226 return find(tildeKeyTable, accentBaseKey);
227 case Qt::Key_Dead_Diaeresis:
228 return find(diaeresisKeyTable, accentBaseKey);
229 case Qt::Key_Dead_Circumflex:
230 return find(circumflexKeyTable, accentBaseKey);
231 default:
232 return Qt::Key_unknown;
233 };
234}
235
236template<class T>
237std::optional<QString> findKeyTextByKeyId(const T &mappingArray, Qt::Key qtKey)
238{
239 const auto it = std::find_if(mappingArray.cbegin(), mappingArray.cend(),
240 [qtKey](const WebKb2QtData &data) { return data.qt == qtKey; });
241 return it != mappingArray.cend() ? it->web : std::optional<QString>();
242}
243} // namespace
244
246{
247 const WebKb2QtData searchKey{ toFind, 0 };
248 const auto it = std::lower_bound(WebToQtKeyCodeMappings.cbegin(), WebToQtKeyCodeMappings.cend(),
249 searchKey);
250 return it != WebToQtKeyCodeMappings.cend() && searchKey == *it ? static_cast<Qt::Key>(it->qt)
251 : std::optional<Qt::Key>();
252}
253
254QT_END_NAMESPACE
std::optional< QString > findKeyTextByKeyId(const T &mappingArray, Qt::Key qtKey)
static constexpr const auto DiacriticalCharsKeyToTextLowercase
static Qt::Key find(const KeyMapping(&map)[N], Qt::Key key) noexcept
constexpr KeyMapping diaeresisKeyTable[]
static constexpr const auto DiacriticalCharsKeyToTextUppercase
constexpr KeyMapping tildeKeyTable[]
constexpr KeyMapping graveKeyTable[]
static Qt::Key find_impl(const KeyMapping *first, const KeyMapping *last, Qt::Key key) noexcept
static constexpr const auto WebToQtKeyCodeMappings
Qt::Key translateBaseKeyUsingDeadKey(Qt::Key accentBaseKey, Qt::Key deadKey)
constexpr KeyMapping acuteKeyTable[]
constexpr KeyMapping circumflexKeyTable[]
std::optional< Qt::Key > mapWebKeyTextToQtKey(const char *toFind)
static constexpr const char storage[sizeof...(WebChar)+1]
static constexpr Type data() noexcept
bool operator<(const WebKb2QtData &that) const noexcept
constexpr int strcmp(const WebKb2QtData &that, const int i=0) const
constexpr bool operator==(const WebKb2QtData &that) const noexcept
constexpr bool operator<=(const WebKb2QtData &that) const noexcept