diff -r ebd48d2de13c -r ecbabf52600f fep/aknfep/src/aknfepuiinputstateinitialindicphoneticmultitap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fep/aknfep/src/aknfepuiinputstateinitialindicphoneticmultitap.cpp Wed Sep 01 12:23:33 2010 +0100 @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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 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 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( 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