|
1 /* |
|
2 * Copyright (c) 2002 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: |
|
15 * Provides the TAknFepInputStateInitialHalfQwertyWesternPredictive methods. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 #include "AknFepUiInputStateInitialHalfQwertyWesternPredictive.h" |
|
31 #include "AknFepUIManagerStateInterface.h" //MAknFepUIManagerStateInterface |
|
32 #include "AknFepManagerUIInterface.h" //MAknFepManagerUIInterface |
|
33 #include "AknFepManager.h" |
|
34 #include "AknFepCaseManager.h" //CAknFepCaseManager |
|
35 |
|
36 #include <PtiDefs.h> |
|
37 #include <PtiEngine.h> |
|
38 |
|
39 // TODO: Remove this include |
|
40 #include <AvkonInternalCRKeys.h> |
|
41 static const TInt KKeyMappingsLength = 32; |
|
42 TAknFepUiInputStateInitialHalfQwertyWesternPredictive::TAknFepUiInputStateInitialHalfQwertyWesternPredictive(MAknFepUIManagerStateInterface* aOwner) |
|
43 //:TAknFepInputStateBase(aOwner), |
|
44 :TAknFepInputStateInitialMultitapBase(aOwner) |
|
45 { |
|
46 iData = 0; |
|
47 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
48 // this is already being done in the base constructor |
|
49 // should not be done again |
|
50 // TPtiTextCase caseMode = ptiengine->Case(); |
|
51 // ptiengine->ClearCurrentWord(); |
|
52 // ptiengine->SetCase(caseMode); |
|
53 ptiengine->SetInputMode( EPtiEngineHalfQwerty ); |
|
54 } |
|
55 |
|
56 TBool TAknFepUiInputStateInitialHalfQwertyWesternPredictive::HandleKeyL(TInt aKey, TKeyPressLength aLength) |
|
57 { |
|
58 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
59 |
|
60 TBool retVal = EFalse; |
|
61 TBuf<KKeyMappingsLength> mappedCharacters; |
|
62 if (iData && (iData != aKey) && fepMan->IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction)) |
|
63 { |
|
64 iOwner->PtiEngine()->CancelTimerActivity(); |
|
65 fepMan->CommitInlineEditL(); |
|
66 iOwner->PtiEngine()->ClearCurrentWord(); |
|
67 fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); |
|
68 iData = 0; |
|
69 // if the current fn key state is FnNext, then clear it. |
|
70 if( !fepMan->IsFlagSet( CAknFepManager::EFlagLongShiftKeyPress ) ) |
|
71 { |
|
72 if( CAknFepFnKeyManager::EFnKeyNext == fepMan->FnKeyState()) |
|
73 { |
|
74 fepMan->SetFnKeyState( CAknFepFnKeyManager::EFnKeyNone ); |
|
75 } |
|
76 } |
|
77 } |
|
78 HandleShiftState(aKey); |
|
79 if((fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed))&& (aKey !=EStdKeyBackspace) && (aKey!=EKeyBackspace)) |
|
80 { |
|
81 if ( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) ) |
|
82 { |
|
83 fepMan->TryRemoveNoMatchesIndicatorL(); |
|
84 } |
|
85 if (fepMan->IsAutoCompleteOn()) |
|
86 { |
|
87 TInt tailLength = 0; |
|
88 iOwner->PtiEngine()->HandleCommandL( EPtiCommandGetAutoCompletionTailLength, &tailLength ); |
|
89 if(tailLength > 0) |
|
90 { |
|
91 // To remove the autocompletion part, the below function is used. |
|
92 // DeleteKeyPress was used earlier. This is removed to fix the bug : |
|
93 // enter characters to show autocompletion part. Now press a |
|
94 // character so that the no matches character is shown. Now press |
|
95 // backspace key, last character is not deleted. |
|
96 fepMan->RemoveSuggestedAdvanceCompletionL(); |
|
97 return ETrue; |
|
98 } |
|
99 } |
|
100 // for long key press do not go to multitap base |
|
101 if( EShortKeyPress == aLength ) |
|
102 { |
|
103 TAknFepInputStateInitialMultitapBase::HandleKeyL(aKey, aLength); |
|
104 } |
|
105 else |
|
106 { |
|
107 mappedCharacters.Zero(); |
|
108 iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey |
|
109 , mappedCharacters, iOwner->PtiEngine()->Case()); |
|
110 fepMan->NewCharacterL(mappedCharacters); |
|
111 fepMan->CommitInlineEditL(); |
|
112 } |
|
113 // cancel the multitap timer if only one character is mapped to it |
|
114 mappedCharacters.Zero(); |
|
115 |
|
116 iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey, mappedCharacters, iOwner->PtiEngine()->Case()); |
|
117 |
|
118 if( mappedCharacters.Length() < 2 ) |
|
119 { |
|
120 iOwner->PtiEngine()->CancelTimerActivity(); |
|
121 } |
|
122 |
|
123 iData = aKey; |
|
124 fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringChrKeyPress); |
|
125 return ETrue; |
|
126 } |
|
127 // for long press of punct key, a stream of characters mapped to |
|
128 // that case should be shown both in predictive and non-predictive mode |
|
129 if ( aLength == ELongKeyPress && aKey == EStdKeyFullStop ) |
|
130 { |
|
131 // Long press should always input fnlower character |
|
132 iOwner->PtiEngine()->SetCase( EPtiCaseFnLower); |
|
133 |
|
134 mappedCharacters.Zero(); |
|
135 iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey |
|
136 , mappedCharacters, iOwner->PtiEngine()->Case()); |
|
137 fepMan->NewCharacterL(mappedCharacters); |
|
138 fepMan->CommitInlineEditL(); |
|
139 return ETrue; |
|
140 } |
|
141 switch (aKey) |
|
142 { |
|
143 case EStdKeyLeftShift: |
|
144 case EStdKeyRightShift: |
|
145 case EStdKeyLeftFunc: |
|
146 { |
|
147 // Handle shift key seperately only if fn state is set. |
|
148 if( CAknFepFnKeyManager::EFnKeyPressed == fepMan->FnKeyState() || |
|
149 CAknFepFnKeyManager::EFnKeyDown == fepMan->FnKeyState() || |
|
150 CAknFepFnKeyManager::EFnKeyForced == fepMan->FnKeyState() || |
|
151 CAknFepFnKeyManager::EFnKeyNext == fepMan->FnKeyState() || |
|
152 CAknFepFnKeyManager::EFnKeyPressedAgain == fepMan->FnKeyState() || |
|
153 CAknFepFnKeyManager::EFnKeyLock == fepMan->FnKeyState()) |
|
154 { |
|
155 fepMan->PtiEngine()->SetCase( EPtiCaseFnLower ); |
|
156 TAknFepInputStateInitialMultitapBase::HandleKeyL(aKey, aLength); |
|
157 // cancel the multitap timer if only one character is mapped to it |
|
158 mappedCharacters.Zero(); |
|
159 iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey, mappedCharacters, iOwner->PtiEngine()->Case()); |
|
160 |
|
161 if( mappedCharacters.Length() < 2 ) |
|
162 { |
|
163 iOwner->PtiEngine()->CancelTimerActivity(); |
|
164 } |
|
165 } |
|
166 } |
|
167 break; |
|
168 |
|
169 case EStdKeyNull: |
|
170 // Take no action if simulated key ends up here |
|
171 break; |
|
172 |
|
173 case EStdKeySpace: //fall through |
|
174 { |
|
175 _LIT(KSpace," "); |
|
176 if( fepMan->FnKeyState() == CAknFepFnKeyManager::EFnKeyNone) |
|
177 { |
|
178 fepMan->StartInlineEditL(); |
|
179 fepMan->UpdateInlineEditL(KSpace,0); |
|
180 fepMan->CommitInlineEditL(); |
|
181 return ETrue; |
|
182 } |
|
183 else |
|
184 { |
|
185 // Most keys activate the entry state and are handled there |
|
186 fepMan->TryCloseUiL(); //expires the multitap timer |
|
187 iOwner->ChangeState(EEntry); |
|
188 fepMan->SendUIActivatedNotification(); |
|
189 } |
|
190 break; |
|
191 } |
|
192 case EStdKeyEnter: |
|
193 case EStdKeyTab: |
|
194 case EStdKeyBackspace: |
|
195 case EStdKeyLeftArrow: |
|
196 case EStdKeyRightArrow: |
|
197 case EStdKeyUpArrow: |
|
198 case EStdKeyDownArrow: |
|
199 { |
|
200 // Navigation keys do not activate the entry state. Instead they are handled by the editor directly. |
|
201 |
|
202 // Asyncronous case update is needed after the editor has handled the key |
|
203 fepMan->SimulateKeyEventL(EKeyF19); |
|
204 if (((aKey == EStdKeyBackspace) || (aKey == EKeyBackspace)) && (fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed))) |
|
205 fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringChrKeyPress); |
|
206 } |
|
207 break; |
|
208 default: |
|
209 { |
|
210 // Most keys activate the entry state and are handled there |
|
211 fepMan->TryCloseUiL(); //expires the multitap timer |
|
212 iOwner->ChangeState(EEntry); |
|
213 fepMan->SendUIActivatedNotification(); |
|
214 } |
|
215 } |
|
216 |
|
217 if ( aKey == EStdKeyEnter) |
|
218 { |
|
219 iData = 0; |
|
220 return 0; |
|
221 } |
|
222 if( !iOwner->PtiEngine()->IsValidKey((TPtiKey)aKey)) |
|
223 { |
|
224 iData = 0; |
|
225 fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); |
|
226 fepMan->PtiEngine()->CancelTimerActivity(); |
|
227 |
|
228 return retVal; |
|
229 } |
|
230 |
|
231 iData = aKey; |
|
232 |
|
233 return retVal; |
|
234 } |
|
235 |
|
236 void TAknFepUiInputStateInitialHalfQwertyWesternPredictive::KeyTimerExpired() |
|
237 { |
|
238 if (iData) |
|
239 { |
|
240 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
241 CAknFepCaseManager* caseMan = iOwner->CaseMan(); |
|
242 |
|
243 TAknFepInputStateInitialMultitapBase::KeyTimerExpired(); |
|
244 |
|
245 caseMan->UpdateCase(ENullNaviEvent); |
|
246 fepMan->ClearFlag( CAknFepManager::EFlagInsideMultitapInlineEditingTransaction ); |
|
247 |
|
248 iData = 0; |
|
249 |
|
250 // if the current fn key state is FnNext, then clear it. |
|
251 if( !fepMan->IsFlagSet( CAknFepManager::EFlagLongShiftKeyPress ) ) |
|
252 { |
|
253 if( CAknFepFnKeyManager::EFnKeyNext == fepMan->FnKeyState()) |
|
254 { |
|
255 // This cannot be done in fn manager. It should happen only |
|
256 // on timer expiry -> for shift key multitapping in fn mode |
|
257 // when prediction is ON. |
|
258 fepMan->SetFnKeyState( CAknFepFnKeyManager::EFnKeyNone ); |
|
259 } |
|
260 } |
|
261 } |
|
262 } |
|
263 void TAknFepUiInputStateInitialHalfQwertyWesternPredictive::HandleShiftState( TInt aKey ) |
|
264 { |
|
265 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
266 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
267 CAknFepCaseManager* caseMan = iOwner->CaseMan(); |
|
268 CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState(); |
|
269 TPtiTextCase shiftedCase; |
|
270 if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone) |
|
271 { |
|
272 shiftedCase = EPtiCaseFnLower; |
|
273 } |
|
274 else |
|
275 { |
|
276 shiftedCase= EPtiCaseLower; |
|
277 } |
|
278 |
|
279 // Find out if the key is alphabetic |
|
280 TBuf<KKeyMappingsLength> keyMappings; |
|
281 ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseUpper ); |
|
282 TBool isAlpha = ( keyMappings.Length() && TChar(keyMappings[0]).IsAlpha() ); |
|
283 |
|
284 if (isAlpha && (fnKeyState == CAknFepFnKeyManager::EFnKeyNone)) |
|
285 { |
|
286 switch ( caseMan->CurrentCase() ) |
|
287 { |
|
288 case EAknEditorTextCase: |
|
289 { |
|
290 // Alphabetic characters are always capitalized in "Abc" mode |
|
291 // unless the shift is pressed |
|
292 if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) ) |
|
293 { |
|
294 shiftedCase = EPtiCaseUpper; |
|
295 } |
|
296 } |
|
297 break; |
|
298 |
|
299 case EAknEditorLowerCase: |
|
300 { |
|
301 // Pressing shift enters uppercae letters in the "abc" mode |
|
302 if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) ) |
|
303 { |
|
304 shiftedCase = EPtiCaseUpper; |
|
305 } |
|
306 } |
|
307 break; |
|
308 |
|
309 case EAknEditorUpperCase: |
|
310 { |
|
311 // In the "ABC" mode (capslock mode) the letters are uppercased |
|
312 // unless the shift is pressed |
|
313 if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) ) |
|
314 { |
|
315 shiftedCase = EPtiCaseUpper; |
|
316 } |
|
317 } |
|
318 break; |
|
319 |
|
320 default: |
|
321 break; |
|
322 } |
|
323 |
|
324 |
|
325 } |
|
326 else |
|
327 { |
|
328 // non-alphabetic keys are shifted if and only if shift is pressed, no matter what is the input state |
|
329 if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) && (fnKeyState == CAknFepFnKeyManager::EFnKeyNone)) |
|
330 { |
|
331 shiftedCase = EPtiCaseUpper; |
|
332 } |
|
333 else if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) && (fnKeyState != CAknFepFnKeyManager::EFnKeyNone)) |
|
334 { |
|
335 shiftedCase = EPtiCaseFnUpper; |
|
336 } |
|
337 } |
|
338 |
|
339 |
|
340 // Handle the Chr key state |
|
341 if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) ) |
|
342 { |
|
343 // Chr key is pressed down. Chr mode is used. |
|
344 if (shiftedCase == EPtiCaseLower) |
|
345 { |
|
346 shiftedCase = EPtiCaseChrLower; |
|
347 } |
|
348 else if (shiftedCase == EPtiCaseUpper) |
|
349 { |
|
350 shiftedCase = EPtiCaseChrUpper; |
|
351 } |
|
352 } |
|
353 |
|
354 ptiengine->SetCase(shiftedCase); |
|
355 |
|
356 fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringShiftKeyPress); |
|
357 }// End of file |