fep/aknfep/src/aknfepuiinputstateinitialindicphoneticmultitap.cpp
changeset 0 eb1f2e154e89
child 12 5e18d8c489d6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/aknfep/src/aknfepuiinputstateinitialindicphoneticmultitap.cpp	Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,467 @@
+/*
+* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0""
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:            Provides the TAknFepInputStateInitialIndicPhoneticMultitap methods.
+*
+*/
+
+
+
+
+
+
+
+
+
+
+
+#include "aknfepuiinputstateinitialindicphoneticmultitap.h"
+#include "AknFepUIManagerStateInterface.h"      //MAknFepUIManagerStateInterface
+#include "AknFepUIManagerWestern.h"
+#include "AknFepUiIndicEnums.h"
+#include "AknFepCaseManager.h"
+#include "AknFepUiIndicInputManager.h"
+
+#include <uikon.hrh>
+#include <PtiEngine.h>
+#include <PtiDefs.h>
+#include <aknsctdialog.h>
+#include <avkon.rsg>
+#include <AknFep.rsg>
+#include <EikEnv.h>
+#include <Aknutils.h>
+#define PHONETIC_SEPARATOR 0x2e
+
+const TUint KSpaceChar = 0x0020;
+const TUint KQuestionMark = 0x003F;
+
+#define PTI_CLEAR_CURRENTWORD( A, B ) \
+		( A )->ClearCurrentWord(); \
+		( B ) = ETrue; \
+
+const TText KAknFEPLineFeedSymbol = 0x21B2;
+const TText KAknFEPMirroredLineFeedSymbol = 0x21B3;
+	
+// -----------------------------------------------------------------------------
+// TAknFepInputStateInitialIndicPhoneticMultitap::TAknFepInputStateInitialIndicPhoneticMultitap
+
+// C++ default constructor can NOT contain any code, that
+// might leave or if it is absolutely necessary then MUST be trapped.
+// -----------------------------------------------------------------------------
+
+TAknFepInputStateInitialIndicPhoneticMultitap::
+TAknFepInputStateInitialIndicPhoneticMultitap( MAknFepUIManagerStateInterface* aOwner,
+																			TInt aLanguage )
+																			:TAknFepInputStateInitialMultitapBase( aOwner )
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    iIsStarKeyPressed = EFalse;
+    iIndicLanguage = TLanguage(aLanguage);
+    iIndicPhoneticBuffer.Zero();
+    TRAP_IGNORE( ptiengine->ActivateLanguageL(KLangHindiPhonetic,
+                 EPtiEngineInputModeIndicPhoneticMultitap))
+    ptiengine->SetCase( EPtiCaseLower );
+    iPreviousCommittedChar = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL
+
+// Handles the logic of Indic multitap input. This function first checks the validity
+// of the inputed text and then enters it.
+// -----------------------------------------------------------------------------
+
+TBool TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL( TInt aKey, 
+                                                                 TKeyPressLength aLength )
+	{
+	TBool                      result       	= ETrue;
+	MAknFepManagerUIInterface* fepMan       	= iOwner->FepMan();
+	CPtiEngine* 			   ptiengine 		= iOwner->PtiEngine();
+	
+	if(aKey == EKeyBackspace)
+		{
+		iIndicPhoneticBuffer.Zero();
+		iPhoneticLatinChar = 0;	
+    	iPreviousCommittedChar = 0;						
+		}
+	else if(fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches) 
+           && aKey != EPtiKey0 && aLength != ELongKeyPress)
+		{
+		//no matches, so just play tone
+        fepMan->PlaySound(EAvkonSIDConfirmationTone);
+		}
+	else
+		{
+		if ( iData && ( iData != aKey ) && (!iIsStarKeyPressed ))
+	    	{
+	    	//iPrevCharacter = 
+	    	TransliterateFromLatinL();
+		    PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired )
+		    // = ;
+	   		}
+		iIsStarKeyPressed = EFalse;
+		if ( aLength == EShortKeyPress )
+			{
+		    if ( aKey == EPtiKeyStar ) // Overriding Key
+	            {
+		    	ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );	
+		    	iIsStarKeyPressed = ETrue;
+	    		}
+			else
+				{
+				TPtrC ptiText = ptiengine->AppendKeyPress( ( TPtiKey )aKey );
+				iPhoneticLatinChar = ptiText[0];
+				
+				if (IsToTransliterate(iPhoneticLatinChar) 
+				&& (!fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)))
+			    	{
+			    	TBuf<CAknFepManager::EMaximumFepWordLength> buf;
+		            buf.Copy(iIndicPhoneticBuffer);
+		            buf.Append(ptiText);
+					fepMan->NewCharacterSequenceL(buf,EIndicInputResponsePhoneticMultitapText);
+			    	}
+				else if(!IsToTransliterate(iPhoneticLatinChar))
+					{
+					TChar prevcharacter(fepMan->PreviousChar());
+					
+					if((fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)) && (KQuestionMark == prevcharacter))
+						{
+						fepMan->RemovePreviousCharacterL();		
+						fepMan->ClearFlag(CAknFepManager::EFlagNoMatches);	
+						ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
+						}
+					iIndicPhoneticBuffer.Zero();
+					if(IsToTransliterate(prevcharacter) && prevcharacter != '0')
+						fepMan->CommitInlineEditL();	
+					fepMan->NewCharacterSequenceL(ptiText,EIndicInputResponseNone);
+					}
+				}
+			}
+	   	else
+	    	{
+	    	if(fepMan->PreviousChar() == KQuestionMark)
+				{
+				fepMan->RemovePreviousCharacterL();		
+				}
+			fepMan->ClearFlag(CAknFepManager::EFlagNoMatches);
+
+	        /* Long press of a Key */
+	        if ( aKey == EPtiKeyStar)
+		        {
+	        	
+	            /* Launch the SCT For Indic */
+	   			if( fepMan->EditorHasFreeSpace() )
+					{
+					if (fepMan->IsAbleToLaunchSCT() && !fepMan->EditSubmenuInUse())
+	        			{        			
+		            	fepMan->LaunchSpecialCharacterTableL();	
+		            	}
+					}
+			    }
+	        else
+		        {
+		        //commit the inline text
+		        fepMan->CommitInlineEditL();
+		        //Remove one character, to remove the Latin character
+		        //appended because of the short key press. This is 
+		        //because long key press results  in short key press 
+		        //and then long key press.
+		        fepMan->RemovePreviousCharacterL();
+		        //Reset the phonetic state in FEP. So, that any further 
+		        //phonetic conversion will start from fresh.
+		        iIndicPhoneticBuffer.SetLength(0);
+		        iPhoneticLatinChar = 0;	
+    	        iPreviousCommittedChar = 0;
+    	        
+		        ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
+		        TUint prevchar = fepMan->PreviousChar(ETrue);
+	            if(!((aKey == EPtiKey1) && ((0x0031 == prevchar) || (0x0967 == prevchar)) ))
+			        {
+					TChar ch( aKey );
+			        TBuf<1> buf;
+			        buf.Append( ch );
+			        fepMan->NewCharacterSequenceL( buf, EIndicInputResponseNumber );
+					fepMan->CommitInlineEditL();			
+					PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired )				
+					}
+		        }
+	    	}
+	    iData = aKey;
+		}
+   //hindi phonetic changes
+   if(iPhoneticLatinChar.IsUpper())
+	{
+		fepMan->HandleIndicCaseL();
+	}
+    return( result );
+	}
+
+// -----------------------------------------------------------------------------
+// TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired
+
+// Handles the logic of post keytimerexpired event. This function commits 
+// the inline editing text to the editor.
+// -----------------------------------------------------------------------------
+
+void TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired()
+	{
+	TRAP_IGNORE(HandleKeyTimerExpiryL())
+	iData = 0;	
+	iOwner->PtiEngine()->ClearCurrentWord();
+	if((iPreviousCommittedChar = iOwner->FepMan()->PreviousChar()) == 0x002E)
+		iPreviousCommittedChar = iOwner->FepMan()->PreviousToPreviousChar(ETrue);
+	iIsKeyTimerExpired = ETrue;
+	}
+	
+void TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyTimerExpiryL()
+	{
+	CPtiEngine* ptiengine = iOwner->PtiEngine();
+	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();	
+	if ( !(fepMan->EditorHasFreeSpace() 
+       || fepMan->IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction)))
+	    {
+	    return;
+	    }
+	if(iData && ( IsToTransliterate(iPhoneticLatinChar) &&  iData != EPtiKeyStar) 
+     && !fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
+		{
+		TransliterateFromLatinL();
+		}
+	else if ( !IsToTransliterate (iPhoneticLatinChar))
+        {
+		MPtiLanguage* ptilang = ptiengine->CurrentLanguage();
+	    TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0;
+		// Space clears Explicite halant for North Indian Languages.
+		if(IsToRemoveHalantForLanguage(languageCode))
+			{
+			RemoveHalantL(TLanguage(languageCode));
+			}	
+		ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL );
+		fepMan->CommitInlineEditL();
+		iIndicPhoneticBuffer.Zero();
+        }	
+	else
+		{
+		iOwner->FepMan()->CommitInlineEditL();
+    	iIndicPhoneticBuffer.Zero();
+		}	
+	}
+
+void TAknFepInputStateInitialIndicPhoneticMultitap :: TransliterateFromLatinL() 
+	{
+	TPhoneticArg arg;
+    TBuf<CAknFepManager::EMaximumFepWordLength> destinationbuf;
+    destinationbuf.Zero();               
+	TInt errorcode = 0; 
+	CPtiEngine* ptiengine = iOwner->PtiEngine();
+	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+	MPtiLanguage* ptilang = iOwner->PtiEngine()->CurrentLanguage();
+    TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0;
+	    
+	arg.iChar = iPhoneticLatinChar;
+	arg.iDest = & destinationbuf;
+	errorcode = ptiengine->HandleCommandL(EPtiCommandGetPhoneticText,REINTERPRET_CAST( TAny*, &arg));
+	AknTextUtils::LanguageSpecificNumberConversion(destinationbuf);
+	switch(errorcode)
+    	{
+    	case KErrNone:
+    		{
+    		if(arg.iState == EIndicSyllableStateSyllableBroken)
+    			{
+				if(iIndicPhoneticBuffer.Length())
+					{
+					fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length());
+					iPreviousCommittedChar = fepMan->PreviousChar(ETrue);
+					iIndicPhoneticBuffer.Zero();
+					}
+      			}
+
+			if (destinationbuf.Length())
+	            {
+	            	if(! ValidatePhoneticInputL(destinationbuf, TLanguage(languageCode)))
+	            		{
+	            		break;	
+	            		}
+	            	
+	            fepMan->NewCharacterSequenceL(destinationbuf,
+	                                          EIndicInputResponsePhoneticMultitapText);
+
+        		if(TAknFepUiIndicInputManager::IsCharOther(destinationbuf[0],
+        		     TLanguage(languageCode)) && 0x002E != destinationbuf[0])
+        			{
+        			fepMan->CommitInlineEditL();
+        			iIndicPhoneticBuffer.Zero();
+        			}
+				else
+					{
+        			iIndicPhoneticBuffer.Copy(destinationbuf);
+					}
+	            }
+    		}
+    	break;
+    	case KErrOverflow:
+    		{
+			fepMan->NewCharacterSequenceL(destinationbuf,EIndicInputResponsePhoneticMultitapText);    		
+    		fepMan->CommitInlineEditL();
+        	ptiengine->HandleCommandL(EPtiCommandClearPhoneticBuffer,NULL);
+    		}
+    	break;
+    	default:
+    	break;
+    	}
+    iPhoneticLatinChar = 0;	
+	}
+
+TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToRemoveHalantForLanguage(TInt aLanguage)
+	{
+	TBool ret = EFalse;
+	switch(aLanguage)
+		{
+		case KLangHindiPhonetic:
+			ret = ETrue;
+		break;
+		}
+	return ret;	
+	}
+	
+inline TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToTransliterate(TChar& aChar)
+	{
+	return !(KAknFEPLineFeedSymbol == aChar || KSpaceChar == aChar);
+	}
+	
+TBool TAknFepInputStateInitialIndicPhoneticMultitap::ValidatePhoneticInputL(const TDes& aBuf, 
+                                                                            TLanguage aLanguage)
+	{
+	TBool ret = ETrue;
+    TUint curChar = 0;
+    TUint prevChar=0;
+    TUint len=aBuf.Length();
+    TPtr buffer(const_cast<TText*>( aBuf.Ptr() ),len,len);
+	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+	TPtiTextCase newCase = iOwner->PtiEngine()->Case();
+	if(! iPreviousCommittedChar)
+		{
+		iPreviousCommittedChar = fepMan->PreviousChar(ETrue);	
+		}
+       while(len)
+                {
+                if(buffer[len-1] == 0x94d)
+                    {
+                    len--;
+                    buffer.SetLength(len);
+                    continue;
+                    }
+                else if(!curChar)
+                    {
+                    curChar = buffer[len-1] ;
+                    len--;
+                    }
+                else if(!prevChar)
+                    {
+                    prevChar = buffer[len-1] ;
+                    len--;
+                    }
+                else
+                    break;
+                }
+       if(!prevChar)
+            prevChar = iPreviousCommittedChar;
+       /*
+       Multitap does not allow any fall back characters. The phonetic engine does not
+       check for the fallback characters and FEP has to do it.
+       */
+       //fallback character if Nukta is entered after Nukta
+       if((TAknFepUiIndicInputManager::IsCharNukta(prevChar,aLanguage) && 
+        TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) ||
+        
+        //fallback character if Nukta is entered after Modifier or
+        //Modifier is entered after Modifier
+        (TAknFepUiIndicInputManager::IsCharModifier(prevChar,aLanguage) && 
+        (TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage) ||
+        TAknFepUiIndicInputManager::IsCharModifier(curChar,aLanguage))) ||
+        
+        //fallback character if Nukta is entered after Vowel or
+        //Nukta is entered after matra
+       ((TAknFepUiIndicInputManager::IsCharAnVowel(prevChar,aLanguage) ||
+       TAknFepUiIndicInputManager::IsCharMatra(prevChar,aLanguage)) && 
+        TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage))  ||
+        //fallback character if Nukta is entered after Nukta Consonant
+        (TAknFepUiIndicInputManager::IsCharNuktaConsonant(prevChar,aLanguage) &&
+        TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) ||
+        
+        //fallback character if Nukta entered in an empty editor
+        (prevChar == PHONETIC_SEPARATOR &&
+        TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage))
+        )
+           {
+            TBuf<1> buffer;
+            fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length());
+	        buffer.Append(KQuestionMark);
+		if(!fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction))
+			{
+			fepMan->StartInlineEditL();	
+			}
+        fepMan->UpdateInlineEditL(buffer,CAknFepManager::ESingleCharacter);
+        fepMan->SetFlag(CAknFepManager::EFlagNoMatches);
+		ret = EFalse;
+		}
+	return ret;
+	}
+	
+TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsInvalidPhoneticCharacter( 
+                                              TUint aChar, TLanguage aLanguage )
+	{
+	TBool ret = EFalse;
+	if(TAknFepUiIndicInputManager::IsCharNukta( aChar, aLanguage )
+	   || TAknFepUiIndicInputManager::IsCharMatra( aChar,  aLanguage )
+	   || TAknFepUiIndicInputManager::IsCharModifier( aChar,  aLanguage )
+	   || TAknFepUiIndicInputManager::IsCharVirama( aChar,  aLanguage ))
+		{	
+		ret = ETrue;
+		}
+	return ret;	
+	}
+
+void TAknFepInputStateInitialIndicPhoneticMultitap::RemoveHalantL(TLanguage aLanguage)
+	{
+	MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+	TBool isLineFeedEntered = fepMan->IsFlagSet(CAknFepManager::EFlagLineFeedCharacter);
+	if (fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction))
+        {
+        fepMan->CommitInlineEditL();
+        }
+
+	TInt position = 0;
+	
+    if(TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousChar(ETrue), aLanguage))
+    	{
+    	position = 1;
+    	}
+    else if(!isLineFeedEntered && 
+    TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousToPreviousChar(ETrue), aLanguage))
+    	{
+    	position = 2;	
+    	}
+    if(position)	
+    	fepMan->RemoveTextFromEditorL( 1, position-1, EFalse );
+   	if(fepMan->NextChar() == KSpaceChar)
+   		{
+   		fepMan->AlignLogicalAndVisualCursorL(TTmDocPosSpec::ELeading, EFalse);	
+   		}
+	}
+
+void TAknFepInputStateInitialIndicPhoneticMultitap::GetPhoneticLatinChar(TChar& aChar)const
+	{
+		aChar = iPhoneticLatinChar;
+	}
+//End of File