author | Fionntina Carville <fionntinac@symbian.org> |
Mon, 15 Nov 2010 11:44:32 +0000 | |
branch | RCL_3 |
changeset 84 | 1dabaed15bcd |
parent 81 | c26cc2a7c548 |
permissions | -rw-r--r-- |
62 | 1 |
/* |
2 |
* Copyright (c) 2007 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: Key event forwarder. |
|
15 |
* |
|
16 |
*/ |
|
17 |
||
18 |
||
19 |
// INCLUDE FILES |
|
20 |
#include <eikenv.h> |
|
21 |
#include <eikappui.h> |
|
22 |
#include <bldvariant.hrh> |
|
23 |
#include <featmgr.h> |
|
24 |
#include <PtiDefs.h> |
|
25 |
#include <AknUtils.h> |
|
26 |
||
27 |
#include "mphonestatemachine.h" |
|
28 |
#include "mphonekeyeventhandler.h" |
|
29 |
#include "cphonekeys.h" |
|
30 |
#include "cphonekeyeventforwarder.h" |
|
31 |
#include "cphonepubsubproxy.h" |
|
32 |
#include "cphonetimer.h" |
|
33 |
#include "phonelogger.h" |
|
34 |
#include "phoneui.pan" |
|
35 |
#include "mphoneviewcommandhandle.h" |
|
36 |
#include "cphoneqwertyhandler.h" |
|
37 |
#include "tphonecmdparampointer.h" |
|
38 |
#include "tphonecmdparamboolean.h" |
|
39 |
#include "mphoneqwertymodeobserver.h" |
|
40 |
#include "cdialer.h" |
|
41 |
||
42 |
// CONSTANTS |
|
43 |
||
44 |
//Avkon P&S keys |
|
45 |
const TUid KCRUidAvkon = { 0x101F876E }; |
|
46 |
const TUint32 KAknKeyBoardLayout = 0x0000000B; |
|
47 |
||
48 |
// Characters resulting from multitapping *-key. |
|
49 |
_LIT( KAsteriskMultitapCharacters, "*+pw" ); |
|
50 |
||
51 |
// Multitap delay parameter in micro seconds. |
|
52 |
const TInt KMultitapDelay = 1000000; |
|
53 |
||
54 |
||
55 |
// ============================ MEMBER FUNCTIONS =============================== |
|
56 |
||
57 |
// ----------------------------------------------------------------------------- |
|
58 |
// CPhoneKeyEventForwarder::NewL |
|
59 |
// ----------------------------------------------------------------------------- |
|
60 |
// |
|
61 |
CPhoneKeyEventForwarder* CPhoneKeyEventForwarder::NewL( |
|
62 |
const TRect& aRect, |
|
63 |
MPhoneStateMachine* aStateMachine, |
|
64 |
MPhoneViewCommandHandle* aViewCommandHandle ) |
|
65 |
{ |
|
66 |
CPhoneKeyEventForwarder* self = |
|
67 |
new (ELeave) CPhoneKeyEventForwarder( aStateMachine, aViewCommandHandle ); |
|
68 |
||
69 |
CleanupStack::PushL( self ); |
|
70 |
self->ConstructL( aRect ); |
|
71 |
CleanupStack::Pop( self ); |
|
72 |
||
73 |
return self; |
|
74 |
} |
|
75 |
||
76 |
// ----------------------------------------------------------------------------- |
|
77 |
// CPhoneKeyEventForwarder::~CPhoneKeyEventForwarder |
|
78 |
// ----------------------------------------------------------------------------- |
|
79 |
// |
|
80 |
CPhoneKeyEventForwarder::~CPhoneKeyEventForwarder() |
|
81 |
{ |
|
82 |
__LOGMETHODSTARTEND( EPhoneControl, "CPhoneKeyEventForwarder::~CPhoneKeyEventForwarder"); |
|
83 |
||
84 |
if ( AknLayoutUtils::PenEnabled() ) |
|
85 |
{ |
|
86 |
iPeninputServer.RemovePenUiActivationHandler( this ); |
|
87 |
} |
|
88 |
||
89 |
iPeninputServer.Close(); |
|
90 |
||
91 |
if ( iEikonEnv ) |
|
92 |
{ |
|
93 |
iEikonEnv->EikAppUi()->RemoveFromStack( this ); |
|
94 |
} |
|
95 |
delete iLongPressKeyEventTimer; |
|
96 |
||
97 |
delete iQwertyHandler; |
|
98 |
} |
|
99 |
||
100 |
// ----------------------------------------------------------------------------- |
|
101 |
// CPhoneKeyEventForwarder::CountComponentControls |
|
102 |
// ----------------------------------------------------------------------------- |
|
103 |
// |
|
104 |
TInt CPhoneKeyEventForwarder::CountComponentControls() const |
|
105 |
{ |
|
106 |
__LOGMETHODSTARTEND( EPhoneControl, "CPhoneKeyEventForwarder::CountComponentControls"); |
|
107 |
return 0; |
|
108 |
} |
|
109 |
||
110 |
// ----------------------------------------------------------------------------- |
|
111 |
// CPhoneKeyEventForwarder::ComponentControl |
|
112 |
// ----------------------------------------------------------------------------- |
|
113 |
// |
|
114 |
CCoeControl* CPhoneKeyEventForwarder::ComponentControl( |
|
115 |
TInt /*aIndex*/ ) const |
|
116 |
{ |
|
117 |
__LOGMETHODSTARTEND( EPhoneControl, "CPhoneKeyEventForwarder::ComponentControl"); |
|
118 |
return NULL; |
|
119 |
} |
|
120 |
||
121 |
// ----------------------------------------------------------------------------- |
|
122 |
// CPhoneKeyEventForwarder::SizeChanged |
|
123 |
// ----------------------------------------------------------------------------- |
|
124 |
// |
|
125 |
void CPhoneKeyEventForwarder::SizeChanged() |
|
126 |
{ |
|
127 |
__LOGMETHODSTARTEND( EPhoneControl, "CPhoneKeyEventForwarder::SizeChanged"); |
|
128 |
} |
|
129 |
||
130 |
// ----------------------------------------------------------------------------- |
|
131 |
// CPhoneKeyEventForwarder::Draw |
|
132 |
// ----------------------------------------------------------------------------- |
|
133 |
// |
|
134 |
void CPhoneKeyEventForwarder::Draw( |
|
135 |
const TRect& /*aRect*/ ) const |
|
136 |
{ |
|
137 |
__LOGMETHODSTARTEND( EPhoneControl, "CPhoneKeyEventForwarder::Draw"); |
|
138 |
} |
|
139 |
||
140 |
// ----------------------------------------------------------------------------- |
|
141 |
// CPhoneKeyEventForwarder::OfferKeyEventL |
|
142 |
// Checks is hte keyevent such that the number entry can be opened |
|
143 |
// ----------------------------------------------------------------------------- |
|
144 |
// |
|
145 |
TKeyResponse CPhoneKeyEventForwarder::OfferKeyEventL( |
|
146 |
const TKeyEvent& aKeyEvent, |
|
147 |
TEventCode aType ) |
|
148 |
{ |
|
149 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
150 |
"CPhoneKeyEventForwarder::OfferKeyEventL"); |
|
151 |
||
152 |
TKeyResponse ret( EKeyWasNotConsumed ); |
|
153 |
||
154 |
// After event key, expect to have key up event. |
|
155 |
iExpectKeyUpEvent = ( aType == EEventKey ); |
|
156 |
||
157 |
ret = OfferKeyEventBeforeControlStackL( aKeyEvent, aType ); |
|
158 |
||
81
c26cc2a7c548
Revision: 201039
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
69
diff
changeset
|
159 |
if ( !aKeyEvent.iRepeats ) |
62 | 160 |
{ |
161 |
// Convert event. Use already converted iKeyPressedDown. |
|
162 |
TKeyEvent keyEvent = aKeyEvent; |
|
69
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
163 |
keyEvent.iCode = iKeyPressedDown; |
62 | 164 |
|
165 |
// Do not handle dtmf tone if the type is EEventKey but we are not |
|
166 |
// expecting key up event. This happens if the key up event has been |
|
167 |
// handled by some CActiveSchedulerWait object somewhere in the execution |
|
168 |
// of function OfferKeyEventBeforeControlStackL. |
|
169 |
if ( iExpectKeyUpEvent || aType != EEventKey ) |
|
170 |
{ |
|
171 |
// Start and stop dtmf |
|
172 |
iStateMachine->State()->HandleDtmfKeyToneL( keyEvent, aType ); |
|
173 |
} |
|
174 |
||
175 |
// Open number entry view if any allowed character key |
|
176 |
// is pressed on homescreen or in-call ui |
|
177 |
if ( aType != EEventKeyUp && IsKeyAllowedL( keyEvent ) ) |
|
178 |
{ |
|
179 |
// Do not open number entry with up key |
|
180 |
iStateMachine->State()->HandleCreateNumberEntryL( keyEvent, aType ); |
|
181 |
} |
|
182 |
} |
|
183 |
||
184 |
return ret; |
|
185 |
} |
|
186 |
||
187 |
// ----------------------------------------------------------------------------- |
|
188 |
// CPhoneKeyEventForwarder::CPhoneKeyEventForwarder |
|
189 |
// ----------------------------------------------------------------------------- |
|
190 |
// |
|
191 |
CPhoneKeyEventForwarder::CPhoneKeyEventForwarder( |
|
192 |
MPhoneStateMachine* aStateMachine, |
|
193 |
MPhoneViewCommandHandle* aViewCommandHandle ) |
|
194 |
: iStateMachine( aStateMachine ), |
|
195 |
iViewCommandHandle( aViewCommandHandle ) |
|
196 |
{ |
|
197 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
198 |
"CPhoneKeyEventForwarder::CPhoneKeyEventForwarder"); |
|
199 |
} |
|
200 |
||
201 |
// ----------------------------------------------------------------------------- |
|
202 |
// CPhoneKeyEventForwarder::ConstructL |
|
203 |
// ----------------------------------------------------------------------------- |
|
204 |
// |
|
205 |
void CPhoneKeyEventForwarder::ConstructL( const TRect& aRect ) |
|
206 |
{ |
|
207 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
208 |
"CPhoneKeyEventForwarder::ConstructL"); |
|
209 |
||
210 |
if ( FeatureManager::FeatureSupported( KFeatureIdKeypadNoSlider ) ) |
|
211 |
{ |
|
212 |
RWindowGroup& groupWin = iCoeEnv->RootWin(); |
|
213 |
} |
|
214 |
// Create invisible control. |
|
215 |
CreateWindowL(); |
|
216 |
MakeVisible( EFalse ); |
|
217 |
SetRect( aRect ); |
|
218 |
||
219 |
if ( iEikonEnv ) |
|
220 |
{ |
|
221 |
iEikonEnv->EikAppUi()->AddToStackL( |
|
222 |
this, |
|
223 |
ECoeStackPriorityEnvironmentFilter, |
|
224 |
ECoeStackFlagRefusesFocus ); |
|
225 |
} |
|
226 |
||
227 |
// Create the long press key event timer |
|
228 |
iLongPressKeyEventTimer = CPhoneTimer::NewL(); |
|
229 |
||
230 |
// Create qwerty mode handler |
|
231 |
iQwertyHandler = CPhoneQwertyHandler::NewL(); |
|
232 |
||
233 |
TPhoneCmdParamPointer ptrParam; |
|
234 |
iViewCommandHandle->ExecuteCommand( EPhoneViewGetQwertyModeObserver, &ptrParam ); |
|
235 |
CDialer* qwertyObserver = |
|
236 |
static_cast<CDialer*>( ptrParam.Pointer() ); |
|
237 |
||
238 |
iQwertyHandler->AddQwertyModeObserverL( *qwertyObserver ); |
|
239 |
||
240 |
if ( AknLayoutUtils::PenEnabled() ) |
|
241 |
{ |
|
242 |
User::LeaveIfError( iPeninputServer.Connect() ); |
|
243 |
iPeninputServer.AddPenUiActivationHandler( this, EPluginInputModeAll ); |
|
244 |
iVirtualKeyBoardOpen = iPeninputServer.IsVisible(); |
|
245 |
} |
|
246 |
||
247 |
CEikonEnv* env = static_cast<CEikonEnv*>( ControlEnv() ); |
|
248 |
if ( env ) |
|
249 |
{ |
|
250 |
iMenu = env->AppUiFactory()->MenuBar(); |
|
251 |
} |
|
252 |
} |
|
253 |
||
254 |
// ----------------------------------------------------------------------------- |
|
255 |
// CPhoneKeyEventForwarder::IsKeyAllowedL |
|
256 |
// ----------------------------------------------------------------------------- |
|
257 |
// |
|
258 |
TBool CPhoneKeyEventForwarder::IsKeyAllowedL( const TKeyEvent& aKeyEvent ) |
|
259 |
{ |
|
260 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
261 |
"CPhoneKeyEventForwarder::IsKeyAllowedL"); |
|
262 |
||
263 |
TKeyEvent keyEvent( aKeyEvent ); |
|
264 |
||
265 |
// Check keyboard mode |
|
266 |
TBool isModeNumeric = iViewCommandHandle->HandleCommandL( |
|
267 |
EPhoneViewIsNumberEntryNumericMode ) == EPhoneViewResponseSuccess; |
|
268 |
||
269 |
// Check if key is a numeric key |
|
270 |
TBool isNumeric = CPhoneKeys::IsNumericKey( keyEvent, EEventKey ); |
|
271 |
||
272 |
// Check if key is alpha numeric key and alphabet input is allowed |
|
273 |
TBool isAllowedAlphaNumeric = |
|
274 |
iStateMachine->State()->IsAlphanumericSupportedAndCharInput( keyEvent ); |
|
275 |
||
276 |
return ( ( isModeNumeric && isNumeric ) || |
|
277 |
( !isModeNumeric && isAllowedAlphaNumeric ) ); |
|
278 |
} |
|
279 |
||
280 |
// ----------------------------------------------------------------------------- |
|
281 |
// CPhoneKeyEventForwarder::ConvertHalfQwertySpecialChar |
|
282 |
// ----------------------------------------------------------------------------- |
|
283 |
// |
|
284 |
TBool CPhoneKeyEventForwarder::ConvertHalfQwertySpecialChar( TUint& aCode, |
|
285 |
const TKeyEvent& aKeyEvent ) |
|
286 |
{ |
|
287 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
288 |
"CPhoneKeyEventForwarder::ConvertHalfQwertySpecialChar"); |
|
289 |
||
290 |
TBool ret( EFalse ); |
|
291 |
TInt keyboard( CPhonePubSubProxy::Instance()->Value( |
|
292 |
KCRUidAvkon, |
|
293 |
KAknKeyBoardLayout ) ); |
|
294 |
||
295 |
if ( keyboard == EPtiKeyboardHalfQwerty ) |
|
296 |
{ |
|
297 |
switch ( aKeyEvent.iScanCode ) |
|
298 |
{ |
|
299 |
case EStdKeyLeftShift: |
|
300 |
ret = ETrue; |
|
301 |
aCode = KPhoneDtmfHashCharacter; |
|
302 |
break; |
|
303 |
case EStdKeyLeftFunc: |
|
304 |
ret = ETrue; |
|
305 |
aCode = KPhoneDtmfStarCharacter; |
|
306 |
break; |
|
307 |
case EStdKeySpace: |
|
308 |
ret = ETrue; |
|
309 |
aCode = KPhoneDtmf0Character; |
|
310 |
break; |
|
311 |
default: |
|
312 |
break; |
|
313 |
} |
|
314 |
} |
|
315 |
||
316 |
__PHONELOG1( EBasic, EPhoneControl, |
|
317 |
"CPhoneKeyEventForwarder::ConvertHalfQwertySpecialChar =%d ", |
|
318 |
ret ); |
|
319 |
||
320 |
return ret; |
|
321 |
} |
|
322 |
||
323 |
// ----------------------------------------------------------------------------- |
|
324 |
// CPhoneKeyEventForwarder::IsKeySimulatedByTouchDialer |
|
325 |
// |
|
326 |
// ----------------------------------------------------------------------------- |
|
327 |
// |
|
328 |
TBool CPhoneKeyEventForwarder::IsKeySimulatedByTouchDialer( |
|
329 |
const TKeyEvent& aKeyEvent ) const |
|
330 |
{ |
|
331 |
return ( ( aKeyEvent.iModifiers & EModifierNumLock ) && |
|
332 |
( aKeyEvent.iModifiers & EModifierKeypad ) ); |
|
333 |
} |
|
334 |
||
335 |
// ----------------------------------------------------------------------------- |
|
336 |
// CPhoneKeyEventForwarder::HandleTouchDialerKeyEventL |
|
337 |
// Handle EEventKey type of event from touch dialer |
|
338 |
// ----------------------------------------------------------------------------- |
|
339 |
// |
|
340 |
void CPhoneKeyEventForwarder::HandleTouchDialerKeyEventL( const TKeyEvent& aKeyEvent ) |
|
341 |
{ |
|
342 |
TBool multitap = aKeyEvent.iScanCode == EStdKeyNkpAsterisk && |
|
343 |
iPreviousScanCode == EStdKeyNkpAsterisk && |
|
344 |
iKeyPressTime.MicroSecondsFrom( iPreviousKeyPressTime ) < KMultitapDelay; |
|
345 |
||
346 |
if ( multitap ) |
|
347 |
{ |
|
348 |
// Update multitap index |
|
349 |
iMultitapIndex = ( iMultitapIndex + 1 ) % KAsteriskMultitapCharacters().Length(); |
|
350 |
||
351 |
// Delete the previously entered character by simulating a backspace character. |
|
352 |
TKeyEvent backSpaceEvent; |
|
353 |
backSpaceEvent.iModifiers = 0; |
|
354 |
backSpaceEvent.iRepeats = 0; |
|
355 |
backSpaceEvent.iCode = EKeyBackspace; |
|
356 |
backSpaceEvent.iScanCode = EStdKeyBackspace; |
|
357 |
iStateMachine->State()->HandleKeyEventL( backSpaceEvent, EEventKey ); |
|
358 |
||
359 |
TKeyEvent keyEvent( aKeyEvent ); |
|
360 |
||
361 |
// Modify the key event to contain the next character on multitap list. |
|
362 |
keyEvent.iCode = ( TInt ) KAsteriskMultitapCharacters()[ iMultitapIndex ]; |
|
363 |
||
364 |
// Send character to number entry. |
|
365 |
iStateMachine->State()->HandleKeyEventL( keyEvent, EEventKey ); |
|
366 |
} |
|
367 |
else |
|
368 |
{ |
|
369 |
iMultitapIndex = 0; |
|
370 |
iStateMachine->State()->HandleKeyEventL( aKeyEvent, EEventKey ); |
|
371 |
} |
|
372 |
} |
|
373 |
||
374 |
// ----------------------------------------------------------------------------- |
|
375 |
// CPhoneKeyEventForwarder::OfferKeyEventBeforeControlStackL |
|
376 |
// Let phone handle before other components in control stack |
|
377 |
// ----------------------------------------------------------------------------- |
|
378 |
// |
|
379 |
TKeyResponse CPhoneKeyEventForwarder::OfferKeyEventBeforeControlStackL( |
|
380 |
const TKeyEvent& aKeyEvent, |
|
381 |
TEventCode aType ) |
|
382 |
{ |
|
383 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
384 |
"CPhoneKeyEventForwarder::OfferKeyEventBeforeControlStackL"); |
|
385 |
||
386 |
TKeyResponse response( EKeyWasNotConsumed ); |
|
387 |
||
388 |
// Handle key events before FEP |
|
389 |
// This is must becouse FEP consumes * key and when |
|
390 |
// editor is in alphanumeric mode FEP consumes all alphanumeric |
|
391 |
// keys |
|
392 |
switch( aType ) |
|
393 |
{ |
|
394 |
// EEventKeyDown |
|
395 |
case EEventKeyDown: |
|
396 |
response = HandleEventKeyDownBeforeControlStackL( aKeyEvent ); |
|
397 |
break; |
|
398 |
// EEventKey |
|
399 |
case EEventKey: |
|
400 |
response = HandleEventKeyBeforeControlStackL( aKeyEvent ); |
|
401 |
break; |
|
402 |
// EEventKeyUp |
|
403 |
case EEventKeyUp: |
|
404 |
response = HandleEventKeyUpBeforeControlStackL( aKeyEvent ); |
|
405 |
break; |
|
406 |
default: |
|
407 |
break; |
|
408 |
} |
|
409 |
||
410 |
return response; |
|
411 |
} |
|
412 |
||
413 |
||
414 |
// ----------------------------------------------------------------------------- |
|
415 |
// CPhoneKeyEventForwarder::OfferKeyEventAfterControlStackL |
|
416 |
// Let phone handle keys if no one has done it already |
|
417 |
// ----------------------------------------------------------------------------- |
|
418 |
// |
|
419 |
TKeyResponse CPhoneKeyEventForwarder::OfferKeyEventAfterControlStackL( |
|
420 |
const TKeyEvent& aKeyEvent, |
|
421 |
TEventCode aType ) |
|
422 |
{ |
|
423 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
424 |
"CPhoneKeyEventForwarder::OfferKeyEventAfterControlStackL"); |
|
425 |
||
426 |
// Send key to editor |
|
427 |
iStateMachine->State()->HandleKeyEventL( aKeyEvent, aType ); |
|
428 |
||
429 |
if ( EEventKeyUp == aType && EKeyNull != iKeyPressedDown ) |
|
430 |
{ |
|
431 |
// EKeyEnter is always offered to Telephony so don´t offer it |
|
432 |
// to state if there is menu or a dialog open. |
|
433 |
if ( !( EKeyEnter == iKeyPressedDown |
|
434 |
&& iDisplayingMenuOrDialogOnEventKeyDown ) ) |
|
435 |
{ |
|
436 |
// Handle short key press |
|
437 |
iStateMachine->State()->HandleKeyMessageL( |
|
438 |
MPhoneKeyEvents::EPhoneKeyShortPress, |
|
439 |
TKeyCode( iKeyPressedDown ) ); |
|
440 |
} |
|
441 |
// Reset key code |
|
442 |
iScanCode = EStdKeyNull; |
|
443 |
iKeyPressedDown = EKeyNull; |
|
444 |
iDisplayingMenuOrDialogOnEventKeyDown = EFalse; |
|
445 |
} |
|
446 |
||
447 |
return EKeyWasNotConsumed; |
|
448 |
} |
|
449 |
||
450 |
// --------------------------------------------------------------------------- |
|
451 |
// CPhoneKeyEventForwarder::OnPeninputUiDeactivated |
|
452 |
// |
|
453 |
// Gets called when the virtual keyboard editor is closed. |
|
454 |
// --------------------------------------------------------------------------- |
|
455 |
// |
|
456 |
void CPhoneKeyEventForwarder::OnPeninputUiDeactivated() |
|
457 |
{ |
|
458 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
459 |
"CPhoneKeyEventForwarder::OnPeninputUiDeactivated"); |
|
460 |
iVirtualKeyBoardOpen = EFalse; |
|
461 |
} |
|
462 |
||
463 |
// --------------------------------------------------------------------------- |
|
464 |
// CPhoneKeyEventForwarder::OnPeninputUiActivated |
|
465 |
// |
|
466 |
// Gets called when the virtual keyboard editor is opened. |
|
467 |
// --------------------------------------------------------------------------- |
|
468 |
// |
|
469 |
void CPhoneKeyEventForwarder::OnPeninputUiActivated() |
|
470 |
{ |
|
471 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
472 |
"CPhoneKeyEventForwarder::OnPeninputUiActivated"); |
|
473 |
iVirtualKeyBoardOpen = ETrue; |
|
474 |
} |
|
475 |
||
476 |
// ----------------------------------------------------------- |
|
477 |
// CPhoneKeyEventForwarder::HandleEventKeyDownBeforeControlStackL |
|
478 |
// ----------------------------------------------------------- |
|
479 |
// |
|
480 |
TKeyResponse CPhoneKeyEventForwarder::HandleEventKeyDownBeforeControlStackL( |
|
481 |
const TKeyEvent& aKeyEvent ) |
|
482 |
{ |
|
483 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
484 |
"CPhoneKeyEventForwarder::HandleEventKeyDownBeforeControlStackL"); |
|
485 |
||
486 |
// Convert key code |
|
487 |
ConvertKeyCodeL( iKeyPressedDown, aKeyEvent ); |
|
488 |
// Save key scan code |
|
489 |
iScanCode = aKeyEvent.iScanCode; |
|
490 |
||
491 |
// Store the previous keypress time. |
|
492 |
iPreviousKeyPressTime = iKeyPressTime; |
|
493 |
||
494 |
// Start the key press timer |
|
495 |
iKeyPressTime.UniversalTime(); |
|
496 |
||
497 |
// Cancel the long press key event timer, if it is active |
|
498 |
if ( iLongPressKeyEventTimer->IsActive() ) |
|
499 |
{ |
|
500 |
iLongPressKeyEventTimer->CancelTimer(); |
|
501 |
} |
|
502 |
||
503 |
// Don't initiate long tap timer if all these are true |
|
504 |
// a) key event is not from virtual dialer |
|
505 |
// b) device is in qwerty mode |
|
506 |
// c) phone number editor is alpha mode, i.e. not in numeric mode |
|
507 |
// This is to prevent phone app's long tap functionality with qwerty |
|
508 |
// long presses, and to have the normal editor long press behaviour |
|
509 |
// instead. |
|
510 |
TBool preventLongTap = |
|
511 |
!IsKeySimulatedByTouchDialer( aKeyEvent ) && |
|
512 |
iQwertyHandler->IsQwertyInput() && |
|
513 |
iViewCommandHandle->HandleCommandL( EPhoneViewIsNumberEntryNumericMode ) != EPhoneViewResponseSuccess; |
|
514 |
||
515 |
// Prevent long tap functionality for key events coming from virtual touch keyboard. |
|
516 |
// Virtual touch keyboard has own editing functionality for long presses, and telephony |
|
517 |
// should not add conflicting behaviour on top of that. |
|
518 |
preventLongTap = preventLongTap || iVirtualKeyBoardOpen; |
|
519 |
||
520 |
if ( !preventLongTap ) |
|
521 |
{ |
|
522 |
// Start long press timer |
|
523 |
iLongPressKeyEventTimer->After( |
|
524 |
KPhoneLongPressKeyEventDuration, |
|
525 |
TCallBack( DoHandleLongPressKeyEventCallbackL, |
|
526 |
this ) ); |
|
527 |
} |
|
528 |
||
529 |
// Check if dialog or menu is open |
|
530 |
// EikAppUi()->IsDisplayingMenuOrDialog doesn´t always return correct |
|
531 |
// value for menubar, so ask visibility also from CEikMenuBar |
|
532 |
iDisplayingMenuOrDialogOnEventKeyDown = ( iViewCommandHandle->HandleCommandL( |
|
533 |
EPhoneViewIsDisplayingMenuOrDialog ) == |
|
534 |
EPhoneViewResponseSuccess ) || ( iMenu && iMenu->IsDisplayed() ); |
|
535 |
||
69
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
536 |
// Consume dialer simulated key events, pass others on |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
537 |
return ( IsKeySimulatedByTouchDialer( aKeyEvent ) ? EKeyWasConsumed : EKeyWasNotConsumed ); |
62 | 538 |
} |
539 |
||
540 |
// ----------------------------------------------------------- |
|
541 |
// CPhoneKeyEventForwarder::HandleEventKeyBeforeControlStackL |
|
542 |
// Both short key press event (iRepeats == 0) and |
|
543 |
// long key press event (iRepeats == 1) are handled here |
|
544 |
// ----------------------------------------------------------- |
|
545 |
// |
|
546 |
TKeyResponse CPhoneKeyEventForwarder::HandleEventKeyBeforeControlStackL( |
|
547 |
const TKeyEvent& aKeyEvent ) |
|
548 |
{ |
|
549 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
550 |
"CPhoneKeyEventForwarder::HandleEventKeyBeforeControlStackL"); |
|
551 |
||
552 |
TKeyResponse response( EKeyWasNotConsumed ); |
|
553 |
TKeyEvent keyEvent( aKeyEvent ); |
|
554 |
||
555 |
// Special handling for virtual dialer keys events |
|
556 |
const TBool simulatedByDialer = IsKeySimulatedByTouchDialer( keyEvent ); |
|
557 |
if ( simulatedByDialer ) |
|
558 |
{ |
|
559 |
// feed the event directly to number entry |
|
560 |
HandleTouchDialerKeyEventL( keyEvent ); |
|
561 |
response = EKeyWasConsumed; |
|
562 |
} |
|
563 |
else |
|
564 |
{ |
|
565 |
// If not simulated by dialer, multitap related fields are reset. |
|
566 |
// Any key event not originating from dialer interrupts multitap |
|
567 |
// behaviour. |
|
568 |
iMultitapIndex = 0; |
|
569 |
iPreviousScanCode = 0; |
|
570 |
} |
|
571 |
||
572 |
// Special handling for QWERTY numeric mode key events |
|
573 |
if ( response == EKeyWasNotConsumed ) |
|
574 |
{ |
|
575 |
// FEP does not handle numeric characters 0123456789+*#pw correctly |
|
576 |
// when in QWERTY mode and number mode. If nothing is done about it, |
|
577 |
// these problems result in non-hybrid mode qwerty: |
|
578 |
// +, # and * cannot be typed without pressing Fn-key |
|
579 |
// Fn + <p/0> produces 0 although p is expected. |
|
580 |
// Fn + <w/2> produces 2 although w is expected. |
|
581 |
// To avoid this problems we do the following. |
|
582 |
||
583 |
// Take numeric keyevent, pass it to number entry and consume it. |
|
584 |
TBool numericMode = iViewCommandHandle->HandleCommandL( |
|
585 |
EPhoneViewIsNumberEntryNumericMode ) == EPhoneViewResponseSuccess; |
|
586 |
||
587 |
TPhoneCmdParamBoolean blockingDialog; |
|
588 |
iViewCommandHandle->ExecuteCommandL( EPhoneViewGetBlockingDialogStatus, |
|
589 |
&blockingDialog ); |
|
590 |
||
591 |
// Handle and consume keyevent only if in qwerty mode, editor is |
|
592 |
// in numeric mode, menu is not shown and there is no blocking dialog. |
|
593 |
if ( iQwertyHandler->IsQwertyInput() && numericMode && |
|
594 |
( !iMenu || !iMenu->IsDisplayed() ) && !blockingDialog.Boolean() ) |
|
595 |
{ |
|
596 |
iQwertyHandler->ConvertToNumeric( keyEvent ); |
|
597 |
||
598 |
// Send key to editor only if a) it is not a repeating keyevent and |
|
599 |
// it is a valid number entry character (0123456789+*#pw). |
|
600 |
if ( aKeyEvent.iRepeats == 0 && |
|
601 |
( CPhoneKeys::IsDtmfTone( keyEvent, EEventKey ) || |
|
602 |
CPhoneKeys::IsExtraChar( keyEvent.iCode ) ) ) |
|
603 |
{ |
|
604 |
iStateMachine->State()->HandleKeyEventL( keyEvent, EEventKey ); |
|
605 |
response = EKeyWasConsumed; |
|
606 |
} |
|
607 |
} |
|
608 |
} |
|
609 |
||
610 |
return response; |
|
611 |
} |
|
612 |
||
613 |
// ----------------------------------------------------------- |
|
614 |
// CPhoneKeyEventForwarder::HandleEventKeyUpBeforeControlStackL |
|
615 |
// ----------------------------------------------------------- |
|
616 |
// |
|
617 |
TKeyResponse CPhoneKeyEventForwarder::HandleEventKeyUpBeforeControlStackL( |
|
618 |
const TKeyEvent& aKeyEvent ) |
|
619 |
{ |
|
620 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
621 |
"CPhoneKeyEventForwarder::HandleEventKeyUpBeforeControlStackL"); |
|
622 |
||
623 |
// Send a long press key event to the current state provided |
|
624 |
// that the key scan code is the same as the key that was pressed |
|
625 |
if ( iScanCode == aKeyEvent.iScanCode ) |
|
626 |
{ |
|
627 |
// Pass the key press duration to the current state |
|
628 |
TTime now; |
|
629 |
now.UniversalTime(); |
|
630 |
TTimeIntervalMicroSeconds keyPressDuration = now.MicroSecondsFrom( |
|
631 |
iKeyPressTime ); |
|
632 |
iStateMachine->State()->HandleKeyPressDurationL( |
|
633 |
TKeyCode( iKeyPressedDown ), |
|
634 |
keyPressDuration ); |
|
635 |
||
636 |
// Cancel the long press timer, if it is active. Otherwise |
|
637 |
// ignore the key event since it was already handled as a long press |
|
638 |
// key event. |
|
639 |
if ( iLongPressKeyEventTimer->IsActive() ) |
|
640 |
{ |
|
641 |
iLongPressKeyEventTimer->CancelTimer(); |
|
642 |
} |
|
643 |
} |
|
644 |
||
645 |
// Store the previous scan code |
|
646 |
iPreviousScanCode = iScanCode; |
|
647 |
||
648 |
// Consume dialer simulated key events, pass others on |
|
69
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
649 |
TKeyResponse retValue = IsKeySimulatedByTouchDialer( aKeyEvent ) ? EKeyWasConsumed : EKeyWasNotConsumed; |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
650 |
|
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
651 |
// If event is consumed, reset key specific state variables. Otherwise they may disturb |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
652 |
// handling of coming key events originating from a different key. |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
653 |
if ( retValue == EKeyWasConsumed ) |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
654 |
{ |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
655 |
iKeyPressedDown = EKeyNull; |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
656 |
iScanCode = EStdKeyNull; |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
657 |
iDisplayingMenuOrDialogOnEventKeyDown = EFalse; |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
658 |
} |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
659 |
|
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
660 |
return retValue; |
62 | 661 |
} |
662 |
||
663 |
// --------------------------------------------------------- |
|
664 |
// CPhoneKeyEventForwarder::DoHandleLongPressKeyEventCallback |
|
665 |
// |
|
666 |
// This routine is called when the long press key event timer expires |
|
667 |
// after KPhoneLongPressKeyEventDuration. |
|
668 |
// --------------------------------------------------------- |
|
669 |
// |
|
670 |
TInt CPhoneKeyEventForwarder::DoHandleLongPressKeyEventCallbackL( TAny* aAny ) |
|
671 |
{ |
|
672 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
673 |
"CPhoneKeyEventForwarder::DoHandleLongPressKeyEventCallbackL"); |
|
674 |
||
675 |
__ASSERT_DEBUG( aAny, |
|
676 |
Panic( EPhoneCtrlUnknownPanic ) ); |
|
677 |
||
678 |
reinterpret_cast< CPhoneKeyEventForwarder* >( aAny )-> |
|
679 |
HandleLongPressKeyEventL(); |
|
680 |
||
681 |
return KErrNone; |
|
682 |
} |
|
683 |
||
684 |
// --------------------------------------------------------- |
|
685 |
// CPhoneKeyEventForwarder::HandleLongPressKeyEventL |
|
686 |
// Handle long press key event |
|
687 |
// --------------------------------------------------------- |
|
688 |
// |
|
689 |
void CPhoneKeyEventForwarder::HandleLongPressKeyEventL() |
|
690 |
{ |
|
691 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
692 |
"CPhoneKeyEventForwarder::HandleLongPressKeyEventL"); |
|
693 |
||
694 |
// In alphanumeric mode EEventKey-event is not received so we must |
|
695 |
// compare also with scan code. |
|
696 |
if ( KPhoneDtmfHashCharacter == iKeyPressedDown ) |
|
697 |
{ |
|
698 |
// Separate handling for long hash key because there is so much |
|
699 |
// different functionality under it and it works differently |
|
700 |
// in different protocols. |
|
701 |
iStateMachine->State()->HandleLongHashL(); |
|
702 |
} |
|
703 |
else if ( KPhoneDtmfStarCharacter == iKeyPressedDown ) |
|
704 |
{ |
|
705 |
// KPhoneDtmfStarCharacter value used in configuration file for |
|
706 |
// long key press application launching |
|
707 |
iStateMachine->State()->HandleKeyMessageL( |
|
708 |
MPhoneKeyEvents::EPhoneKeyLongPress, |
|
709 |
TKeyCode( KPhoneDtmfStarCharacter ) ); |
|
710 |
} |
|
711 |
else |
|
712 |
{ |
|
713 |
__PHONELOG1( |
|
714 |
EBasic, EPhoneControl, |
|
715 |
"CPhoneKeyEventHandler::HandleLongPressKeyEventL iCode(%d)", |
|
716 |
iKeyPressedDown ); |
|
717 |
iStateMachine->State()->HandleKeyMessageL( |
|
718 |
MPhoneKeyEvents::EPhoneKeyLongPress, |
|
719 |
TKeyCode( iKeyPressedDown ) ); |
|
720 |
} |
|
721 |
||
722 |
// Reset key code |
|
723 |
iScanCode = EStdKeyNull; |
|
724 |
iKeyPressedDown = EKeyNull; |
|
725 |
} |
|
726 |
||
727 |
// ----------------------------------------------------------- |
|
728 |
// CPhoneKeyEventForwarder::ConvertKeyCodeL |
|
729 |
// ----------------------------------------------------------- |
|
730 |
// |
|
731 |
void CPhoneKeyEventForwarder::ConvertKeyCodeL( TUint& aCode, |
|
732 |
const TKeyEvent& aKeyEvent ) |
|
733 |
{ |
|
734 |
__LOGMETHODSTARTEND( EPhoneControl, |
|
735 |
"CPhoneKeyEventForwarder::ConvertKeyCodeL"); |
|
736 |
||
737 |
// Handler for special device key mapping in case iScanCode |
|
738 |
// to iCode conversion hasn't been handled by CAknAppUi::GetAliasKeyCodeL |
|
739 |
__PHONELOG1( EBasic, EPhoneControl, |
|
740 |
"CPhoneKeyEventHandler::ConvertKeyCodeL scan code (%d)", |
|
741 |
aKeyEvent.iScanCode ); |
|
742 |
||
743 |
if ( !ConvertHalfQwertySpecialChar( aCode, aKeyEvent ) ) |
|
744 |
{ |
|
745 |
TBool numMode = iViewCommandHandle->HandleCommandL( |
|
746 |
EPhoneViewIsNumberEntryNumericMode ) == EPhoneViewResponseSuccess; |
|
747 |
TBool simulatedByDialer = IsKeySimulatedByTouchDialer( aKeyEvent ); |
|
69
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
748 |
|
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
749 |
TUint numCode( EKeyNull ); |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
750 |
|
62 | 751 |
if ( iQwertyHandler->IsQwertyInput() && numMode && !simulatedByDialer ) |
752 |
{ |
|
69
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
753 |
numCode = iQwertyHandler->NumericKeyCode( aKeyEvent ); |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
754 |
} |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
755 |
if ( numCode ) |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
756 |
{ |
8baf28733c3d
Revision: 201033
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
62
diff
changeset
|
757 |
aCode = numCode; |
62 | 758 |
} |
81
c26cc2a7c548
Revision: 201039
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
69
diff
changeset
|
759 |
else |
62 | 760 |
{ |
761 |
switch ( aKeyEvent.iScanCode ) |
|
762 |
{ |
|
763 |
case EStdKeyEnter: |
|
764 |
case EStdKeyNkpEnter: |
|
765 |
aCode = EKeyEnter; |
|
766 |
break; |
|
767 |
case EStdKeyYes: |
|
768 |
aCode = EKeyYes; |
|
769 |
break; |
|
770 |
case EStdKeyEnd: // End key is emulated if the device has combined power and end key |
|
771 |
case EStdKeyNo: |
|
772 |
aCode = EKeyNo; |
|
773 |
break; |
|
774 |
case EStdKeyDeviceF: |
|
775 |
aCode = EKeyDeviceF; // EStdKeyDeviceF mapping for unlock switch. |
|
776 |
break; |
|
777 |
case EStdKeyHash: |
|
778 |
aCode = KPhoneDtmfHashCharacter; |
|
779 |
break; |
|
780 |
case EStdKeyNkpAsterisk: |
|
781 |
aCode = KPhoneDtmfStarCharacter; |
|
782 |
break; |
|
783 |
case EStdKeyApplication0: |
|
784 |
aCode = EKeyApplication0; |
|
785 |
break; |
|
786 |
default: |
|
787 |
aCode = aKeyEvent.iScanCode; // Use default code |
|
788 |
break; |
|
789 |
} |
|
790 |
} |
|
791 |
} |
|
792 |
||
793 |
__PHONELOG1( EBasic, EPhoneControl, |
|
794 |
"CPhoneKeyEventHandler::ConvertKeyCodeL aCode (%d)", aCode ); |
|
795 |
} |
|
796 |
||
797 |
// End of File |
|
798 |