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