|
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 "cpcskeymap.h" |
|
19 #include <QChar> |
|
20 #include <QString> |
|
21 |
|
22 #if defined(USE_ORBIT_KEYMAP) |
|
23 #include <hbinputkeymap.h> |
|
24 #include <hbinputkeymapfactory.h> |
|
25 #endif // #if defined(USE_ORBIT_KEYMAP) |
|
26 |
|
27 // This macro suppresses log writes |
|
28 //#define NO_PRED_SEARCH_LOGS |
|
29 #include "predictivesearchlog.h" |
|
30 |
|
31 const QChar KSpaceChar = ' '; |
|
32 |
|
33 // Separator character stored in predictive search table columns |
|
34 const QChar KSeparatorChar = ' '; |
|
35 |
|
36 |
|
37 // ============================== MEMBER FUNCTIONS ============================ |
|
38 |
|
39 // ---------------------------------------------------------------------------- |
|
40 // CPcsKeyMap::~CPcsKeyMap |
|
41 // ---------------------------------------------------------------------------- |
|
42 CPcsKeyMap::~CPcsKeyMap() |
|
43 { |
|
44 PRINT(_L("Enter CPcsKeyMap::~CPcsKeyMap")); |
|
45 PRINT(_L("End CPcsKeyMap::~CPcsKeyMap")); |
|
46 } |
|
47 |
|
48 // ---------------------------------------------------------------------------- |
|
49 // CPcsKeyMap::GetMappedStringL |
|
50 // ---------------------------------------------------------------------------- |
|
51 HBufC* CPcsKeyMap::GetMappedStringL(const TDesC& aSource) const |
|
52 { |
|
53 PRINT1(_L("Enter CPcsKeyMap::GetMappedStringL input '%S'"), &aSource); |
|
54 |
|
55 QString source((QChar*)aSource.Ptr(), aSource.Length()); |
|
56 QString result; |
|
57 TInt err(KErrNone); |
|
58 QT_TRYCATCH_ERROR(err, result = GetMappedString(source)); |
|
59 User::LeaveIfError(err); |
|
60 |
|
61 HBufC* destination = HBufC::NewL(result.length()); |
|
62 destination->Des().Copy(result.utf16()); |
|
63 |
|
64 PRINT1(_L("End CPcsKeyMap::GetMappedStringL result '%S'"), destination); |
|
65 return destination; |
|
66 } |
|
67 |
|
68 // ---------------------------------------------------------------------------- |
|
69 // CPcsKeyMap::GetMappedString |
|
70 // ---------------------------------------------------------------------------- |
|
71 QString CPcsKeyMap::GetMappedString(QString aSource) const |
|
72 { |
|
73 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
74 const int KLogLength = 30; |
|
75 TBuf<KLogLength> log(aSource.left(KLogLength).utf16()); |
|
76 PRINT1(_L("Enter CPcsKeyMap::GetMappedString input '%S'"), &log); |
|
77 #endif |
|
78 |
|
79 QString destination; |
|
80 TBool skipHashStar = DetermineSpecialCharBehaviour(aSource); |
|
81 TInt length = aSource.length(); |
|
82 |
|
83 for (int i = 0; i < length; ++i) |
|
84 { |
|
85 if (aSource[i] == KSpaceChar) |
|
86 { |
|
87 destination.append(KSeparatorChar); |
|
88 } |
|
89 else |
|
90 { |
|
91 QChar ch(0); |
|
92 #if defined(USE_ORBIT_KEYMAP) |
|
93 ch = MappedKeyForChar(aSource[i]); |
|
94 #else |
|
95 ch = UseHardcodedKeyMap(aSource[i]); |
|
96 #endif |
|
97 if (!ShouldSkipChar(ch, skipHashStar)) |
|
98 { |
|
99 destination.append(ch); |
|
100 } |
|
101 } |
|
102 } |
|
103 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
104 log = destination.left(KLogLength).utf16(); |
|
105 PRINT1(_L("End CPcsKeyMap::GetMappedString result '%S'"), &log); |
|
106 #endif |
|
107 return destination; |
|
108 } |
|
109 |
|
110 // ---------------------------------------------------------------------------- |
|
111 // CPcsKeyMap::GetNumericLimitsL |
|
112 // In order to speed up the execution, caller should convert search pattern |
|
113 // with a one call to CPcsKeyMap::GetMappedStringL() and then pass the tokens |
|
114 // to CPcsKeyMap::GetNumericLimitsL(). |
|
115 // So it is expected that aString contains only certain characters. |
|
116 // ---------------------------------------------------------------------------- |
|
117 TInt CPcsKeyMap::GetNumericLimits(QString aString, |
|
118 QString& aLowerLimit, |
|
119 QString& aUpperLimit) const |
|
120 { |
|
121 PRINT(_L("CPcsKeyMap::GetNumericLimits")); |
|
122 if (aString.length() > iMaxKeysStoredInDb) |
|
123 { |
|
124 QString truncated = aString.left(iMaxKeysStoredInDb); |
|
125 aString = truncated; |
|
126 } |
|
127 |
|
128 TInt err = ComputeValue(aString, EFalse, aLowerLimit); |
|
129 if (err == KErrNone) |
|
130 { |
|
131 err = ComputeValue(aString, ETrue, aUpperLimit); |
|
132 } |
|
133 PRINT1(_L("End CPcsKeyMap::GetNumericLimits ret=%d"), err); |
|
134 return err; |
|
135 } |
|
136 |
|
137 #if defined(USE_ORBIT_KEYMAP) |
|
138 // ---------------------------------------------------------------------------- |
|
139 // CPcsKeyMap::Separator |
|
140 // ---------------------------------------------------------------------------- |
|
141 QChar CPcsKeyMap::Separator() const |
|
142 { |
|
143 return KSeparatorChar; |
|
144 } |
|
145 |
|
146 // ---------------------------------------------------------------------------- |
|
147 // CPcsKeyMap::SetHardcodedCharacters |
|
148 // Default implementation selects only the current default language. |
|
149 // ---------------------------------------------------------------------------- |
|
150 QList<HbInputLanguage> CPcsKeyMap::SelectLanguages() |
|
151 { |
|
152 QList<HbInputLanguage> languages; |
|
153 HbInputLanguage inputLanguage(QLocale::system().language()); |
|
154 languages << inputLanguage; |
|
155 return languages; |
|
156 } |
|
157 |
|
158 // ---------------------------------------------------------------------------- |
|
159 // CPcsKeyMap::SetHardcodedCharacters |
|
160 // Default implementation does nothing |
|
161 // ---------------------------------------------------------------------------- |
|
162 void CPcsKeyMap::SetHardcodedCharacters() |
|
163 { |
|
164 } |
|
165 #endif // #if defined(USE_ORBIT_KEYMAP) |
|
166 |
|
167 // ---------------------------------------------------------------------------- |
|
168 // CPcsKeyMap::DetermineSpecialCharBehaviour |
|
169 // Default implementation |
|
170 // ---------------------------------------------------------------------------- |
|
171 TBool CPcsKeyMap::DetermineSpecialCharBehaviour(QString /*aSource*/) const |
|
172 { |
|
173 return EFalse; |
|
174 } |
|
175 |
|
176 // ---------------------------------------------------------------------------- |
|
177 // CPcsKeyMap::ShouldSkipChar |
|
178 // Default implementation |
|
179 // ---------------------------------------------------------------------------- |
|
180 TBool CPcsKeyMap::ShouldSkipChar(QChar /*aChar*/, TBool /*aSkipHashStar*/) const |
|
181 { |
|
182 return EFalse; |
|
183 } |
|
184 |
|
185 // ---------------------------------------------------------------------------- |
|
186 // CPcsKeyMap::ConstructL |
|
187 // ---------------------------------------------------------------------------- |
|
188 #if defined(USE_ORBIT_KEYMAP) |
|
189 void CPcsKeyMap::ConstructL(HbKeyboardType aKeyboardType) |
|
190 #else |
|
191 void CPcsKeyMap::ConstructL() |
|
192 #endif |
|
193 { |
|
194 PRINT(_L("Enter CPcsKeyMap::ConstructL")); |
|
195 |
|
196 #if defined(USE_ORBIT_KEYMAP) |
|
197 TInt err(KErrNone); |
|
198 QT_TRYCATCH_ERROR(err, |
|
199 { |
|
200 InitKeyMappings(); |
|
201 SetHardcodedCharacters(); |
|
202 ConstructLanguageMappings(aKeyboardType); |
|
203 }); |
|
204 if (err != KErrNone) |
|
205 { |
|
206 PRINT1(_L("CPcsKeyMap::ConstructL exception, err=%d"), err); |
|
207 User::Leave(err); |
|
208 } |
|
209 #endif |
|
210 |
|
211 PRINT(_L("End CPcsKeyMap::ConstructL")); |
|
212 } |
|
213 |
|
214 // ---------------------------------------------------------------------------- |
|
215 // CPcsKeyMap::CPcsKeyMap |
|
216 // ---------------------------------------------------------------------------- |
|
217 #if defined(USE_ORBIT_KEYMAP) |
|
218 CPcsKeyMap::CPcsKeyMap(TInt aAmountOfKeys, |
|
219 QChar aPadChar, |
|
220 TInt aMaxKeysStoredInDb) : |
|
221 iKeyMapping(), |
|
222 iAmountOfKeys(aAmountOfKeys), |
|
223 iPadChar(aPadChar), |
|
224 iMaxKeysStoredInDb(aMaxKeysStoredInDb) |
|
225 { |
|
226 } |
|
227 #else // #if defined(USE_ORBIT_KEYMAP) |
|
228 CPcsKeyMap::CPcsKeyMap(TInt /*aAmountOfKeys*/, |
|
229 QChar /*aPadChar*/, |
|
230 TInt aMaxKeysStoredInDb) : |
|
231 iMaxKeysStoredInDb(aMaxKeysStoredInDb) |
|
232 { |
|
233 } |
|
234 #endif // #if defined(USE_ORBIT_KEYMAP) |
|
235 |
|
236 #if defined(USE_ORBIT_KEYMAP) |
|
237 // ---------------------------------------------------------------------------- |
|
238 // CPcsKeyMap::InitKeyMappings |
|
239 // Put string for each key into iKeyMapping. |
|
240 // ---------------------------------------------------------------------------- |
|
241 void CPcsKeyMap::InitKeyMappings() |
|
242 { |
|
243 PRINT(_L("Enter CPcsKeyMap::InitKeyMappings")); |
|
244 |
|
245 for (TInt i = 0; i < iAmountOfKeys; ++i) |
|
246 { |
|
247 iKeyMapping << QString(""); |
|
248 } |
|
249 } |
|
250 |
|
251 // ---------------------------------------------------------------------------- |
|
252 // CPcsKeyMap::ConstructLanguageMappings |
|
253 // Fetch keymap for selected languages. |
|
254 // ---------------------------------------------------------------------------- |
|
255 void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType) |
|
256 { |
|
257 PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings")); |
|
258 |
|
259 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
260 TInt count(0); |
|
261 #endif |
|
262 |
|
263 QList<HbInputLanguage> languages = SelectLanguages(); |
|
264 PRINT1(_L("build keymap from %d language(s)"), languages.count()); |
|
265 |
|
266 TInt languageCount = languages.size(); |
|
267 for (TInt lang = 0; lang < languageCount; ++lang) |
|
268 { |
|
269 PRINT2(_L("(%d) handle language %d"), lang, languages[lang].language()); |
|
270 if (IsLanguageSupported(languages[lang].language())) |
|
271 { |
|
272 PRINT2(_L("Constructing keymap for lang=%d,var=%d"), |
|
273 languages[lang].language(), |
|
274 languages[lang].variant()); |
|
275 const HbKeymap* keymap = |
|
276 HbKeymapFactory::instance()->keymap(languages[lang].language(), |
|
277 languages[lang].variant()); |
|
278 if (keymap) |
|
279 { |
|
280 for (TInt key = 0; key < iAmountOfKeys; ++key) |
|
281 { |
|
282 PRINT1(_L("handle key(enum value %d)"), key); // test |
|
283 const HbMappedKey* mappedKey = keymap->keyForIndex(aKeyboardType, key); |
|
284 // 12-key: Most languages don't have mapping for EKeyStar, EKeyHash. |
|
285 // QWERTY: Different languages have different amount of keys, |
|
286 // so mappedKey can be NULL. |
|
287 if (mappedKey) |
|
288 { |
|
289 const QString lowerCase = mappedKey->characters(HbModifierNone); // "abc2.." |
|
290 const QString upperCase = mappedKey->characters(HbModifierShiftPressed); // "ABC2.." |
|
291 const QString charsForKey = lowerCase + upperCase; |
|
292 |
|
293 // Filter out duplicate characters |
|
294 for (TInt i = charsForKey.length() - 1; i >= 0 ; --i) |
|
295 { |
|
296 QChar ch = charsForKey[i]; |
|
297 if (!iKeyMapping[key].contains(ch) && |
|
298 !iHardcodedChars.contains(ch)) |
|
299 { |
|
300 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
301 char ascChar = ch.toAscii(); |
|
302 TChar logChar(ArrayIndexToMappedChar(key).unicode()); |
|
303 |
|
304 if (ascChar == 0) // ch can't be represented in ASCII |
|
305 { |
|
306 PRINT2(_L("CPcsKeyMap: map key(%c) <-> char=0x%x"), |
|
307 logChar, ch); |
|
308 } |
|
309 else |
|
310 { |
|
311 PRINT3(_L("CPcsKeyMap: map key(%c) <-> char='%c'(0x%x)"), |
|
312 logChar, |
|
313 ascChar, |
|
314 ascChar); |
|
315 } |
|
316 ++count; |
|
317 #endif // #if defined(WRITE_PRED_SEARCH_LOGS) |
|
318 iKeyMapping[key] += ch; |
|
319 } |
|
320 } |
|
321 } |
|
322 } |
|
323 } |
|
324 else |
|
325 { |
|
326 PRINT(_L("CPcsKeyMap::ContructKeyboardMapping keymap not found")); |
|
327 } |
|
328 } |
|
329 } |
|
330 |
|
331 #if defined(WRITE_PRED_SEARCH_LOGS) |
|
332 PRINT1(_L("End CPcsKeyMap::ConstructLanguageMappings keymap has %d chars"), count); |
|
333 #endif |
|
334 } |
|
335 |
|
336 // ---------------------------------------------------------------------------- |
|
337 // CPcsKeyMap::IsLanguageSupported |
|
338 // ---------------------------------------------------------------------------- |
|
339 TBool CPcsKeyMap::IsLanguageSupported(QLocale::Language aLanguage) const |
|
340 { |
|
341 return (aLanguage != QLocale::Japanese && aLanguage != QLocale::Chinese); |
|
342 } |
|
343 |
|
344 // ---------------------------------------------------------------------------- |
|
345 // CPcsKeyMap::MappedKeyForChar |
|
346 // Loop all QStrings of iKeyMapping to find one containing the character. |
|
347 // If the character is not mapped, use pad character. |
|
348 // ---------------------------------------------------------------------------- |
|
349 const QChar CPcsKeyMap::MappedKeyForChar(const QChar aChar) const |
|
350 { |
|
351 for (TInt index = 0; index < iAmountOfKeys; ++index) |
|
352 { |
|
353 if (iKeyMapping[index].contains(aChar)) |
|
354 { |
|
355 return ArrayIndexToMappedChar(index); |
|
356 } |
|
357 } |
|
358 |
|
359 #if _DEBUG |
|
360 TUint ch = aChar.unicode(); |
|
361 PRINT2(_L("CPcsKeyMap::MappedKeyForChar no mapping for char '%c' (0x%x)"), |
|
362 ch, ch); |
|
363 #endif |
|
364 return iPadChar; |
|
365 } |
|
366 #endif // #if defined(USE_ORBIT_KEYMAP) |
|
367 |
|
368 // End of file |