fep/aknfep/src/aknfepuiinputstateinitialindicphoneticmultitap.cpp
changeset 40 2cb9bae34d17
parent 31 f1bdd6b078d1
child 49 37f5d84451bd
equal deleted inserted replaced
31:f1bdd6b078d1 40:2cb9bae34d17
     1 /*
       
     2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:            Provides the TAknFepInputStateInitialIndicPhoneticMultitap methods.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 
       
    28 #include "aknfepuiinputstateinitialindicphoneticmultitap.h"
       
    29 #include "AknFepUIManagerStateInterface.h"      //MAknFepUIManagerStateInterface
       
    30 #include "AknFepUIManagerWestern.h"
       
    31 #include "AknFepUiIndicEnums.h"
       
    32 #include "AknFepCaseManager.h"
       
    33 #include "AknFepUiIndicInputManager.h"
       
    34 
       
    35 #include <uikon.hrh>
       
    36 #include <PtiEngine.h>
       
    37 #include <PtiDefs.h>
       
    38 #include <aknsctdialog.h>
       
    39 #include <avkon.rsg>
       
    40 #include <aknfep.rsg>
       
    41 #include <EikEnv.h>
       
    42 #include <Aknutils.h>
       
    43 #define PHONETIC_SEPARATOR 0x2e
       
    44 
       
    45 const TUint KSpaceChar = 0x0020;
       
    46 const TUint KQuestionMark = 0x003F;
       
    47 
       
    48 #define PTI_CLEAR_CURRENTWORD( A, B ) \
       
    49 		( A )->ClearCurrentWord(); \
       
    50 		( B ) = ETrue; \
       
    51 
       
    52 const TText KAknFEPLineFeedSymbol = 0x21B2;
       
    53 const TText KAknFEPMirroredLineFeedSymbol = 0x21B3;
       
    54 	
       
    55 // -----------------------------------------------------------------------------
       
    56 // TAknFepInputStateInitialIndicPhoneticMultitap::TAknFepInputStateInitialIndicPhoneticMultitap
       
    57 
       
    58 // C++ default constructor can NOT contain any code, that
       
    59 // might leave or if it is absolutely necessary then MUST be trapped.
       
    60 // -----------------------------------------------------------------------------
       
    61 
       
    62 TAknFepInputStateInitialIndicPhoneticMultitap::
       
    63 TAknFepInputStateInitialIndicPhoneticMultitap( MAknFepUIManagerStateInterface* aOwner,
       
    64 																			TInt aLanguage )
       
    65 																			:TAknFepInputStateInitialMultitapBase( aOwner )
       
    66     {
       
    67     CPtiEngine* ptiengine = iOwner->PtiEngine();
       
    68     iIsStarKeyPressed = EFalse;
       
    69     iIndicLanguage = TLanguage(aLanguage);
       
    70     iIndicPhoneticBuffer.Zero();
       
    71     TRAP_IGNORE( ptiengine->ActivateLanguageL(KLangHindiPhonetic,
       
    72                  EPtiEngineInputModeIndicPhoneticMultitap))
       
    73     ptiengine->SetCase( EPtiCaseLower );
       
    74     iPreviousCommittedChar = NULL;
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL
       
    79 
       
    80 // Handles the logic of Indic multitap input. This function first checks the validity
       
    81 // of the inputed text and then enters it.
       
    82 // -----------------------------------------------------------------------------
       
    83 
       
    84 TBool TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL( TInt aKey, 
       
    85                                                                  TKeyPressLength aLength )
       
    86 	{
       
    87 	TBool                      result       	= ETrue;
       
    88 	MAknFepManagerUIInterface* fepMan       	= iOwner->FepMan();
       
    89 	CPtiEngine* 			   ptiengine 		= iOwner->PtiEngine();
       
    90 	
       
    91 	if(aKey == EKeyBackspace)
       
    92 		{
       
    93 		iIndicPhoneticBuffer.Zero();
       
    94 		iPhoneticLatinChar = 0;	
       
    95     	iPreviousCommittedChar = 0;						
       
    96 		}
       
    97 	else if(fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches) 
       
    98            && aKey != EPtiKey0 && aLength != ELongKeyPress)
       
    99 		{
       
   100 		//no matches, so just play tone
       
   101         fepMan->PlaySound(EAvkonSIDConfirmationTone);
       
   102 		}
       
   103 	else
       
   104 		{
       
   105 		if ( iData && ( iData != aKey ) && (!iIsStarKeyPressed ))
       
   106 	    	{
       
   107 	    	//iPrevCharacter = 
       
   108 	    	TransliterateFromLatinL();
       
   109 		    PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired )
       
   110 		    // = ;
       
   111 	   		}
       
   112 		iIsStarKeyPressed = EFalse;
       
   113 		if ( aLength == EShortKeyPress )
       
   114 			{
       
   115 		    if ( aKey == EPtiKeyStar ) // Overriding Key
       
   116 	            {
       
   117 		    	ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );	
       
   118 		    	iIsStarKeyPressed = ETrue;
       
   119 	    		}
       
   120 			else
       
   121 				{
       
   122 				TPtrC ptiText = ptiengine->AppendKeyPress( ( TPtiKey )aKey );
       
   123 				iPhoneticLatinChar = ptiText[0];
       
   124 				
       
   125 				if (IsToTransliterate(iPhoneticLatinChar) 
       
   126 				&& (!fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)))
       
   127 			    	{
       
   128 			    	TBuf<CAknFepManager::EMaximumFepWordLength> buf;
       
   129 		            buf.Copy(iIndicPhoneticBuffer);
       
   130 		            buf.Append(ptiText);
       
   131 					fepMan->NewCharacterSequenceL(buf,EIndicInputResponsePhoneticMultitapText);
       
   132 			    	}
       
   133 				else if(!IsToTransliterate(iPhoneticLatinChar))
       
   134 					{
       
   135 					TChar prevcharacter(fepMan->PreviousChar());
       
   136 					
       
   137 					if((fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)) && (KQuestionMark == prevcharacter))
       
   138 						{
       
   139 						fepMan->RemovePreviousCharacterL();		
       
   140 						fepMan->ClearFlag(CAknFepManager::EFlagNoMatches);	
       
   141 						ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
       
   142 						}
       
   143 					iIndicPhoneticBuffer.Zero();
       
   144 					if(IsToTransliterate(prevcharacter) && prevcharacter != '0')
       
   145 						fepMan->CommitInlineEditL();	
       
   146 					fepMan->NewCharacterSequenceL(ptiText,EIndicInputResponseNone);
       
   147 					}
       
   148 				}
       
   149 			}
       
   150 	   	else
       
   151 	    	{
       
   152 	    	if(fepMan->PreviousChar() == KQuestionMark)
       
   153 				{
       
   154 				fepMan->RemovePreviousCharacterL();		
       
   155 				}
       
   156 			fepMan->ClearFlag(CAknFepManager::EFlagNoMatches);
       
   157 
       
   158 	        /* Long press of a Key */
       
   159 	        if ( aKey == EPtiKeyStar)
       
   160 		        {
       
   161 	        	
       
   162 	            /* Launch the SCT For Indic */
       
   163 	   			if( fepMan->EditorHasFreeSpace() )
       
   164 					{
       
   165 					if (fepMan->IsAbleToLaunchSCT() && !fepMan->EditSubmenuInUse())
       
   166 	        			{        			
       
   167 		            	fepMan->LaunchSpecialCharacterTableL();	
       
   168 		            	}
       
   169 					}
       
   170 			    }
       
   171 	        else
       
   172 		        {
       
   173 		        //commit the inline text
       
   174 		        fepMan->CommitInlineEditL();
       
   175 		        //Remove one character, to remove the Latin character
       
   176 		        //appended because of the short key press. This is 
       
   177 		        //because long key press results  in short key press 
       
   178 		        //and then long key press.
       
   179 		        fepMan->RemovePreviousCharacterL();
       
   180 		        //Reset the phonetic state in FEP. So, that any further 
       
   181 		        //phonetic conversion will start from fresh.
       
   182 		        iIndicPhoneticBuffer.SetLength(0);
       
   183 		        iPhoneticLatinChar = 0;	
       
   184     	        iPreviousCommittedChar = 0;
       
   185     	        
       
   186 		        ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
       
   187 		        TUint prevchar = fepMan->PreviousChar(ETrue);
       
   188 	            if(!((aKey == EPtiKey1) && ((0x0031 == prevchar) || (0x0967 == prevchar)) ))
       
   189 			        {
       
   190 					TChar ch( aKey );
       
   191 			        TBuf<1> buf;
       
   192 			        buf.Append( ch );
       
   193 			        fepMan->NewCharacterSequenceL( buf, EIndicInputResponseNumber );
       
   194 					fepMan->CommitInlineEditL();			
       
   195 					PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired )				
       
   196 					}
       
   197 		        }
       
   198 	    	}
       
   199 	    iData = aKey;
       
   200 		}
       
   201    //hindi phonetic changes
       
   202    if(iPhoneticLatinChar.IsUpper())
       
   203 	{
       
   204 		fepMan->HandleIndicCaseL();
       
   205 	}
       
   206     return( result );
       
   207 	}
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired
       
   211 
       
   212 // Handles the logic of post keytimerexpired event. This function commits 
       
   213 // the inline editing text to the editor.
       
   214 // -----------------------------------------------------------------------------
       
   215 
       
   216 void TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired()
       
   217 	{
       
   218 	TRAP_IGNORE(HandleKeyTimerExpiryL())
       
   219 	iData = 0;	
       
   220 	iOwner->PtiEngine()->ClearCurrentWord();
       
   221 	if((iPreviousCommittedChar = iOwner->FepMan()->PreviousChar()) == 0x002E)
       
   222 		iPreviousCommittedChar = iOwner->FepMan()->PreviousToPreviousChar(ETrue);
       
   223 	iIsKeyTimerExpired = ETrue;
       
   224 	}
       
   225 	
       
   226 void TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyTimerExpiryL()
       
   227 	{
       
   228 	CPtiEngine* ptiengine = iOwner->PtiEngine();
       
   229 	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();	
       
   230 	if ( !(fepMan->EditorHasFreeSpace() 
       
   231        || fepMan->IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction)))
       
   232 	    {
       
   233 	    return;
       
   234 	    }
       
   235 	if(iData && ( IsToTransliterate(iPhoneticLatinChar) &&  iData != EPtiKeyStar) 
       
   236      && !fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
       
   237 		{
       
   238 		TransliterateFromLatinL();
       
   239 		}
       
   240 	else if ( !IsToTransliterate (iPhoneticLatinChar))
       
   241         {
       
   242 		MPtiLanguage* ptilang = ptiengine->CurrentLanguage();
       
   243 	    TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0;
       
   244 		// Space clears Explicite halant for North Indian Languages.
       
   245 		if(IsToRemoveHalantForLanguage(languageCode))
       
   246 			{
       
   247 			RemoveHalantL(TLanguage(languageCode));
       
   248 			}	
       
   249 		ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
       
   250 		fepMan->CommitInlineEditL();
       
   251 		iIndicPhoneticBuffer.Zero();
       
   252         }	
       
   253 	else
       
   254 		{
       
   255 		iOwner->FepMan()->CommitInlineEditL();
       
   256     	iIndicPhoneticBuffer.Zero();
       
   257 		}	
       
   258 	}
       
   259 
       
   260 void TAknFepInputStateInitialIndicPhoneticMultitap :: TransliterateFromLatinL() 
       
   261 	{
       
   262 	TPhoneticArg arg;
       
   263     TBuf<CAknFepManager::EMaximumFepWordLength> destinationbuf;
       
   264     destinationbuf.Zero();               
       
   265 	TInt errorcode = 0; 
       
   266 	CPtiEngine* ptiengine = iOwner->PtiEngine();
       
   267 	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
       
   268 	MPtiLanguage* ptilang = iOwner->PtiEngine()->CurrentLanguage();
       
   269     TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0;
       
   270 	    
       
   271 	arg.iChar = iPhoneticLatinChar;
       
   272 	arg.iDest = & destinationbuf;
       
   273 	errorcode = ptiengine->HandleCommandL(EPtiCommandGetPhoneticText,REINTERPRET_CAST( TAny*, &arg));
       
   274 	AknTextUtils::LanguageSpecificNumberConversion(destinationbuf);
       
   275 	switch(errorcode)
       
   276     	{
       
   277     	case KErrNone:
       
   278     		{
       
   279     		if(arg.iState == EIndicSyllableStateSyllableBroken)
       
   280     			{
       
   281 				if(iIndicPhoneticBuffer.Length())
       
   282 					{
       
   283 					fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length());
       
   284 					iPreviousCommittedChar = fepMan->PreviousChar(ETrue);
       
   285 					iIndicPhoneticBuffer.Zero();
       
   286 					}
       
   287       			}
       
   288 
       
   289 			if (destinationbuf.Length())
       
   290 	            {
       
   291 	            	if(! ValidatePhoneticInputL(destinationbuf, TLanguage(languageCode)))
       
   292 	            		{
       
   293 	            		break;	
       
   294 	            		}
       
   295 	            	
       
   296 	            fepMan->NewCharacterSequenceL(destinationbuf,
       
   297 	                                          EIndicInputResponsePhoneticMultitapText);
       
   298 
       
   299         		if(TAknFepUiIndicInputManager::IsCharOther(destinationbuf[0],
       
   300         		     TLanguage(languageCode)) && 0x002E != destinationbuf[0])
       
   301         			{
       
   302         			fepMan->CommitInlineEditL();
       
   303         			iIndicPhoneticBuffer.Zero();
       
   304         			}
       
   305 				else
       
   306 					{
       
   307         			iIndicPhoneticBuffer.Copy(destinationbuf);
       
   308 					}
       
   309 	            }
       
   310     		}
       
   311     	break;
       
   312     	case KErrOverflow:
       
   313     		{
       
   314 			fepMan->NewCharacterSequenceL(destinationbuf,EIndicInputResponsePhoneticMultitapText);    		
       
   315     		fepMan->CommitInlineEditL();
       
   316         	ptiengine->HandleCommandL(EPtiCommandClearPhoneticBuffer,NULL);
       
   317     		}
       
   318     	break;
       
   319     	default:
       
   320     	break;
       
   321     	}
       
   322     iPhoneticLatinChar = 0;	
       
   323 	}
       
   324 
       
   325 TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToRemoveHalantForLanguage(TInt aLanguage)
       
   326 	{
       
   327 	TBool ret = EFalse;
       
   328 	switch(aLanguage)
       
   329 		{
       
   330 		case KLangHindiPhonetic:
       
   331 			ret = ETrue;
       
   332 		break;
       
   333 		}
       
   334 	return ret;	
       
   335 	}
       
   336 	
       
   337 inline TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToTransliterate(TChar& aChar)
       
   338 	{
       
   339 	return !(KAknFEPLineFeedSymbol == aChar || KSpaceChar == aChar);
       
   340 	}
       
   341 	
       
   342 TBool TAknFepInputStateInitialIndicPhoneticMultitap::ValidatePhoneticInputL(const TDes& aBuf, 
       
   343                                                                             TLanguage aLanguage)
       
   344 	{
       
   345 	TBool ret = ETrue;
       
   346     TUint curChar = 0;
       
   347     TUint prevChar=0;
       
   348     TUint len=aBuf.Length();
       
   349     TPtr buffer(const_cast<TText*>( aBuf.Ptr() ),len,len);
       
   350 	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
       
   351 	TPtiTextCase newCase = iOwner->PtiEngine()->Case();
       
   352 	if(! iPreviousCommittedChar)
       
   353 		{
       
   354 		iPreviousCommittedChar = fepMan->PreviousChar(ETrue);	
       
   355 		}
       
   356        while(len)
       
   357                 {
       
   358                 if(buffer[len-1] == 0x94d)
       
   359                     {
       
   360                     len--;
       
   361                     buffer.SetLength(len);
       
   362                     continue;
       
   363                     }
       
   364                 else if(!curChar)
       
   365                     {
       
   366                     curChar = buffer[len-1] ;
       
   367                     len--;
       
   368                     }
       
   369                 else if(!prevChar)
       
   370                     {
       
   371                     prevChar = buffer[len-1] ;
       
   372                     len--;
       
   373                     }
       
   374                 else
       
   375                     break;
       
   376                 }
       
   377        if(!prevChar)
       
   378             prevChar = iPreviousCommittedChar;
       
   379        /*
       
   380        Multitap does not allow any fall back characters. The phonetic engine does not
       
   381        check for the fallback characters and FEP has to do it.
       
   382        */
       
   383        //fallback character if Nukta is entered after Nukta
       
   384        if((TAknFepUiIndicInputManager::IsCharNukta(prevChar,aLanguage) && 
       
   385         TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) ||
       
   386         
       
   387         //fallback character if Nukta is entered after Modifier or
       
   388         //Modifier is entered after Modifier
       
   389         (TAknFepUiIndicInputManager::IsCharModifier(prevChar,aLanguage) && 
       
   390         (TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage) ||
       
   391         TAknFepUiIndicInputManager::IsCharModifier(curChar,aLanguage))) ||
       
   392         
       
   393         //fallback character if Nukta is entered after Vowel or
       
   394         //Nukta is entered after matra
       
   395        ((TAknFepUiIndicInputManager::IsCharAnVowel(prevChar,aLanguage) ||
       
   396        TAknFepUiIndicInputManager::IsCharMatra(prevChar,aLanguage)) && 
       
   397         TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage))  ||
       
   398         //fallback character if Nukta is entered after Nukta Consonant
       
   399         (TAknFepUiIndicInputManager::IsCharNuktaConsonant(prevChar,aLanguage) &&
       
   400         TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) ||
       
   401         
       
   402         //fallback character if Nukta entered in an empty editor
       
   403         (prevChar == PHONETIC_SEPARATOR &&
       
   404         TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage))
       
   405         )
       
   406            {
       
   407             TBuf<1> buffer;
       
   408             fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length());
       
   409 	        buffer.Append(KQuestionMark);
       
   410 		if(!fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction))
       
   411 			{
       
   412 			fepMan->StartInlineEditL();	
       
   413 			}
       
   414         fepMan->UpdateInlineEditL(buffer,CAknFepManager::ESingleCharacter);
       
   415         fepMan->SetFlag(CAknFepManager::EFlagNoMatches);
       
   416 		ret = EFalse;
       
   417 		}
       
   418 	return ret;
       
   419 	}
       
   420 	
       
   421 TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsInvalidPhoneticCharacter( 
       
   422                                               TUint aChar, TLanguage aLanguage )
       
   423 	{
       
   424 	TBool ret = EFalse;
       
   425 	if(TAknFepUiIndicInputManager::IsCharNukta( aChar, aLanguage )
       
   426 	   || TAknFepUiIndicInputManager::IsCharMatra( aChar,  aLanguage )
       
   427 	   || TAknFepUiIndicInputManager::IsCharModifier( aChar,  aLanguage )
       
   428 	   || TAknFepUiIndicInputManager::IsCharVirama( aChar,  aLanguage ))
       
   429 		{	
       
   430 		ret = ETrue;
       
   431 		}
       
   432 	return ret;	
       
   433 	}
       
   434 
       
   435 void TAknFepInputStateInitialIndicPhoneticMultitap::RemoveHalantL(TLanguage aLanguage)
       
   436 	{
       
   437 	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
       
   438 	TBool isLineFeedEntered = fepMan->IsFlagSet(CAknFepManager::EFlagLineFeedCharacter);
       
   439 	if (fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction))
       
   440         {
       
   441         fepMan->CommitInlineEditL();
       
   442         }
       
   443 
       
   444 	TInt position = 0;
       
   445 	
       
   446     if(TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousChar(ETrue), aLanguage))
       
   447     	{
       
   448     	position = 1;
       
   449     	}
       
   450     else if(!isLineFeedEntered && 
       
   451     TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousToPreviousChar(ETrue), aLanguage))
       
   452     	{
       
   453     	position = 2;	
       
   454     	}
       
   455     if(position)	
       
   456     	fepMan->RemoveTextFromEditorL( 1, position-1, EFalse );
       
   457    	if(fepMan->NextChar() == KSpaceChar)
       
   458    		{
       
   459    		fepMan->AlignLogicalAndVisualCursorL(TTmDocPosSpec::ELeading, EFalse);	
       
   460    		}
       
   461 	}
       
   462 
       
   463 void TAknFepInputStateInitialIndicPhoneticMultitap::GetPhoneticLatinChar(TChar& aChar)const
       
   464 	{
       
   465 		aChar = iPhoneticLatinChar;
       
   466 	}
       
   467 //End of File