|
1 /* |
|
2 * Copyright (c) 2002-2004 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 CAknFepKeyCatcher methods. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 #include <eikenv.h> |
|
31 #include <eikappui.h> //iEikonEnv |
|
32 #include <e32keys.h> //keys |
|
33 #include <uikon.hrh> //keys |
|
34 |
|
35 #include "AknFepKeyCatcher.h" |
|
36 #include "AknFepManager.h" |
|
37 #include "AknFepGlobalEnums.h" |
|
38 #include "AknFepPanic.h" |
|
39 #include "AknFepPluginManager.h" |
|
40 #include <AknDef.h> |
|
41 #include <PtiEngine.h> |
|
42 #include <PtiDefs.h> //keys |
|
43 #include <featmgr.h> //FeatureManager |
|
44 #include <AvkonInternalCRKeys.h> |
|
45 |
|
46 LOCAL_C void FepObserverHandleCompletionOfTransactionL(MCoeFepObserver& aFepObserver) |
|
47 { |
|
48 aFepObserver.HandleCompletionOfTransactionL(); |
|
49 } |
|
50 |
|
51 CAknFepKeyCatcherInterface::~CAknFepKeyCatcherInterface() |
|
52 { |
|
53 } |
|
54 |
|
55 void CAknFepKeyCatcherInterface::HandleChangeInFocus() |
|
56 { |
|
57 } |
|
58 |
|
59 CAknFepKeyCatcher* CAknFepKeyCatcher::NewL(CAknFepManager& aFepMan) |
|
60 { |
|
61 CAknFepKeyCatcher* self=new(ELeave) CAknFepKeyCatcher(aFepMan); |
|
62 CleanupStack::PushL(self); |
|
63 self->ConstructL(); |
|
64 CleanupStack::Pop(); //self |
|
65 return self; |
|
66 } |
|
67 |
|
68 CAknFepKeyCatcher::~CAknFepKeyCatcher() |
|
69 { |
|
70 CloseWindow(); |
|
71 if(NULL != iEikonEnv->EikAppUi()) |
|
72 { |
|
73 iEikonEnv->EikAppUi()->RemoveFromStack(this); |
|
74 #ifdef RD_SCALABLE_UI_V2 |
|
75 (CEikonEnv::Static())->RemoveMessageMonitorObserver(*this); |
|
76 #endif //RD_SCALABLE_UI_V2 |
|
77 } |
|
78 } |
|
79 |
|
80 TKeyResponse CAknFepKeyCatcher::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aEventCode) |
|
81 { |
|
82 |
|
83 #ifdef RD_SCALABLE_UI_V2 |
|
84 if (aEventCode == EEventKeyUp && |
|
85 aKeyEvent.iScanCode == EStdKeyNo) |
|
86 { |
|
87 iFepMan.HandleEndKeyL(); |
|
88 } |
|
89 #endif //RD_SCALABLE_UI_V2 |
|
90 // Temporary solution for Disable key tone when press key in Virtual ITUT |
|
91 iFepMan.NeedDisableKeySound(aKeyEvent, aEventCode); |
|
92 // sort out if we're doing long or short presses... |
|
93 TKeyPressLength length = aKeyEvent.iRepeats ? ELongKeyPress : EShortKeyPress; |
|
94 if (iKeyCatcherState == EAknFepStateNull) |
|
95 { |
|
96 if (aEventCode == EEventKeyUp && iLongPressedScanCode == aKeyEvent.iScanCode) |
|
97 { |
|
98 // An editor has lost focus during long key press (for example SCT popup |
|
99 // is shown during long keypress of star key). |
|
100 // EFlagLongKeyPressHandled needs to be reseted also in this case. |
|
101 ClearFlag(EFlagLongKeyPressHandled); |
|
102 iLongPressedScanCode = 0; |
|
103 } |
|
104 if((aEventCode == EEventKeyDown) && (aKeyEvent.iScanCode==EStdKeyRightShift) |
|
105 && (iFepMan.KeyboardLayout()== EPtiKeyboard12Key) && !iFepMan.Japanese() |
|
106 && !iFepMan.IsChineseInputLanguage() ) |
|
107 { |
|
108 iFepMan.SetCcpuFlag(CAknFepManager::ECcpuStateShiftkeyWasPressedBeforeLosingFocus); |
|
109 } |
|
110 else if ((aEventCode == EEventKeyUp) && (aKeyEvent.iScanCode==EStdKeyRightShift) |
|
111 && (iFepMan.KeyboardLayout()== EPtiKeyboard12Key) |
|
112 && iFepMan.IsCcpuFlagSet(CAknFepManager::ECcpuStateShiftkeyWasPressedBeforeLosingFocus)) |
|
113 { |
|
114 iFepMan.ClearCcpuFlag(CAknFepManager::ECcpuStateShiftkeyWasPressedBeforeLosingFocus); |
|
115 } |
|
116 |
|
117 TInt keyCode = aKeyEvent.iCode; |
|
118 if (keyCode == EKeyF19 || keyCode == EKeyF22 || |
|
119 keyCode == EKeyF23 || keyCode == EKeyF24 ) |
|
120 { |
|
121 // Internal FEP key events that are simulated by FEP are always |
|
122 // also consumed by FEP. In this situation FEP has simulated the |
|
123 // key event but the editor is unfocused right after. |
|
124 return EKeyWasConsumed; |
|
125 } |
|
126 // FEP does not handle any keyevents if there are not any FEP aware editor focused, except shift key. |
|
127 // Notice that shift key is handled only if CAknFepKeyCatcher is constructed by focusing some editor. |
|
128 |
|
129 if (iFepMan.HashKeySelectionInUse()) |
|
130 { |
|
131 // Hash key selection should work also with uneditable editors, therefore |
|
132 // we need to fake it as a shift key press here. |
|
133 if (aKeyEvent.iScanCode == EStdKeyHash) |
|
134 { |
|
135 if (aEventCode == EEventKeyUp) |
|
136 { |
|
137 if (iFepMan.IsFlagSet(CAknFepManager::EFlagLongShiftKeyPress)) |
|
138 { |
|
139 // We need to generate real shift up event for editor to |
|
140 // cancel ccpu-mode. |
|
141 TKeyEvent ccpuStart = {0, EStdKeyLeftShift, 0, 0}; |
|
142 CCoeEnv::Static()->SimulateKeyEventL(ccpuStart, aEventCode); |
|
143 } |
|
144 else |
|
145 { |
|
146 // CCpu-mode was not yet activated. Just cancel the timer. |
|
147 iFepMan.CancelShiftKeyTimer(); |
|
148 } |
|
149 return EKeyWasNotConsumed; |
|
150 } |
|
151 else if (aEventCode == EEventKeyDown) |
|
152 { |
|
153 return iFepMan.HandleShiftKeyEventL(aEventCode); |
|
154 } |
|
155 } |
|
156 } |
|
157 |
|
158 if( keyCode == EKeyEscape ) |
|
159 { |
|
160 return iFepMan.HandleKeyEventL(keyCode, length); |
|
161 } |
|
162 |
|
163 if ((aKeyEvent.iScanCode==EStdKeyRightShift || aKeyEvent.iScanCode==EStdKeyLeftShift)) |
|
164 { |
|
165 if (aEventCode == EEventKeyUp) |
|
166 { |
|
167 iFepMan.SetExtendedFlag(CAknFepManager::EExtendedFlagShiftReleasedOnPopup); |
|
168 } |
|
169 else |
|
170 { |
|
171 iFepMan.ClearExtendedFlag(CAknFepManager::EExtendedFlagShiftReleasedOnPopup); |
|
172 } |
|
173 } |
|
174 else |
|
175 { |
|
176 return EKeyWasNotConsumed; |
|
177 } |
|
178 } |
|
179 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
180 if(iKeyCatcherState != EAknFepStateNull) |
|
181 { |
|
182 if(iFepMan.IsFnKeyMapped() && |
|
183 (iFepMan.HandleFnKeyEventL( aKeyEvent, aEventCode ) == EKeyWasConsumed)) |
|
184 { |
|
185 return EKeyWasConsumed; |
|
186 } |
|
187 |
|
188 } |
|
189 #endif |
|
190 |
|
191 if ( aEventCode == EEventKeyUp && |
|
192 aKeyEvent.iScanCode == EStdKeyHash && |
|
193 iFepMan.IsExtendedFlagSet(CAknFepManager::EExtendedFlagShortPressHashKey) ) |
|
194 { |
|
195 // We are here because of short press of has key. Since, we had consumed |
|
196 // short press of hash key, we re-simulate is again, so that the respective |
|
197 // application can handle it as per their need. |
|
198 |
|
199 TKeyEvent keyHash = {EPtiKeyHash, EStdKeyHash, 0, 0}; |
|
200 CCoeEnv::Static()->SimulateKeyEventL(keyHash, EEventKey); |
|
201 iFepMan.ClearExtendedFlag(CAknFepManager::EExtendedFlagShortPressHashKey); |
|
202 } |
|
203 // Check for the Wireless Keyboard Modifier Flag. |
|
204 const TUint KModifierExternalKeyboard = 0x00200000; |
|
205 if ( aKeyEvent.iModifiers & KModifierExternalKeyboard ) |
|
206 { |
|
207 if ( iFepMan.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction | |
|
208 CAknFepManager::EFlagInsideMultitapInlineEditingTransaction) ) |
|
209 { |
|
210 if (iFepMan.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) |
|
211 { |
|
212 // Remove any no matching word indicator. |
|
213 iFepMan.TryRemoveNoMatchesIndicatorL(); |
|
214 } |
|
215 // Ensure the CBA is in the default state. |
|
216 iFepMan.UpdateCbaL(NULL); |
|
217 // Close FEP UI, commit the inline edit and show the cursor. |
|
218 iFepMan.TryCloseUiL(); |
|
219 } |
|
220 // Allow the key through to the underlying control. |
|
221 return EKeyWasNotConsumed; |
|
222 } |
|
223 |
|
224 TKeyResponse retCode; |
|
225 if (iFepMan.HandleCcpuModeKeyEventL(aKeyEvent, aEventCode, |
|
226 retCode, IsFlagSet(EFlagLongKeyPressHandled))) |
|
227 { |
|
228 return retCode; |
|
229 } |
|
230 |
|
231 #ifdef RD_SCALABLE_UI_V2 |
|
232 // Set text selection when tap arrow keys |
|
233 if(iFepMan.HandleSelModeArrowKeyEventL(aKeyEvent, aEventCode, retCode)) |
|
234 { |
|
235 return retCode; |
|
236 } |
|
237 #endif //RD_SCALABLE_UI_V2 |
|
238 |
|
239 |
|
240 |
|
241 if ( ( aKeyEvent.iModifiers & EModifierCtrl |
|
242 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
243 || aKeyEvent.iScanCode==EStdKeyRightCtrl |
|
244 || aKeyEvent.iScanCode==EStdKeyLeftCtrl |
|
245 #endif |
|
246 ) |
|
247 && aKeyEvent.iScanCode != EStdKeyBackspace |
|
248 && aKeyEvent.iScanCode != EStdKeyDelete ) |
|
249 {// Chinese qwerty increment input mode by Ctrl+Shift |
|
250 return iFepMan.HandleQwertyControlKeyEventL(aKeyEvent, aEventCode); |
|
251 } |
|
252 |
|
253 // handling hash key event in japanese input |
|
254 if (iFepMan.IsFeatureSupportedJapanese() |
|
255 && aKeyEvent.iScanCode==EStdKeyHash && !iFepMan.IsOnlyNumericPermitted()) |
|
256 { |
|
257 return HandleHashKeyJapaneseL(aKeyEvent, aEventCode); |
|
258 } |
|
259 |
|
260 // Let FepMan handle chr key |
|
261 if (aKeyEvent.iScanCode==EStdKeyLeftFunc) |
|
262 { |
|
263 if (iFepMan.HandleQwertyChrKeyEventL(aEventCode)) |
|
264 { |
|
265 return EKeyWasConsumed; |
|
266 } |
|
267 } |
|
268 //let FepMan handle shifts |
|
269 if ( aKeyEvent.iScanCode==EStdKeyRightShift || aKeyEvent.iScanCode |
|
270 ==EStdKeyLeftShift ) |
|
271 { |
|
272 // phrase creation |
|
273 if ( iFepMan.IsPinyinPhraseCreation() ) |
|
274 { |
|
275 return EKeyWasConsumed; |
|
276 } |
|
277 else |
|
278 { |
|
279 return iFepMan.HandleShiftKeyEventL( aEventCode ); |
|
280 } |
|
281 } |
|
282 |
|
283 if (iFepMan.Japanese()) |
|
284 { |
|
285 if ((aKeyEvent.iScanCode==EStdKeyDevice0) || (aKeyEvent.iScanCode==EStdKeyDevice1)) |
|
286 { |
|
287 if (aEventCode != EEventKey) |
|
288 { |
|
289 return EKeyWasNotConsumed; |
|
290 } |
|
291 } |
|
292 } |
|
293 |
|
294 if (aEventCode==EEventKeyUp) |
|
295 { |
|
296 if ( iLongPressedScanCode == aKeyEvent.iScanCode ) |
|
297 { |
|
298 ClearFlag(EFlagLongKeyPressHandled); |
|
299 iLongPressedScanCode = 0; |
|
300 } |
|
301 |
|
302 if ( (EStdKeyDelete == aKeyEvent.iScanCode || |
|
303 EStdKeyBackspace == aKeyEvent.iScanCode)) |
|
304 { |
|
305 iFepMan.SetLongClearAfterCloseUI(EFalse); |
|
306 } |
|
307 |
|
308 iFepMan.ClearFlag(CAknFepManager::EFlagCharacterAdded); |
|
309 } |
|
310 |
|
311 |
|
312 //let FepMan to try to handle Thai 0 key |
|
313 TBool thai0Keyhandling = EFalse; |
|
314 |
|
315 if (aKeyEvent.iScanCode==EPtiKey0 |
|
316 && (!(aKeyEvent.iModifiers & EModifierSpecial) // If the key is produced by hardware key |
|
317 // In VKB and FSQ latin range 0 could be input with virtual keyboard |
|
318 || (iFepMan.PluginInputMode() != EPluginInputModeFSQ |
|
319 && iFepMan.PluginInputMode() != EPluginInputModeVkb))) |
|
320 { |
|
321 if (iFepMan.HandleThai0KeyEvent(aEventCode, length, thai0Keyhandling) == EKeyWasConsumed) |
|
322 { |
|
323 return (EKeyWasConsumed); // Eats some key events to find out when o key goes up |
|
324 } |
|
325 if (thai0Keyhandling) |
|
326 { |
|
327 if(length == ELongKeyPress) |
|
328 { |
|
329 SetFlag(EFlagLongKeyPressHandled); |
|
330 iLongPressedScanCode = aKeyEvent.iScanCode; |
|
331 } |
|
332 return (iFepMan.HandleKeyEventL(EPtiKey0, length)); |
|
333 } |
|
334 } |
|
335 TInt keyCode = aKeyEvent.iCode; |
|
336 TKeyResponse response = EKeyWasNotConsumed; |
|
337 |
|
338 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
339 if ((aKeyEvent.iScanCode == EStdKeyNkpAsterisk ||aKeyEvent.iScanCode == EPtiKeyStar )&& iFepMan.KeyboardLayout() == EPtiKeyboard12Key) |
|
340 { |
|
341 //For Special Editors like Java numeric editor, EventKeyUp is allowed to flow through FEP. |
|
342 //All other events for Special Editor is not consumed by FEP. |
|
343 if(iFepMan.IsSpecialNumericEditor() && iFepMan.IsOnlyNumericPermitted() && aEventCode != EEventKeyUp) |
|
344 { |
|
345 return EKeyWasNotConsumed; |
|
346 } |
|
347 #ifdef FF_HOME_SCREEN_EASY_DIALING |
|
348 // If Easy Dialing Feature in Phone Idle is turned on then, |
|
349 // phoneIdleinEasyDialingNumericMode is set to True |
|
350 TBool phoneIdleinEasyDialingNumericMode = EFalse; |
|
351 phoneIdleinEasyDialingNumericMode = |
|
352 (iFepMan.EditorType() == CAknExtendedInputCapabilities::EPhoneNumberEditor) && |
|
353 (iFepMan.InputMode() == ENumber || iFepMan.InputMode() == ENativeNumber); |
|
354 #endif |
|
355 // For all Numeric Editors, only Event Key is allowed to flow through |
|
356 // When Easy Dialing is on, the editor in not numeric, even though in this scenario only Event key is allowed throug FEP |
|
357 if ( (iFepMan.IsOnlyNumericPermitted() |
|
358 #ifdef FF_HOME_SCREEN_EASY_DIALING |
|
359 || phoneIdleinEasyDialingNumericMode |
|
360 #endif |
|
361 )&& |
|
362 aEventCode != EEventKey) |
|
363 { |
|
364 return EKeyWasConsumed; |
|
365 } |
|
366 |
|
367 /* |
|
368 For Long Key press: |
|
369 We only have Event Key, and FEP handles it for launching SCT. |
|
370 For short key presses: |
|
371 For Non numeric editors: |
|
372 EventDown and Eventkey: |
|
373 FEP consumes it - if FEP is in Inline edit or it can launch SCT. It is consumed by below check and does not flow further. |
|
374 Else, these events flow through FEP. Later decision is made to consume the event or not. |
|
375 EventUpKey: |
|
376 FEP consumes it - if FEP is in Inline edit or it can launch SCT. Desired functionality is achieved after flowing through FEP. |
|
377 Else, these events flow through FEP. Later decision is made to consume the event or not. |
|
378 For Numeric Editors: |
|
379 FEP handles EventKey for star key looping or launching sct. Other events does not reach here. |
|
380 */ |
|
381 if ( length != ELongKeyPress && |
|
382 aEventCode != EEventKeyUp && |
|
383 ( |
|
384 iFepMan.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) || |
|
385 !iFepMan.IsAbleToLaunchSCT() |
|
386 ) && |
|
387 (!iFepMan.IsOnlyNumericPermitted() |
|
388 #ifdef FF_HOME_SCREEN_EASY_DIALING |
|
389 && !phoneIdleinEasyDialingNumericMode |
|
390 #endif |
|
391 ) |
|
392 ) |
|
393 { |
|
394 return EKeyWasConsumed; |
|
395 } |
|
396 keyCode = EPtiKeyStar; |
|
397 } |
|
398 else |
|
399 #endif |
|
400 //only interested in EventKeys apart from for the shift key |
|
401 if (aEventCode!=EEventKey) |
|
402 { |
|
403 // For Japanese, don't pass EEventKeyUp and EEventKeyDown |
|
404 // event to application side if we are inputting Hiragana/Kanji. |
|
405 if (iFepMan.Japanese() && iKeyCatcherState == EAknFepStateUIActive) |
|
406 { |
|
407 // arrow keys |
|
408 if (aKeyEvent.iScanCode == EStdKeyDownArrow |
|
409 || aKeyEvent.iScanCode == EStdKeyRightArrow |
|
410 || aKeyEvent.iScanCode == EStdKeyLeftArrow |
|
411 || aKeyEvent.iScanCode == EStdKeyUpArrow) |
|
412 { |
|
413 return EKeyWasConsumed; |
|
414 } |
|
415 } |
|
416 |
|
417 if ((iKeyCatcherState == EAknFepStateInitial) |
|
418 && (aEventCode == EEventKeyUp) && (aKeyEvent.iScanCode == EStdKeyBackspace)) |
|
419 { |
|
420 CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleCompletionOfTransactionL); |
|
421 } |
|
422 |
|
423 return EKeyWasNotConsumed; |
|
424 } |
|
425 |
|
426 //if we've done a long press, and we get repeats, don't pass it on to the fep man. |
|
427 |
|
428 if (!(iFepMan.Japanese()&& |
|
429 (aKeyEvent.iCode == EKeyLeftArrow |
|
430 || aKeyEvent.iCode == EKeyRightArrow |
|
431 || aKeyEvent.iCode == EKeyDownArrow |
|
432 || aKeyEvent.iCode == EKeyUpArrow))) |
|
433 { |
|
434 if (!(aKeyEvent.iCode == EKeyPrevious || aKeyEvent.iCode == EKeyNext)) |
|
435 { |
|
436 if (IsFlagSet(EFlagLongKeyPressHandled)&&(aKeyEvent.iRepeats)) |
|
437 { |
|
438 return EKeyWasConsumed; |
|
439 } |
|
440 } |
|
441 } |
|
442 |
|
443 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
444 CAknFepFnKeyManager::TFnKeyState fnKeyStateBeforeKey = iFepMan.FnKeyState(); |
|
445 |
|
446 // the short key press was blocked, don't allow the long key press to go through |
|
447 if ( IsFlagSet(EFlagBlockAllLongKeyPressEvents) && length == ELongKeyPress |
|
448 && !IsNaviKey(aKeyEvent.iCode) ) |
|
449 { |
|
450 return EKeyWasNotConsumed; |
|
451 } |
|
452 // if the editor has no free space |
|
453 // the key press is a valid one |
|
454 // (it is not for eg. a simulated key press for case change) |
|
455 // we are not in between multitapping |
|
456 // block the subsequent long key press also |
|
457 if ( length == EShortKeyPress && !iFepMan.EditorHasFreeSpace() |
|
458 && iFepMan.PtiEngine()->IsValidKey((TPtiKey)aKeyEvent.iScanCode) |
|
459 && !iFepMan.IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction) ) |
|
460 { |
|
461 SetFlag(EFlagBlockAllLongKeyPressEvents); // block the subsequent long key press also |
|
462 return EKeyWasNotConsumed; |
|
463 } |
|
464 else |
|
465 { |
|
466 ClearFlag(EFlagBlockAllLongKeyPressEvents); |
|
467 } |
|
468 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
469 if (iFepMan.HandleQwertyKeyEventL(aKeyEvent, response)) |
|
470 { |
|
471 |
|
472 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
473 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
474 ClearFlag(EFlagBlockAllLongKeyPressEvents); |
|
475 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
476 TPtiKeyboardType keyboardType = iFepMan.KeyboardLayout(); |
|
477 if( (length == ELongKeyPress) && |
|
478 ( |
|
479 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
480 iFepMan.LongPressNumberEntryOnQwerty()|| |
|
481 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
482 (keyboardType == EPtiKeyboardHalfQwerty)) && |
|
483 iFepMan.KeyMapsDifferentCharacterWithFn( (TPtiKey)aKeyEvent.iScanCode ) && |
|
484 fnKeyStateBeforeKey == CAknFepFnKeyManager::EFnKeyNone ) |
|
485 { |
|
486 SetFlag(EFlagLongKeyPressHandled); // don't allow any more long presses to go through. |
|
487 iLongPressedScanCode = aKeyEvent.iScanCode; |
|
488 } |
|
489 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
490 return response; |
|
491 } |
|
492 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
493 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
494 // key was not handled because there is no space in editor |
|
495 else if( !iFepMan.EditorHasFreeSpace() && ( iFepMan.KeyboardLayout() != EPtiKeyboard12Key)) |
|
496 { |
|
497 SetFlag(EFlagBlockAllLongKeyPressEvents); |
|
498 } |
|
499 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__ |
|
500 #endif // RD_INTELLIGENT_TEXT_INPUT |
|
501 if (iFepMan.IsFlagSet(CAknFepManager::EFlagShiftKeyDepressed)) |
|
502 { |
|
503 // If shift (ie. edit-key) is pressed in itu-t mode, block all the numeric keys, |
|
504 // otherwise they will be routed to edwin and prodec unwanted character. |
|
505 if ((aKeyEvent.iScanCode >= EPtiKey1 && aKeyEvent.iScanCode <= EPtiKey9) || |
|
506 aKeyEvent.iScanCode == EPtiKey0 || aKeyEvent.iScanCode == EStdKeyFullStop ) |
|
507 { |
|
508 return EKeyWasConsumed; |
|
509 } |
|
510 } |
|
511 |
|
512 if (iFepMan.IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed)) |
|
513 { |
|
514 if ((aKeyEvent.iScanCode >= EPtiKeyQwertyA && aKeyEvent.iScanCode <= EPtiKeyQwertyZ) || |
|
515 aKeyEvent.iScanCode == EStdKeyFullStop ) |
|
516 { |
|
517 return EKeyWasConsumed; |
|
518 } |
|
519 } |
|
520 |
|
521 // bulk of the selection. |
|
522 switch(keyCode) |
|
523 { |
|
524 case EKeyLeftArrow: //fall through |
|
525 case EKeyRightArrow: |
|
526 case EKeyDownArrow: |
|
527 case EKeyUpArrow: |
|
528 response = iFepMan.HandleKeyEventL(keyCode, length); |
|
529 break; |
|
530 case EKeyCBA1: |
|
531 { |
|
532 TInt inputMode = iFepMan.InputMode(); |
|
533 if ( iKeyCatcherState == EAknFepStateUIActive && |
|
534 inputMode >= ECangJie && inputMode <= EStroke ) |
|
535 { |
|
536 // Left softkey does not have functionality in Chinese input modes when |
|
537 // FEP UI is active. |
|
538 // phrase creation |
|
539 iFepMan.HandleKeyEventL( keyCode, length ); |
|
540 response = EKeyWasConsumed; |
|
541 break; |
|
542 } |
|
543 } |
|
544 //fall through |
|
545 case EKeyOK: |
|
546 case EKeyCBA2: |
|
547 case EPtiKey0: |
|
548 case EPtiKey1: |
|
549 case EPtiKey2: |
|
550 case EPtiKey3: |
|
551 case EPtiKey4: |
|
552 case EPtiKey5: |
|
553 case EPtiKey6: |
|
554 case EPtiKey7: |
|
555 case EPtiKey8: |
|
556 case EPtiKey9: |
|
557 case EPtiKeyStar: |
|
558 case EPtiKeyHash: |
|
559 case EKeyEscape: |
|
560 if(length == ELongKeyPress) |
|
561 { |
|
562 SetFlag(EFlagLongKeyPressHandled); // don't allow any more long presses to go through. |
|
563 iLongPressedScanCode = aKeyEvent.iScanCode; |
|
564 } |
|
565 //fall through |
|
566 case EKeyBackspace: |
|
567 case EKeyDelete: |
|
568 |
|
569 // This check is added to handle the case when user enters a consonant |
|
570 // followed by a halant, follwed by digit using long key press. |
|
571 // When backspace is done, first time, the digit gets deleted. |
|
572 // Second time, only halant should be deleted. But since ZWS is |
|
573 // present, the entire syllable gets deleted. Hence we forcefully |
|
574 // remove the ZWS. |
|
575 |
|
576 if( keyCode == EKeyBackspace && |
|
577 iFepMan.PreviousChar( ETrue ) == ( ZERO_WIDTH_SPACE ) ) |
|
578 { |
|
579 // Remove the Zero Width Space |
|
580 iFepMan.RemovePreviousCharacterL(); |
|
581 } |
|
582 |
|
583 #ifdef RD_MARATHI |
|
584 if( ( keyCode == EKeyBackspace ) && |
|
585 iFepMan.PreviousChar( ETrue ) == ( ZERO_WIDTH_JOINER )) |
|
586 { |
|
587 // Remove the Zero Width Joiner |
|
588 iFepMan.RemovePreviousCharacterL(); |
|
589 } |
|
590 #endif // RD_MARATHI |
|
591 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
592 if( keyCode == EKeyBackspace && |
|
593 ( (aKeyEvent.iModifiers & EModifierLeftShift) || |
|
594 (aKeyEvent.iModifiers & EModifierRightShift) || |
|
595 (aKeyEvent.iModifiers & EModifierShift) )) |
|
596 { |
|
597 keyCode = EKeyDelete; |
|
598 } |
|
599 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
600 response = iFepMan.HandleKeyEventL(keyCode, length, aEventCode ); |
|
601 break; |
|
602 case EKeyF19: // Fep simulated event to asynchronously update the case. |
|
603 case EKeyF22: |
|
604 case EKeyF23: |
|
605 case EKeyF24: |
|
606 response = iFepMan.HandleKeyEventL(keyCode, length); |
|
607 break; |
|
608 case EKeyPowerOff: |
|
609 case EKeyPhoneEnd: |
|
610 case EKeyApplication: |
|
611 #ifndef RD_INTELLIGENT_TEXT_INPUT |
|
612 // To rip off suggested word completion when user press END / APPLICATION |
|
613 if(iFepMan.IsAutoCompleteOn()) |
|
614 { |
|
615 iFepMan.RemoveSuggestedCompletionL(); |
|
616 } |
|
617 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
618 #ifdef RD_INTELLIGENT_TEXT_INPUT |
|
619 response = iFepMan.HandleKeyEventL(keyCode, length); |
|
620 #endif //RD_INTELLIGENT_TEXT_INPUT |
|
621 break; |
|
622 case EKeyPhoneSend: |
|
623 // handling phone send key event in japanese input |
|
624 if (iFepMan.IsFeatureSupportedJapanese()) |
|
625 { |
|
626 if (iFepMan.Japanese() && iKeyCatcherState == EAknFepStateUIActive) |
|
627 { |
|
628 // Ensure the CBA is in the default state. |
|
629 iFepMan.UpdateCbaL(NULL); |
|
630 // Close FEP UI, commit the inline edit and show the cursor. |
|
631 iFepMan.TryCloseUiL(); |
|
632 } |
|
633 } |
|
634 break; |
|
635 default: |
|
636 break; |
|
637 } |
|
638 |
|
639 return response; |
|
640 } |
|
641 |
|
642 void CAknFepKeyCatcher::SetState(const enum TAknFepManagerState aState) |
|
643 { |
|
644 iKeyCatcherState=aState; |
|
645 } |
|
646 |
|
647 CAknFepKeyCatcher::CAknFepKeyCatcher(CAknFepManager& aFepMan) |
|
648 : iFepMan(aFepMan), |
|
649 iKeyCatcherState(EAknFepStateNull) |
|
650 { |
|
651 } |
|
652 |
|
653 void CAknFepKeyCatcher::ConstructL() |
|
654 { |
|
655 // Set up fep key catching control - front window, null size, non-focusing |
|
656 CreateWindowL(); |
|
657 SetFocusing(EFalse); |
|
658 RWindow& window=Window(); |
|
659 window.SetOrdinalPosition(0, ECoeWinPriorityFep); |
|
660 TPoint fepControlPos(0, 0); |
|
661 SetExtent(fepControlPos, TSize(0,0)); //null size |
|
662 window.SetExtent(fepControlPos, TSize(0,0)); |
|
663 window.SetNonFading(ETrue); |
|
664 if(NULL == iEikonEnv->EikAppUi()) |
|
665 { |
|
666 User::Leave(KErrCancel); |
|
667 } |
|
668 iEikonEnv->EikAppUi()->AddToStackL(this, ECoeStackPriorityFep, |
|
669 ECoeStackFlagRefusesFocus|ECoeStackFlagSharable); |
|
670 #ifdef RD_SCALABLE_UI_V2 |
|
671 (CEikonEnv::Static())->AddMessageMonitorObserverL(*this); |
|
672 #endif //RD_SCALABLE_UI_V2 |
|
673 SetBlank(); |
|
674 } |
|
675 |
|
676 TKeyResponse CAknFepKeyCatcher::HandleHashKeyJapaneseL(const TKeyEvent& aKeyEvent, |
|
677 TEventCode aEventCode) |
|
678 { |
|
679 // handling hash keypress event only |
|
680 __ASSERT_DEBUG(aKeyEvent.iScanCode==EStdKeyHash, AknFepPanic(EAknFepPanicNotSupportKey)); |
|
681 |
|
682 // No handling case |
|
683 if (aEventCode == EEventKeyDown |
|
684 || iKeyCatcherState == EAknFepStateNull) |
|
685 { |
|
686 if (aEventCode == EEventKeyUp) |
|
687 { |
|
688 ClearFlag(EFlagLongKeyPressHandled); |
|
689 } |
|
690 return EKeyWasNotConsumed; |
|
691 } |
|
692 |
|
693 // sort out if we're doing long or short presses... |
|
694 TKeyPressLength length = aKeyEvent.iRepeats ? ELongKeyPress : EShortKeyPress; |
|
695 |
|
696 // long keypress is handled once, after key event always is consumed. |
|
697 if (aEventCode == EEventKey && IsFlagSet(EFlagLongKeyPressHandled) ) |
|
698 { |
|
699 return EKeyWasConsumed; |
|
700 } |
|
701 |
|
702 if (length == ELongKeyPress && !IsFlagSet(EFlagLongKeyPressHandled)) |
|
703 { |
|
704 SetFlag(EFlagLongKeyPressHandled); |
|
705 } |
|
706 |
|
707 // Always handling case |
|
708 if (aEventCode != EEventKeyUp && IsFlagSet(EFlagLongKeyPressHandled) |
|
709 || aEventCode == EEventKeyUp && !IsFlagSet(EFlagLongKeyPressHandled)) |
|
710 { |
|
711 TKeyResponse response = iFepMan.HandleKeyEventL(EPtiKeyHash, length); |
|
712 __ASSERT_DEBUG(response != EKeyWasNotConsumed, AknFepPanic(EAknFepPanicNotHandleHashKey)); |
|
713 } |
|
714 else if (aEventCode == EEventKey |
|
715 && iKeyCatcherState == EAknFepStateUIActive) |
|
716 { |
|
717 // Ensure the CBA is in the default state. |
|
718 iFepMan.UpdateCbaL(NULL); |
|
719 // Close FEP UI, commit the inline edit and show the cursor. |
|
720 iFepMan.TryCloseUiL(); |
|
721 } |
|
722 |
|
723 if (aEventCode == EEventKeyUp) |
|
724 { |
|
725 ClearFlag(EFlagLongKeyPressHandled); |
|
726 } |
|
727 |
|
728 return EKeyWasConsumed; |
|
729 } |
|
730 |
|
731 void CAknFepKeyCatcher::HandleResourceChange(TInt aType) |
|
732 { |
|
733 if(aType == KEikDynamicLayoutVariantSwitch) //If the layout has been changed, notify fep manager |
|
734 { |
|
735 iFepMan.HandleResourceChange(aType); |
|
736 } |
|
737 |
|
738 CCoeControl::HandleResourceChange(aType); |
|
739 } |
|
740 TBool CAknFepKeyCatcher::IsNaviKey(TUint aCode) |
|
741 { |
|
742 switch(aCode) |
|
743 { |
|
744 case EKeyBackspace: |
|
745 case EKeyLeftArrow: |
|
746 case EKeyRightArrow: |
|
747 case EKeyUpArrow: |
|
748 case EKeyDownArrow: |
|
749 case EKeyDelete: |
|
750 return ETrue; |
|
751 default: |
|
752 return EFalse; |
|
753 } |
|
754 } |
|
755 #ifdef RD_SCALABLE_UI_V2 |
|
756 |
|
757 void CAknFepKeyCatcher::MonitorWsMessage(const TWsEvent& aEvent) |
|
758 { |
|
759 switch (aEvent.Type()) |
|
760 { |
|
761 case EEventPointer: |
|
762 TRAP_IGNORE(iFepMan.HandlePointerEventL(*aEvent.Pointer())); |
|
763 break; |
|
764 default: |
|
765 break; |
|
766 } |
|
767 } |
|
768 |
|
769 #endif //RD_SCALABLE_UI_V2 |
|
770 |
|
771 // End of file |