|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Retrieves the character map for each of the numeric keys. |
|
15 */ |
|
16 |
|
17 // INCLUDE FILES |
|
18 #include "cqwertykeymap.h" |
|
19 |
|
20 // This macro suppresses log writes |
|
21 //#define NO_PRED_SEARCH_LOGS |
|
22 #include "predictivesearchlog.h" |
|
23 |
|
24 #include <QChar> |
|
25 #include <QString> |
|
26 |
|
27 |
|
28 // Largest amount of keypresses that can be stored in QWERTY keyboard's |
|
29 // predictive search tables. |
|
30 // SQL BIGINT is a 64-bit signed integer and one bit is reserved for sign. |
|
31 // QWERTY's keys are identified by TKeyId that needs 6 bits. |
|
32 // 63 / 6 = 10 |
|
33 const TInt KMaxKeysStoredInDb = 10; |
|
34 |
|
35 // How many bits are needed to represent TKeyId |
|
36 const TInt KBitsInKeyId = 6; |
|
37 |
|
38 |
|
39 const QChar KEY_Q_NAME = 'q'; |
|
40 const QChar KEY_W_NAME = 'w'; |
|
41 const QChar KEY_E_NAME = 'e'; |
|
42 const QChar KEY_R_NAME = 'r'; |
|
43 const QChar KEY_T_NAME = 't'; |
|
44 const QChar KEY_Y_NAME = 'y'; |
|
45 const QChar KEY_U_NAME = 'u'; |
|
46 const QChar KEY_I_NAME = 'i'; |
|
47 const QChar KEY_O_NAME = 'o'; |
|
48 const QChar KEY_P_NAME = 'p'; |
|
49 |
|
50 const QChar KEY_A_NAME = 'a'; |
|
51 const QChar KEY_S_NAME = 's'; |
|
52 const QChar KEY_D_NAME = 'd'; |
|
53 const QChar KEY_F_NAME = 'f'; |
|
54 const QChar KEY_G_NAME = 'g'; |
|
55 const QChar KEY_H_NAME = 'h'; |
|
56 const QChar KEY_J_NAME = 'j'; |
|
57 const QChar KEY_K_NAME = 'k'; |
|
58 const QChar KEY_L_NAME = 'l'; |
|
59 |
|
60 const QChar KEY_Z_NAME = 'z'; |
|
61 const QChar KEY_X_NAME = 'x'; |
|
62 const QChar KEY_C_NAME = 'c'; |
|
63 const QChar KEY_V_NAME = 'v'; |
|
64 const QChar KEY_B_NAME = 'b'; |
|
65 const QChar KEY_N_NAME = 'n'; |
|
66 const QChar KEY_M_NAME = 'm'; |
|
67 |
|
68 const QChar KEY_COLON_NAME = ','; |
|
69 const QChar KEY_DOT_NAME = '.'; |
|
70 const QChar KEY_DASH_NAME = '-'; |
|
71 const QChar KEY_AT_NAME = '@'; |
|
72 const QChar KEY_QUOTE_NAME = '\''; |
|
73 const QChar KEY_QUESTION_MARK_NAME = '?'; |
|
74 |
|
75 const QChar KEY_32_NAME = '1'; |
|
76 const QChar KEY_33_NAME = '2'; |
|
77 const QChar KEY_34_NAME = '3'; |
|
78 const QChar KEY_35_NAME = '4'; |
|
79 const QChar KEY_36_NAME = '5'; |
|
80 const QChar KEY_37_NAME = '6'; |
|
81 const QChar KEY_38_NAME = '7'; |
|
82 const QChar KEY_39_NAME = '8'; |
|
83 const QChar KEY_40_NAME = '9'; |
|
84 const QChar KEY_41_NAME = '0'; |
|
85 const QChar KEY_42_NAME = '+'; |
|
86 const QChar KEY_43_NAME = '#'; |
|
87 |
|
88 // Unmapped (unknown) characters are replaced with this |
|
89 const QChar PAD_CHAR = '!'; |
|
90 |
|
91 // Must be the first key (EKeyQ) that has internal value 0 |
|
92 const QChar KLowerLimitPadding = KEY_Q_NAME; |
|
93 const QChar KUpperLimitPadding = PAD_CHAR; |
|
94 |
|
95 |
|
96 // ============================== MEMBER FUNCTIONS ============================ |
|
97 |
|
98 // ---------------------------------------------------------------------------- |
|
99 // CQwertyKeyMap::NewL |
|
100 // ---------------------------------------------------------------------------- |
|
101 CQwertyKeyMap* CQwertyKeyMap::NewL() |
|
102 { |
|
103 PRINT(_L("Enter CQwertyKeyMap::NewL")); |
|
104 |
|
105 CQwertyKeyMap* self = new (ELeave) CQwertyKeyMap(); |
|
106 CleanupStack::PushL(self); |
|
107 self->ConstructL(); |
|
108 CleanupStack::Pop(self); |
|
109 |
|
110 PRINT(_L("End CQwertyKeyMap::NewL")); |
|
111 return self; |
|
112 } |
|
113 |
|
114 // ---------------------------------------------------------------------------- |
|
115 // CQwertyKeyMap::~CQwertyKeyMap |
|
116 // ---------------------------------------------------------------------------- |
|
117 CQwertyKeyMap::~CQwertyKeyMap() |
|
118 { |
|
119 PRINT(_L("Enter CQwertyKeyMap::~CQwertyKeyMap")); |
|
120 PRINT(_L("End CQwertyKeyMap::~CQwertyKeyMap")); |
|
121 } |
|
122 |
|
123 // ---------------------------------------------------------------------------- |
|
124 // CQwertyKeyMap::ArrayIndexToMappedChar |
|
125 // Map index of iKeyMapping list, to the key that the mapping is for. |
|
126 // Space is already handled in CPcsKeyMap::GetMappedString(), no need to handle |
|
127 // it here. |
|
128 // ---------------------------------------------------------------------------- |
|
129 const QChar CQwertyKeyMap::ArrayIndexToMappedChar(TInt aArrayIndex) const |
|
130 { |
|
131 __ASSERT_DEBUG(aArrayIndex < EAmountOfKeysInQwertyKeypad, |
|
132 User::Panic(_L("CQwertyKeyMap::ArrayIndexToMappedChar"), |
|
133 KErrOverflow)); |
|
134 return iKeyNames.value(static_cast<TKeyId>(aArrayIndex), PAD_CHAR); |
|
135 } |
|
136 |
|
137 #if !defined(USE_ORBIT_KEYMAP) |
|
138 // ---------------------------------------------------------------------------- |
|
139 // CQwertyKeyMap::UseHardcodedKeyMap |
|
140 // ---------------------------------------------------------------------------- |
|
141 const QChar CQwertyKeyMap::UseHardcodedKeyMap(const QChar input) const |
|
142 { |
|
143 if (input >= 'a' && input <= 'z') |
|
144 { |
|
145 return input; |
|
146 } |
|
147 if (input >= 'A' && input <= 'Z') |
|
148 { |
|
149 return input.toLower(); // Return lowercase letter |
|
150 } |
|
151 if (input == KEY_COLON_NAME || |
|
152 input == KEY_DOT_NAME || |
|
153 input == KEY_DASH_NAME || |
|
154 input == KEY_AT_NAME || |
|
155 input == KEY_QUOTE_NAME || |
|
156 input == KEY_QUESTION_MARK_NAME) |
|
157 { |
|
158 return input; |
|
159 } |
|
160 |
|
161 // TODO: add rest of the keys |
|
162 |
|
163 #if defined(THAI_KEYMAP) |
|
164 // TODO: add Thai key map |
|
165 #endif |
|
166 |
|
167 // Other (unknown) chars |
|
168 return PAD_CHAR; |
|
169 } |
|
170 #endif // #if !defined(USE_ORBIT_KEYMAP) |
|
171 |
|
172 // ---------------------------------------------------------------------------- |
|
173 // CQwertyKeyMap::ComputeValue |
|
174 // ---------------------------------------------------------------------------- |
|
175 TInt CQwertyKeyMap::ComputeValue(QString aString, |
|
176 TBool aUpperLimit, |
|
177 QString& aValue) const |
|
178 { |
|
179 QString padded; |
|
180 if (aString.length() < KMaxKeysStoredInDb) |
|
181 { |
|
182 padded = aString.leftJustified(KMaxKeysStoredInDb, |
|
183 aUpperLimit ? KUpperLimitPadding : KLowerLimitPadding); |
|
184 } |
|
185 else |
|
186 { |
|
187 padded = aString; |
|
188 } |
|
189 |
|
190 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
191 TBuf<KMaxKeysStoredInDb> log(padded.utf16()); |
|
192 PRINT1(_L("CQwertyKeyMap::ComputeValue string = '%S'"), &log); |
|
193 #endif |
|
194 |
|
195 qint64 value(0); |
|
196 for (TInt i = 0; i < KMaxKeysStoredInDb; ++i) |
|
197 { |
|
198 value <<= KBitsInKeyId; |
|
199 value += MapKeyNameToValue(padded[i]); |
|
200 PRINT1(_L(" value now 0x%lx"), value); |
|
201 } |
|
202 |
|
203 // In order to write queries using '>' and '<' instead of '>=' and '<=', |
|
204 // expand the limit by one. |
|
205 if (aUpperLimit) |
|
206 { |
|
207 ++value; |
|
208 } |
|
209 else |
|
210 { |
|
211 --value; |
|
212 } |
|
213 PRINT2(_L("CQwertyKeyMap::ComputeValue result=0x%lx (%ld decimal)"), value, value); |
|
214 aValue = QString::number(value); // Convert to decimal value |
|
215 return KErrNone; |
|
216 } |
|
217 |
|
218 #if defined(USE_ORBIT_KEYMAP) |
|
219 // ---------------------------------------------------------------------------- |
|
220 // CQwertyKeyMap::MapKeyNameToValue |
|
221 // ---------------------------------------------------------------------------- |
|
222 bool CQwertyKeyMap::IsValidChar(const QChar aChar) const |
|
223 { |
|
224 return iKeyValues.contains(aChar); |
|
225 } |
|
226 #endif // #if defined(USE_ORBIT_KEYMAP) |
|
227 |
|
228 // ---------------------------------------------------------------------------- |
|
229 // CQwertyKeyMap::MapKeyNameToValue |
|
230 // Does the reverse of ArrayIndexToMappedChar() |
|
231 // ---------------------------------------------------------------------------- |
|
232 TInt CQwertyKeyMap::MapKeyNameToValue(const QChar aKeyName) const |
|
233 { |
|
234 return iKeyNames.key(aKeyName, KPadCharValue); |
|
235 } |
|
236 |
|
237 // ---------------------------------------------------------------------------- |
|
238 // CQwertyKeyMap::CQwertyKeyMap |
|
239 // Fill QList with empty strings |
|
240 // ---------------------------------------------------------------------------- |
|
241 CQwertyKeyMap::CQwertyKeyMap() : |
|
242 CPcsKeyMap(EAmountOfKeysInQwertyKeypad, PAD_CHAR, KMaxKeysStoredInDb) |
|
243 { |
|
244 } |
|
245 |
|
246 // ---------------------------------------------------------------------------- |
|
247 // CQwertyKeyMap::ConstructL |
|
248 // ---------------------------------------------------------------------------- |
|
249 void CQwertyKeyMap::ConstructL() |
|
250 { |
|
251 PRINT(_L("Enter CQwertyKeyMap::ConstructL")); |
|
252 |
|
253 // CPcsKeyMap::ConstructLanguageMappings() uses ArrayIndexToMappedChar() |
|
254 // that uses iKeyNames, so construct it first |
|
255 TInt err(KErrNone); |
|
256 QT_TRYCATCH_ERROR(err, ConstructKeyNameMap()); |
|
257 User::LeaveIfError(err); |
|
258 |
|
259 #if defined(USE_ORBIT_KEYMAP) |
|
260 CPcsKeyMap::ConstructL(HbKeyboardVirtualQwerty); |
|
261 #else |
|
262 CPcsKeyMap::ConstructL(); |
|
263 #endif |
|
264 |
|
265 PRINT(_L("End CQwertyKeyMap::ConstructL")); |
|
266 } |
|
267 |
|
268 // ---------------------------------------------------------------------------- |
|
269 // CQwertyKeyMap::ConstructKeyNameMap |
|
270 // ---------------------------------------------------------------------------- |
|
271 void CQwertyKeyMap::ConstructKeyNameMap() |
|
272 { |
|
273 iKeyNames.insert(EKeyQ, KEY_Q_NAME); |
|
274 iKeyNames.insert(EKeyW, KEY_W_NAME); |
|
275 iKeyNames.insert(EKeyE, KEY_E_NAME); |
|
276 iKeyNames.insert(EKeyR, KEY_R_NAME); |
|
277 iKeyNames.insert(EKeyT, KEY_T_NAME); |
|
278 iKeyNames.insert(EKeyY, KEY_Y_NAME); |
|
279 iKeyNames.insert(EKeyU, KEY_U_NAME); |
|
280 iKeyNames.insert(EKeyI, KEY_I_NAME); |
|
281 iKeyNames.insert(EKeyO, KEY_O_NAME); |
|
282 iKeyNames.insert(EKeyP, KEY_P_NAME); |
|
283 iKeyNames.insert(EKeyA, KEY_A_NAME); |
|
284 iKeyNames.insert(EKeyS, KEY_S_NAME); |
|
285 iKeyNames.insert(EKeyD, KEY_D_NAME); |
|
286 iKeyNames.insert(EKeyF, KEY_F_NAME); |
|
287 iKeyNames.insert(EKeyG, KEY_G_NAME); |
|
288 iKeyNames.insert(EKeyH, KEY_H_NAME); |
|
289 iKeyNames.insert(EKeyJ, KEY_J_NAME); |
|
290 iKeyNames.insert(EKeyK, KEY_K_NAME); |
|
291 iKeyNames.insert(EKeyL, KEY_L_NAME); |
|
292 iKeyNames.insert(EKeyZ, KEY_Z_NAME); |
|
293 iKeyNames.insert(EKeyX, KEY_X_NAME); |
|
294 iKeyNames.insert(EKeyC, KEY_C_NAME); |
|
295 iKeyNames.insert(EKeyV, KEY_V_NAME); |
|
296 iKeyNames.insert(EKeyB, KEY_B_NAME); |
|
297 iKeyNames.insert(EKeyN, KEY_N_NAME); |
|
298 iKeyNames.insert(EKeyM, KEY_M_NAME); |
|
299 iKeyNames.insert(EKeyColon, KEY_COLON_NAME); |
|
300 iKeyNames.insert(EKeyDot, KEY_DOT_NAME); |
|
301 iKeyNames.insert(EKeyDash, KEY_DASH_NAME); |
|
302 iKeyNames.insert(EKeyAt, KEY_AT_NAME); |
|
303 iKeyNames.insert(EKeyQuote, KEY_QUOTE_NAME); |
|
304 iKeyNames.insert(EKeyQuestionMark, KEY_QUESTION_MARK_NAME); |
|
305 iKeyNames.insert(EKey32, KEY_32_NAME); |
|
306 iKeyNames.insert(EKey33, KEY_33_NAME); |
|
307 iKeyNames.insert(EKey34, KEY_34_NAME); |
|
308 iKeyNames.insert(EKey35, KEY_35_NAME); |
|
309 iKeyNames.insert(EKey36, KEY_36_NAME); |
|
310 iKeyNames.insert(EKey37, KEY_37_NAME); |
|
311 iKeyNames.insert(EKey38, KEY_38_NAME); |
|
312 iKeyNames.insert(EKey39, KEY_39_NAME); |
|
313 iKeyNames.insert(EKey40, KEY_40_NAME); |
|
314 iKeyNames.insert(EKey41, KEY_41_NAME); |
|
315 iKeyNames.insert(EKey42, KEY_42_NAME); |
|
316 iKeyNames.insert(EKey43, KEY_43_NAME); |
|
317 |
|
318 |
|
319 // Since reverse lookup in QMap is slow, collect all values into iKeyValues |
|
320 // list, that can be searched. |
|
321 iKeyValues = iKeyNames.values(); |
|
322 } |
|
323 |
|
324 // End of file |