fep/aknfep/src/AknFepFnKeyManager.cpp
changeset 0 eb1f2e154e89
child 7 6defe5d1bd39
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 /*
       
     2 * Copyright (c) 2002-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:            Provides CAknFepManager definition
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 
       
    28 
       
    29 #ifdef _DEBUG
       
    30 #include <eikenv.h>
       
    31 #endif
       
    32 
       
    33 #include <fepbase.h>
       
    34 #include <avkon.hrh>
       
    35 #include <aknedsts.h>               //CAknEdwinState
       
    36 
       
    37 #include "AknFepFnKeyManager.h"
       
    38 #include "AknFepManager.h"
       
    39 #include <centralrepository.h>
       
    40 #include <AknFepInternalCRKeys.h>
       
    41 #include "PtiEngine.h"
       
    42 
       
    43 
       
    44 /*this part is removed 
       
    45 const   TUid    KPhoneUidAppPhone = { 0x100058B3 };
       
    46 const   TUid    KUidCalc = { 0x10005902 };
       
    47 const   TUid    KUidIdle = { 0x101fd64c };
       
    48 */
       
    49 const   TStdScanCode stdFnKeyCode(EStdKeyRightFunc);    // Defines the std key code for Fn key
       
    50 
       
    51 ////////////////////////////////////////////////////////////
       
    52 //   CAknFepFnKeyManager implementation
       
    53 //////////////////////////////////////////////////////////// 
       
    54 CAknFepFnKeyManager::CAknFepFnKeyManager( CAknFepManager& aFepMan, 
       
    55                     CAknFepSharedDataInterface* aSharedDataInterface)
       
    56 :iFepMan( aFepMan ),
       
    57  iFnKeyState( EFnKeyNone ),
       
    58  iIsQwertyMode (EFalse),
       
    59  iSharedDataInterface(aSharedDataInterface),
       
    60  iShiftKeyPressed( EFalse )
       
    61     {
       
    62     iIsQwertyMode = iSharedDataInterface->QwertyInputMode();
       
    63 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__
       
    64 #ifdef RD_INTELLIGENT_TEXT_INPUT
       
    65     iWasPreviousModePredictive = iFepMan.WesternPredictive();
       
    66 #endif // RD_INTELLIGENT_TEXT_INPUT
       
    67 #else   
       
    68     iWasPreviousModePredictive = iSharedDataInterface->PredictiveTextOn();
       
    69 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__     
       
    70     // The CR key KAknFepFnKeyState is reset the Fn key state NONE
       
    71     iSharedDataInterface->SetFnKeyState(0);
       
    72     }
       
    73 
       
    74 CAknFepFnKeyManager* CAknFepFnKeyManager::NewL( CAknFepManager& aFepMan,
       
    75                                             CAknFepSharedDataInterface* aSharedDataInterface)
       
    76     {
       
    77     CAknFepFnKeyManager* self = new(ELeave) CAknFepFnKeyManager( aFepMan,aSharedDataInterface );
       
    78     CleanupStack::PushL(self);
       
    79     self->ConstructL();
       
    80     CleanupStack::Pop();
       
    81     return self;
       
    82     }
       
    83 
       
    84 CAknFepFnKeyManager::~CAknFepFnKeyManager()
       
    85     {    
       
    86     iFnKeyState=EFnKeyNone;
       
    87     }
       
    88     
       
    89 void CAknFepFnKeyManager::ConstructL()
       
    90     {    
       
    91     }
       
    92 
       
    93 void CAknFepFnKeyManager::SetQwertyInputMode(TBool aQwertyState)
       
    94     {
       
    95     iIsQwertyMode = aQwertyState;
       
    96     }
       
    97 void CAknFepFnKeyManager::ClearFnKeyState()
       
    98     {
       
    99     iFnKeyState = EFnKeyNone;
       
   100     iFepMan.UpdateIndicators();    
       
   101     }
       
   102 
       
   103 CAknFepFnKeyManager::TFnKeyState CAknFepFnKeyManager::FnKeyState()
       
   104     {
       
   105     return iFnKeyState;
       
   106     }
       
   107 
       
   108 void CAknFepFnKeyManager::SetFnKeyState(CAknFepFnKeyManager::TFnKeyState aState)
       
   109     {
       
   110     TPtiKeyboardType keyboardType = iFepMan.KeyboardLayout();
       
   111     //This function is only supported for EFnKeyNext and half Qwerty keypad at the moment.
       
   112     if(keyboardType == EPtiKeyboardHalfQwerty && EFnKeyNext == iFnKeyState &&
       
   113         aState == EFnKeyNone)
       
   114         {    
       
   115         if(aState == EFnKeyNext && keyboardType == EPtiKeyboardHalfQwerty)
       
   116         	{
       
   117         	iFepMan.PtiEngine()->CancelTimerActivity();
       
   118         	}
       
   119         iFnKeyState = aState;
       
   120         iFepMan.SetCase( (TCase)iPreviousCase );
       
   121         iFepMan.UpdateIndicators();
       
   122         }
       
   123 #ifdef RD_INTELLIGENT_TEXT_INPUT  
       
   124     else if(keyboardType == EPtiKeyboardQwerty3x11 && EFnKeyNone == iFnKeyState &&
       
   125         aState == EFnKeyLock)
       
   126         {
       
   127         UpdatePreviousCase();
       
   128         iFnKeyState = aState;
       
   129         iFepMan.SetCase(EFnKeyLowerCase);
       
   130         iFepMan.UpdateIndicators();
       
   131         }
       
   132 #endif // RD_INTELLIGENT_TEXT_INPUT 		
       
   133 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__  
       
   134 #ifdef RD_INTELLIGENT_TEXT_INPUT  
       
   135     //Half QWERTY state uses this to change from EFnKeyNext aFnKeyNone
       
   136  	   else if ( iFnKeyState == EFnKeyNone && aState == EFnKeyNext )
       
   137         {
       
   138         // QWERTY long press implementation uses this function to set the Fn state.
       
   139         UpdatePreviousCase();
       
   140         iFnKeyState=EFnKeyNext;
       
   141         }
       
   142 
       
   143 #endif // RD_INTELLIGENT_TEXT_INPUT  
       
   144 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__
       
   145      // TODO: above piece of code should be simplify.    
       
   146      // Set the Fn Key state  
       
   147  	 else
       
   148  	    {
       
   149  	    iFnKeyState = aState;    
       
   150  	    }
       
   151     }
       
   152 TKeyResponse CAknFepFnKeyManager::HandleFnKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType, 
       
   153                                                      TCoeInputCapabilities aInputCapabilities ) 
       
   154     {
       
   155     
       
   156     TKeyResponse keyResponse = EKeyWasNotConsumed;
       
   157     TPtiKeyboardType keyboardType = iFepMan.KeyboardLayout();
       
   158 
       
   159     if(!iIsQwertyMode)
       
   160         {
       
   161         return keyResponse;
       
   162         }
       
   163         
       
   164   	if(!iFepMan.IsFlagSet(CAknFepManager::EFlagShiftKeyDepressed) && 
       
   165       !iFepMan.IsFlagSet(CAknFepManager::EFlagLongShiftKeyPress)
       
   166       && iShiftKeyPressed )
       
   167         {
       
   168         iShiftKeyPressed = EFalse;
       
   169         }
       
   170                 
       
   171     TInt caseFromFep = iFepMan.GetCurrentCase();
       
   172     
       
   173     TBool lockLater = EFalse;    
       
   174     if(  EEventKeyDown == aType )
       
   175         {
       
   176         if( stdFnKeyCode == aKeyEvent.iScanCode )
       
   177     		{
       
   178             iFepMan.PtiEngine()->CancelTimerActivity();
       
   179     		if( iPreviousKeyWasFnKey )
       
   180     			{
       
   181     			lockLater	= ETrue;
       
   182     			}
       
   183     		iPreviousKeyWasFnKey = ETrue; 			
       
   184     		}    
       
   185     	else
       
   186     		{
       
   187     		iPreviousKeyWasFnKey = EFalse; 				
       
   188     		}        
       
   189         }
       
   190     if(aKeyEvent.iRepeats && stdFnKeyCode != aKeyEvent.iScanCode &&
       
   191             iFnKeyState == EFnKeyNext)
       
   192         {
       
   193         // To fix the bug : Long press of number at the begin of editor. Then enter any character. 
       
   194         // The character is shown in upper case.
       
   195         if (ELowerCase == caseFromFep)
       
   196             {
       
   197             iFepMan.SetCase( (TCase)caseFromFep );
       
   198             }
       
   199         // To Fix Error: Character is NOT entered as per the input mode
       
   200         // when the character is entered after pressing Shift + Fn + Shift keys
       
   201         else if(!(EStdKeyRightShift == aKeyEvent.iScanCode ||
       
   202         		  EStdKeyLeftShift == aKeyEvent.iScanCode))
       
   203 	        {
       
   204             iFepMan.SetCase( (TCase)iPreviousCase );	
       
   205             }
       
   206             
       
   207 #ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__
       
   208 #ifdef RD_INTELLIGENT_TEXT_INPUT  
       
   209          // For QWERTY Predictive ---->
       
   210         if(iWasPreviousModePredictive)
       
   211         	{
       
   212         	// We usually end up here when using the long key press to enter Fn symbols
       
   213 			iFepMan.SetWesternPredictive(ETrue); 
       
   214 		   	iFepMan.TryChangeModeL(ELatin);               	
       
   215         	}
       
   216         // For QWERTY Predictive <----
       
   217 
       
   218 #endif // RD_INTELLIGENT_TEXT_INPUT  
       
   219 #endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__    
       
   220         iFnKeyState = EFnKeyNone;
       
   221         iFepMan.UpdateIndicators();
       
   222         }
       
   223      
       
   224     if( stdFnKeyCode == aKeyEvent.iScanCode )
       
   225         {
       
   226         // Consume the function key events.
       
   227         keyResponse = EKeyWasConsumed;
       
   228         }
       
   229     if (iFepMan.IsHybridAplhaEditor())
       
   230         keyResponse = EKeyWasNotConsumed;
       
   231  
       
   232     
       
   233     // check for the case when in Half Qwerty and both shift and fn keys are
       
   234     // pressed and fn key is released while shift is still down
       
   235     if( EEventKeyUp == aType && 
       
   236     	stdFnKeyCode == aKeyEvent.iScanCode &&
       
   237     	iShiftKeyPressed &&
       
   238     	EPtiKeyboardHalfQwerty == keyboardType )
       
   239     	{
       
   240     	ClearFnKeyState();
       
   241     	}
       
   242     	    
       
   243     if( EStdKeyRightShift == aKeyEvent.iScanCode ||  EStdKeyLeftShift == aKeyEvent.iScanCode )
       
   244         {
       
   245         if( EEventKeyDown == aType ) 
       
   246             {
       
   247             iShiftKeyPressed = ETrue;
       
   248             }
       
   249         if( EEventKeyUp == aType )
       
   250             {
       
   251             iShiftKeyPressed = EFalse;
       
   252             }
       
   253         }
       
   254         
       
   255     // For Shift key handling.
       
   256     // Shift Key should be ignored in locked state.
       
   257      
       
   258     if( ( EFnKeyNext == iFnKeyState ) 
       
   259     && EEventKeyDown == aType &&
       
   260     ( EStdKeyRightShift == aKeyEvent.iScanCode ||  EStdKeyLeftShift == aKeyEvent.iScanCode)) 
       
   261         {
       
   262         // Fnkey event+ shift key event. Change to FnKey Upper case
       
   263         iFepMan.SetCase( EFnKeyUpperCase );
       
   264         if( keyboardType == EPtiKeyboardHalfQwerty )
       
   265             {
       
   266             iFepMan.SetCase( EFnKeyLowerCase );
       
   267             }
       
   268         return EKeyWasNotConsumed;
       
   269         }
       
   270     //===================================================		
       
   271 	
       
   272 	// GQF clarification Fn+Shift
       
   273 	// If shift key is hold on, So fn key state should be EFnKeyNext
       
   274 	// So next text mode goes to function upper
       
   275 	if( aType == EEventKeyUp && iShiftKeyPressed &&  stdFnKeyCode == aKeyEvent.iScanCode)	
       
   276 		{
       
   277 		if( EFnKeyPressed == iFnKeyState)
       
   278 			{
       
   279 			iFepMan.PtiEngine()->CancelTimerActivity();
       
   280 			iFnKeyState=EFnKeyNext;
       
   281 			iFepMan.SetCase( EFnKeyUpperCase );				
       
   282 			}			
       
   283         else if (EFnKeyPressedAgain == iFnKeyState )
       
   284             {
       
   285             CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyLock"));
       
   286             iFnKeyState = EFnKeyLock;	                
       
   287             UpdatePreviousCase();
       
   288             iFepMan.SetCase( EFnKeyUpperCase );
       
   289             }
       
   290         else if(EFnKeyDown == iFnKeyState)
       
   291             {
       
   292             iFnKeyState = EFnKeyNone;
       
   293             UpdatePreviousCase();
       
   294             iFepMan.SetCase( EUpperCase );	
       
   295             }
       
   296 		iFepMan.UpdateIndicators();
       
   297 		}
       
   298 	// Holding shift key, press key just after releasing fn key,
       
   299 	// Fn key state goes to EFnKeyNone mode.
       
   300 	if( aType == EEventKeyUp && iShiftKeyPressed && iFnKeyState==EFnKeyNext && stdFnKeyCode != aKeyEvent.iScanCode &&  !(EStdKeyRightShift == aKeyEvent.iScanCode ||  EStdKeyLeftShift == aKeyEvent.iScanCode))
       
   301 		{
       
   302 		iFnKeyState=EFnKeyNone;		
       
   303 		iFepMan.SetCase( EUpperCase );		
       
   304 		iFepMan.UpdateIndicators();
       
   305 		}
       
   306 		
       
   307 	//====================================================
       
   308 		
       
   309     // Fnkey event+ shift key event -> when fn and shift key are kept pressed.
       
   310     if( (iShiftKeyPressed && EFnKeyNone != iFnKeyState ) )
       
   311         {
       
   312         if( (EFnKeyPressed == iFnKeyState) &&
       
   313         	(stdFnKeyCode != aKeyEvent.iScanCode) &&
       
   314         	!( EStdKeyRightShift == aKeyEvent.iScanCode ||  EStdKeyLeftShift == aKeyEvent.iScanCode ))
       
   315 	        {
       
   316      	   	CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyDown"));
       
   317           	iFnKeyState=EFnKeyDown;	      	
       
   318 	        }
       
   319         
       
   320         // Thre is no Functin shift reverse mode
       
   321         // So, In shift key press if fn key state is not none
       
   322         // text case stte is function upper.
       
   323         if( aType == EEventKeyDown && stdFnKeyCode == aKeyEvent.iScanCode)
       
   324         	{
       
   325         	if ( EFnKeyNext == iFnKeyState )
       
   326         		{       	     	
       
   327        	     	if(lockLater)
       
   328        	     	    {
       
   329        	     	    //CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyPressedAgain "));
       
   330        	     	    iFnKeyState=EFnKeyPressedAgain;
       
   331        	     	    } 					
       
   332         		}
       
   333         	else if ( EFnKeyLock == iFnKeyState )
       
   334 	        	{
       
   335        	     	//CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyDown"));
       
   336               	iFnKeyState=EFnKeyDown;
       
   337 	        	}
       
   338         	}
       
   339         iFepMan.SetCase( EFnKeyUpperCase );
       
   340         if( keyboardType == EPtiKeyboardHalfQwerty )
       
   341             {
       
   342             iFepMan.SetCase( EFnKeyLowerCase );
       
   343             }
       
   344         iFepMan.UpdateIndicators();
       
   345         return EKeyWasNotConsumed;
       
   346         }
       
   347 
       
   348     // Check the input mode of the currently focused editor (when available)
       
   349     MCoeFepAwareTextEditor* fepAwareTextEditor = aInputCapabilities.FepAwareTextEditor();
       
   350     
       
   351     if ( fepAwareTextEditor && fepAwareTextEditor->Extension1() )
       
   352         {
       
   353         if( EAknEditorNumericInputMode == 
       
   354             ( static_cast<CAknEdwinState*>( fepAwareTextEditor->Extension1()->State( KNullUid ) ) )->CurrentInputMode() )
       
   355             // If number input mode is detected, handle it as number input
       
   356             // capability with greatest available variation of letters
       
   357             {
       
   358             // Use EDialableCharacters since it provides most flexibility for number input
       
   359             aInputCapabilities.SetCapabilities( TCoeInputCapabilities::EDialableCharacters );
       
   360             }            
       
   361         }
       
   362         
       
   363     if ( EFnKeyForced != iFnKeyState )
       
   364         {
       
   365         // Handling of Fn key events.
       
   366         // If Fn key is held down while characters are typed, all following key 
       
   367         // events are exchanged.
       
   368         // If Fn key is only pressed (key down + key up, not held down), only
       
   369         // the very next key event is exchanged.
       
   370         // If the next key event after Fn key is another Fn key event, the 
       
   371         // Fn lock mode is activated. Then all following key events are
       
   372         // exchanged until the Fn key is pressed again.       
       
   373          
       
   374         if( EEventKeyDown == aType && stdFnKeyCode == aKeyEvent.iScanCode )
       
   375             {
       
   376             if ( EFnKeyNext == iFnKeyState )
       
   377                 {                
       
   378                 if(lockLater)
       
   379             		{
       
   380             		CEikonEnv::Static()->InfoMsg(_L("iFnKeyState=EFnKeyPressedAgain"));	
       
   381             		iFnKeyState=EFnKeyPressedAgain;
       
   382           			}
       
   383               	else
       
   384               	    {
       
   385               	    iFnKeyState=EFnKeyPressed;
       
   386               	    }		              			
       
   387                 }
       
   388             else if ( EFnKeyLock == iFnKeyState )
       
   389                 {
       
   390                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState=EFnKeyDown"));
       
   391                 iFnKeyState=EFnKeyDown;
       
   392                 }
       
   393             //else 
       
   394             // Sahoo
       
   395             else if ( EFnKeyDown != iFnKeyState )
       
   396                 {
       
   397                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState=EFnKeyPressed"));
       
   398                 iFnKeyState=EFnKeyPressed;
       
   399                 }
       
   400             iFepMan.UpdateIndicators();    
       
   401             return keyResponse;
       
   402             }
       
   403         // Sahoo            
       
   404         if( EEventKeyDown == aType && EFnKeyPressed == iFnKeyState )
       
   405             {
       
   406             iFnKeyState=EFnKeyDown;
       
   407             iFepMan.SetCase( EFnKeyLowerCase );
       
   408             }
       
   409 #ifdef __WINS        
       
   410         // NOTE: This following HACK is to ensure working in emulator environment,
       
   411         // where Alt Gr key seems to send always two separate key events:
       
   412         // EStdKeyRightFunc and EStdKeyLeftCtrl
       
   413         if ( EStdKeyLeftCtrl == aKeyEvent.iScanCode )
       
   414             {
       
   415             return;
       
   416             }
       
   417         // HACK ends
       
   418 #endif
       
   419         
       
   420         if( EEventKeyUp == aType && stdFnKeyCode == aKeyEvent.iScanCode )
       
   421             {
       
   422             if ( EFnKeyPressedAgain == iFnKeyState )
       
   423                 {
       
   424                	if(! iFepMan.IsFlagSet(CAknFepManager::EFlagQwertyShiftMode))
       
   425 	               	{
       
   426 	                CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyLock"));
       
   427 	                iFnKeyState = EFnKeyLock;
       
   428 		           	}
       
   429                	else
       
   430 	               	{
       
   431 	                CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyNext"));
       
   432 	                iFepMan.PtiEngine()->CancelTimerActivity();
       
   433 	                iFnKeyState = EFnKeyNext;               		
       
   434 	               	}
       
   435                 UpdatePreviousCase();
       
   436                 iFepMan.ClearFlag(CAknFepManager::EFlagQwertyShiftMode);             
       
   437                 iFepMan.SetCase( EFnKeyLowerCase );
       
   438                 }
       
   439             else if ( EFnKeyPressed == iFnKeyState )
       
   440                 {
       
   441                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyNext"));
       
   442                 iFepMan.PtiEngine()->CancelTimerActivity();
       
   443                 iFnKeyState = EFnKeyNext;
       
   444                 
       
   445                 UpdatePreviousCase();
       
   446                 
       
   447                 // After pressing shift key Press Fn key,
       
   448                 // So its goes to function upper mode
       
   449                 if( iFepMan.IsFlagSet(CAknFepManager::EFlagQwertyShiftMode))
       
   450                 	iFepMan.SetCase( EFnKeyUpperCase );
       
   451                 else
       
   452                     iFepMan.SetCase( EFnKeyLowerCase );
       
   453                 }
       
   454             else
       
   455                 {
       
   456                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyNone"));
       
   457                 
       
   458                 // For Shift key handling.
       
   459                 if( EFnKeyDown == iFnKeyState || EFnKeyNext == iFnKeyState )
       
   460                     {
       
   461                     iFepMan.SetCase( (TCase)iPreviousCase );
       
   462                     }
       
   463                 iFnKeyState = EFnKeyNone;
       
   464                 }
       
   465             if( EEventKeyUp == aType && iFnKeyState == EFnKeyNone )
       
   466                 {
       
   467                 // To fix the bug :Fn key lock. then type a number with short press at begin of 
       
   468                 // editor. Now press Fn key to go to Fn none state. 
       
   469                 // Press a character. The char is in upper case
       
   470                 if (ELowerCase == caseFromFep)
       
   471 		            {
       
   472 		            iFepMan.SetCase( (TCase)caseFromFep );
       
   473 		            }
       
   474 		        // To Fix Error: Character is NOT entered as per the input mode
       
   475 		        // when the character is entered after pressing Shift + Fn + Shift keys
       
   476 		        else if(!(EStdKeyRightShift == aKeyEvent.iScanCode ||
       
   477 		            	  EStdKeyLeftShift == aKeyEvent.iScanCode))
       
   478 		            {
       
   479 		            iFepMan.SetCase( (TCase)iPreviousCase );	
       
   480 		            }
       
   481                 }
       
   482             iFepMan.UpdateIndicators();
       
   483             return keyResponse;
       
   484             }
       
   485         }
       
   486                 
       
   487     // Now detect the input mode for telephone and calculator apps
       
   488 /*    if ( aInputCapabilities.IsNone() )
       
   489         {   // Idle and Calculator do not provide input capabilities at all.
       
   490         if ( KPhoneUidAppPhone == aCurrentTopAppUid || KUidIdle == aCurrentTopAppUid )
       
   491             {
       
   492             aInputCapabilities.SetCapabilities( TCoeInputCapabilities::EDialableCharacters );
       
   493             }
       
   494         if ( aCurrentTopAppUid == KUidCalc )
       
   495             {
       
   496             aInputCapabilities.SetCapabilities( TCoeInputCapabilities::EWesternNumericReal );
       
   497             }
       
   498         }        
       
   499 */        
       
   500     // Now handle the automatic number mode
       
   501     if ((iFnKeyState != EFnKeyForced) && 
       
   502         ( aInputCapabilities.SupportsWesternNumericIntegerPositive() ||
       
   503          aInputCapabilities.SupportsWesternNumericIntegerNegative() ||
       
   504          aInputCapabilities.SupportsWesternNumericReal() ||
       
   505          aInputCapabilities.SupportsDialableCharacters() )         
       
   506        )
       
   507         {
       
   508         // If input mode is numeric, Fn key is automated (=forced)
       
   509         iFnKeyState = EFnKeyForced;
       
   510         
       
   511         UpdatePreviousCase();
       
   512         
       
   513         iFepMan.SetCase( EFnKeyLowerCase );
       
   514         iFepMan.UpdateIndicators();
       
   515         //Forced input mode
       
   516         // The CR key KAknFepFnKeyState set to Locked
       
   517         iSharedDataInterface->SetFnKeyState(EFnKeyForced/*=6*/);        
       
   518         CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyForced"));   
       
   519         }
       
   520 #ifdef __REVERSE_FN_KEY_SUPPORTED
       
   521     //Reverse Fn Key mapping!
       
   522     //Just one of the cases for Reverse Fn key mapping!
       
   523     // There are manu more of these!
       
   524     if((EFnKeyForced == iFnKeyState && aKeyEvent.iModifiers & EModifierRightFunc ) )
       
   525     	{    	
       
   526     	iFepMan.SetCase( (TCase)iPreviousCase );    	
       
   527     	iFepMan.SetReverseFnkeyInputMode(ETrue);    	
       
   528     	}
       
   529     else if(iFepMan.IsReverseFnkeyInput())
       
   530     	{
       
   531     	iFepMan.SetReverseFnkeyInputMode(EFalse);           
       
   532         iFepMan.SetCase(EFnKeyLowerCase);
       
   533     	}
       
   534 #endif //__REVERSE_FN_KEY_SUPPORTED
       
   535         
       
   536     // If any of the following states apply, the key event should be exchanged.        
       
   537     if ( EFnKeyPressed == iFnKeyState ||
       
   538          EFnKeyDown == iFnKeyState ||
       
   539          EFnKeyNext == iFnKeyState ||
       
   540          EFnKeyPressedAgain == iFnKeyState ||
       
   541          EFnKeyLock == iFnKeyState ||
       
   542          EFnKeyForced == iFnKeyState )
       
   543         {
       
   544         // For telephone number editor key events for w, p and + must be accepted as is
       
   545         if( aInputCapabilities.SupportsDialableCharacters() && ( 'W' == aKeyEvent.iScanCode ||
       
   546                                                                  'P' == aKeyEvent.iScanCode ||
       
   547                                                                  '+' == aKeyEvent.iScanCode ||
       
   548                                                                  'w' == aKeyEvent.iCode ||
       
   549                                                                  'p' == aKeyEvent.iCode ||
       
   550                                                                  '+' == aKeyEvent.iCode) )
       
   551             {
       
   552             return keyResponse;
       
   553             }
       
   554             
       
   555         if( EEventKeyUp == aType )
       
   556             {
       
   557             if ( EFnKeyPressed == iFnKeyState || EFnKeyPressedAgain == iFnKeyState )
       
   558                 {
       
   559                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyDown"));
       
   560                 iFnKeyState = EFnKeyDown;                
       
   561                 UpdatePreviousCase();
       
   562                 
       
   563                 // Fn key hold on and press any key
       
   564                 if( iFepMan.IsFlagSet(CAknFepManager::EFlagQwertyShiftMode))
       
   565                 	iFepMan.SetCase( EFnKeyUpperCase );
       
   566                 else
       
   567                 	iFepMan.SetCase( EFnKeyLowerCase );
       
   568                 }
       
   569                 
       
   570              // Debasish MT error fixing
       
   571             else if( EFnKeyNext == iFnKeyState && iFepMan.IsFlagSet(CAknFepManager::EFlagQwertyShiftMode))
       
   572 	            {
       
   573 	            // keep the sate as it is
       
   574 	            UpdatePreviousCase();	
       
   575 	            iFepMan.SetCase( EFnKeyUpperCase );
       
   576 	            
       
   577 	            if( keyboardType == EPtiKeyboardHalfQwerty )
       
   578                     {
       
   579                     iFepMan.SetCase( EFnKeyLowerCase );
       
   580                     }
       
   581 	            }
       
   582             else if ( EFnKeyNext == iFnKeyState )
       
   583                 {
       
   584                 //This has to be done if the keyboard type is not half Qwerty
       
   585                 if(keyboardType == EPtiKeyboardHalfQwerty)
       
   586                     return keyResponse;
       
   587                 CEikonEnv::Static()->InfoMsg(_L("iFnKeyState = EFnKeyNone"));
       
   588                 
       
   589                 // To fix the bug : At begin of editor, press Fn key. Now press a number.
       
   590                 // Now state is FnKeyNone. Type any char. The case is upper.
       
   591                 // For Shift key handling.
       
   592                 if( EFnKeyDown == iFnKeyState || EFnKeyNext == iFnKeyState )
       
   593                     {
       
   594 		 			if (ELowerCase == caseFromFep)
       
   595 	            		{
       
   596 	            		iFepMan.SetCase( (TCase)caseFromFep );
       
   597 	            		}
       
   598 			        // To Fix Error: Character is NOT entered as per the input mode
       
   599 			        // when the character is entered after pressing Shift + Fn + Shift keys
       
   600 		 			else if(!(EStdKeyRightShift == aKeyEvent.iScanCode ||  
       
   601 		 						  EStdKeyLeftShift == aKeyEvent.iScanCode))
       
   602 	            		{
       
   603 	            		iFepMan.SetCase( (TCase)iPreviousCase );	
       
   604 	            		}
       
   605                     }
       
   606                  iFnKeyState = EFnKeyNone;
       
   607                 }
       
   608             iFepMan.UpdateIndicators();
       
   609             }                        
       
   610         }
       
   611 
       
   612     return keyResponse;
       
   613     }
       
   614   
       
   615 void CAknFepFnKeyManager::UpdatePreviousCase()
       
   616     {
       
   617     iPreviousCase = iFepMan.GetCurrentCase();
       
   618     }
       
   619 // End of File
       
   620