diff -r f1bdd6b078d1 -r 2cb9bae34d17 fep/aknfep/src/AknFepUiInputStateInitialIndicMultitap.cpp --- a/fep/aknfep/src/AknFepUiInputStateInitialIndicMultitap.cpp Tue Jul 06 14:38:41 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,712 +0,0 @@ -/* -* 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 TAknFepInputStateInitialIndicMultitap methods. -* -*/ - - - - - - - - - - - -#include "AknFepUIInputStateInitialIndicMultitap.h" -#include "AknFepUIManagerStateInterface.h" //MAknFepUIManagerStateInterface -#include "AknFepUiManagerWestern.h" -#include "AknFepUiIndicEnums.h" -#include "AknFepCaseManager.h" -#include "AknFepUiIndicInputManager.h" - -#include -#include -#include -#include -#include -#include -#include - -#define PTI_CLEAR_CURRENTWORD( A, B ) \ - ( A )->ClearCurrentWord(); \ - ( B ) = ETrue; \ - - -// ----------------------------------------------------------------------------- -// TAknFepInputStateInitialIndicMultitap::TAknFepInputStateInitialIndicMultitap - -// C++ default constructor can NOT contain any code, that -// might leave or if it is absolutely necessary then MUST be trapped. -// ----------------------------------------------------------------------------- - -TAknFepInputStateInitialIndicMultitap:: -TAknFepInputStateInitialIndicMultitap( MAknFepUIManagerStateInterface* aOwner, - TLanguage aLanguage ) - :TAknFepInputStateInitialMultitapBase( aOwner ) - { - CPtiEngine* ptiengine = iOwner->PtiEngine(); - iIsStarKeyPressed = EFalse; - iIsKeyTimerExpired = ETrue; - iIndicLanguage = aLanguage; - iIsHalantAllowed = EFalse; - iZWSPresent = EFalse; - iRephaPresent = EFalse; - iRakarPresent = EFalse; - iResponseInsertZWS = EFalse; - iLigaturePresent = EFalse; -#ifdef RD_MARATHI - iPreviousCommittedChar = 0; - iEyeLashRaPresent = EFalse; - iChandraAPresent = EFalse; -#endif // RD_MARATHI - TRAP_IGNORE( ptiengine->ActivateLanguageL( aLanguage ) ) - ptiengine->SetCase( EPtiCaseLower ); - } - -// ----------------------------------------------------------------------------- -// TAknFepInputStateInitialIndicMultitap::HandleKeyL - -// Handles the logic of Indic multitap input. This function first checks the validity -// of the inputed text and then enters it. -// ----------------------------------------------------------------------------- - -TBool TAknFepInputStateInitialIndicMultitap::HandleKeyL( TInt aKey, TKeyPressLength aLength ) - { - TBool result = ETrue; - MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); - CPtiEngine* ptiengine = iOwner->PtiEngine(); - -#ifdef RD_MARATHI - if( iIsKeyTimerExpired ) - { - iPreviousCommittedChar = fepMan->PreviousChar( ETrue ); - - if( iIndicLanguage == ELangMarathi ) - { - HandleKeyMarathiL(); - } - } -#endif // RD_MARATHI - - if(aKey == EPtiKey1) - { - iKey1Pressed = ETrue; - } - else - { - iKey1Pressed = EFalse; - } - if ( iData && ( iData != aKey ) ) - { -#ifdef RD_MARATHI - iPreviousCommittedChar = fepMan->PreviousChar( ETrue ); - - if( iPreviousCommittedChar == ZERO_WIDTH_SPACE && - aKey == EPtiKey2 ) - { - // This is a scenario where the timer is forcefully - // expired by quickly pressing a different key. - // Should remove the ZWS from the editor. - fepMan->RemovePreviousCharacterL(); - iZWSPresent = EFalse; - - // Reset the previous committed character. - iPreviousCommittedChar = fepMan->PreviousChar( ETrue ); - } - - if( iIndicLanguage == ELangMarathi ) - { - HandleKeyMarathiL(); - } -#endif // RD_MARATHI - - fepMan->CommitInlineEditL(); - PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired ) - - if( iRephaPresent ) - { - fepMan->AlignLogicalAndVisualCursorL( TTmDocPosSpec::ELeading, EFalse ); - iRephaPresent = EFalse; - } - if( iRakarPresent ) - { - iRakarPresent = EFalse; - } - -#ifdef RD_MARATHI - // This check should be done only after the text is committed. - if( iEyeLashRaPresent ) - { - // Calls the overloaded method which used find doc pos. - // Reason: Unlike Repha, EyeLash Ra can be inserted in - // an empty editor. GetNextVisualCursorPosition would - // result in incorrect cursor alignment in this case. - fepMan->AlignLogicalAndVisualCursorL(); - iEyeLashRaPresent = EFalse; - } -#endif - - } - - if ( aLength == EShortKeyPress ) - { - if ( aKey == EPtiKeyStar ) // Overriding Key - { - iIsStarKeyPressed = ETrue; - fepMan->RemoveZWSCharacterL( iKey1Pressed, EFalse, EFalse, iLigaturePresent ); - } - else - { - TPtiTextCase newCase = ptiengine->Case(); - - TIndicInputResponse keyResponse = - TAknFepUiIndicInputManager::ValidateInput( aKey, - fepMan->PreviousChar( ETrue ), - NULL,NULL, - iIsHalantAllowed, - iIsStarKeyPressed, - iIsKeyTimerExpired, - newCase, - aLength, - iIndicLanguage -#ifdef RD_MARATHI - , EFalse, EFalse, iChandraAPresent - -#endif // RD_MARATHI - ); - - ptiengine->SetCase( newCase ); - TPtrC ptiText = ptiengine->AppendKeyPress( ( TPtiKey )aKey ); - - if ( ptiText.Length() ) - { - do - { - TText prChar; - // For Repha, use the Previous to Previous character - // only if multitap timer hasn't expired. This will - // handle cases like Matra attached to the consonant. - // Here, repha is not allowed and the character to - // to checked is Matra. In cases like a consonant with - // Virama, all the characters should be skipped including - // repha. In this this case the timer is set to expired. - // So the previous character is Virama. And as per the - // language rules, repha is not allowed after Virama. - if( TAknFepUiIndicInputManager::IsCharRepha( - ptiText[0], iIndicLanguage ) && !iIsKeyTimerExpired ) - { - prChar = fepMan->PreviousToPreviousChar( ETrue ); -#ifdef RD_MARATHI - prChar = iPreviousCommittedChar; -#endif // RD_MARATHI - } - else - { - prChar = fepMan->PreviousChar( ETrue ); - } - - // When a base consonant is already entered and the - // user starts multitapping, the second modifier in the - // key map will not be allowed if the previous character - // is considered. The base consonant has to be used - // instead. This change had to be added after the new - // function, IsModifierAllowed was added. - if( TAknFepUiIndicInputManager::IsCharModifier( - ptiText[0], iIndicLanguage ) && !iIsKeyTimerExpired ) - { - prChar = fepMan->PreviousToPreviousChar( ETrue ); - } - - if( TAknFepUiIndicInputManager::IsCharLigature( - ptiText[0], iIndicLanguage ) && !iIsKeyTimerExpired ) - { - if( fepMan->IsZWSCharacterPresent( ETrue ) ) - { - iZWSPresent = ETrue; - } - iLigaturePresent = ETrue; - prChar = fepMan->PreviousToPreviousChar( ETrue ); - } - else - { - iLigaturePresent = EFalse; - } - -#ifdef RD_MARATHI - - // While multitapping after inserting a base consonant, - // modifiers will get inserted first, followed by the - // Nukta character. Hence, use Prev to prev char which - // will be a base consonant. - if( TAknFepUiIndicInputManager::IsCharNukta( - ptiText[0], iIndicLanguage ) && !iIsKeyTimerExpired ) - { - prChar = fepMan->PreviousToPreviousChar( ETrue ); - } -#endif // RD_MARATHI - - keyResponse = - TAknFepUiIndicInputManager::ValidateInput( aKey, - prChar, - ptiText[0], - NULL, - iIsHalantAllowed, - iIsStarKeyPressed, - iIsKeyTimerExpired, - newCase, - aLength, - iIndicLanguage, - iRakarPresent, - iZWSPresent -#ifdef RD_MARATHI - , iChandraAPresent -#endif // RD_MARATHI - ); - - if( !IsFreeSpaceAvailable( keyResponse ) ) - { - keyResponse = EIndicInputResponseInvalid; - } - - if( keyResponse == EIndicInputResponseInvalid ) - { - ptiText.Set( ptiengine->AppendKeyPress( ( TPtiKey )aKey ) ); - } - - if( !ptiText.Length() ) - { - break; - } - - }while( keyResponse == EIndicInputResponseInvalid ); - - if( iIsStarKeyPressed && - aKey == EPtiKey0 && - TAknFepUiIndicInputManager::IsCharOther( - ptiText[0], iIndicLanguage ) ) - { - // Forcefully keep the star key flag to true. Else when - // the ligatures are entered, this flag will be false - // thus preventing the ligature formation. - iIsStarKeyPressed = ETrue; - } - else - { - iIsStarKeyPressed = EFalse; - } - - result = HandleIndicKeyResponseL( aKey, keyResponse, ptiText ); - } - } - } - else - { - /* Long press of a Key */ - if ( aKey == EPtiKeyStar ) - { - /* Launch the SCT For Indic */ - if( fepMan->EditorHasFreeSpace() ) - { - if (fepMan->IsAbleToLaunchSCT() && !fepMan->EditSubmenuInUse()) - { - fepMan->LaunchSpecialCharacterTableL(); - } - } - } - else - { - 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; - return( result ); - } - -// ----------------------------------------------------------------------------- -// TAknFepInputStateInitialIndicMultitap::KeyTimerExpired - -// Handles the logic of post keytimerexpired event. This function commits -// the inline editing text to the editor. -// ----------------------------------------------------------------------------- - -void TAknFepInputStateInitialIndicMultitap::KeyTimerExpired() - { - iIsKeyTimerExpired = ETrue; - - if( iRakarPresent ) - { - iRakarPresent = EFalse; - } - - if( iRephaPresent -#ifdef RD_MARATHI - || ( iEyeLashRaPresent && - TAknFepUiIndicInputManager:: - IsCharBaseConsonant( iOwner->FepMan()->NextChar(), - iIndicLanguage ) ) -#endif // RD_MARATHI - ) - { - TRAP_IGNORE( iOwner->FepMan()->AlignLogicalAndVisualCursorL( TTmDocPosSpec::ELeading, EFalse ) ) - iRephaPresent = EFalse; - } - -#ifdef RD_MARATHI - iEyeLashRaPresent = EFalse; -#endif // RD_MARATHI - - if( iResponseInsertZWS || iZWSPresent ) - { - iZWSPresent = EFalse; - iResponseInsertZWS = EFalse; - TRAP_IGNORE( iOwner->FepMan()->RemoveZWSCharacterL( iKey1Pressed, EFalse, - EFalse, iLigaturePresent ) ) - } - iLigaturePresent = EFalse; - -#ifdef RD_MARATHI - iChandraAPresent = EFalse; -#endif // RD_MARATHI - - TAknFepInputStateInitialMultitapBase::KeyTimerExpired(); - } - -TBool TAknFepInputStateInitialIndicMultitap:: - HandleIndicKeyResponseL( TInt aKey, TIndicInputResponse aKeyResponse, TPtrC aPtiText ) - { - TBool result = ETrue; - MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); - - switch( aKeyResponse ) - { - case EIndicInputResponseNone: - { - if ( aPtiText.Length() && ( !iIsKeyTimerExpired || fepMan->EditorHasFreeSpace() ) ) - { - if ( iIsKeyTimerExpired ) - { - if ( iZWSPresent ) - { - fepMan->RemoveZWSCharacterL( iKey1Pressed,EFalse, - TAknFepUiIndicInputManager::IsCharModifier(aPtiText[0], iIndicLanguage)); - iZWSPresent = EFalse; - } - - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseNone ); - - if ( fepMan->IsZWSCharacterPresent() ) - { - iZWSPresent = ETrue; - } - } - else - { - if ( aKey == EPtiKey1 ) - { - if( iRephaPresent ) - { - fepMan->RemoveRephaCharacterL(); - iRephaPresent = EFalse; - } - if( iZWSPresent ) - { - fepMan->RemoveZWSCharacterL( iKey1Pressed, ETrue ); - iZWSPresent = EFalse; - } - if( iRakarPresent ) - { - // This is to handle the case when only - // two spaces are left in the editor. - fepMan->RemoveRakarCharacterL(); - iRakarPresent = EFalse; - } -#ifdef RD_MARATHI - iEyeLashRaPresent = EFalse; -#endif // RD_MARATHI - } - else if( aKey == EPtiKey2 ) - { -#ifdef RD_MARATHI - iChandraAPresent = EFalse; -#endif // RD_MARATHI - } - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseNone ); - } - } - iIsKeyTimerExpired = EFalse; - } - break; - - case EIndicInputResponseZWSandCharacter: - { - if( fepMan->EditorHasFreeSpace( 2 ) ) - { - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseZWSandCharacter ); - iZWSPresent = ETrue; - iIsKeyTimerExpired = EFalse; - } - } - break; - case EIndicInputResponseInsertZWS: - { - //Already in multitapping so we need to check wheather - //there is additional single space for ZWS - if( !iIsKeyTimerExpired || fepMan->EditorHasFreeSpace( 1 ) ) - { - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertZWS ); - - // Using a seperate flag here. Cannot use the flag - // iZWSPresent. Consider the scenario:- User enters - // a consonant, then multitaps key-1 to insert halant. - // Now consider that we set the flag to ETrue. - // But before the key timer expires, key-5 is - // multitapped to insert another consonant. - // In this case the code flow will go to the case - // EIndicInputResponseNone. Here the condition, - // if ( iZWSPresent ) succeeds and ZWS is removed. - // This causes direct ligature formation. It should - // actually show the ligature formation after the timeout. - iResponseInsertZWS = ETrue; - } - else // Remove already entered Modifier "Visarga" if there is no space - { - fepMan->RemovePreviousCharacterL(); - } - iIsKeyTimerExpired = EFalse; - } - break; - case EIndicInputResponseInsertZWSandLigature: - { - if( fepMan->EditorHasFreeSpace( 3 ) ) - { - if ( iIsKeyTimerExpired ) - { - fepMan->RemoveZWSCharacterL( iKey1Pressed ); - } - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertZWSandLigature ); - } - iIsKeyTimerExpired = EFalse; - iZWSPresent = ETrue; - } - break; - case EIndicInputResponseIgnore: - break; - - case EIndicInputResponseInsertRepha: - { - if( !iIsKeyTimerExpired ) - { - if( iRakarPresent ) - { - fepMan->RemoveRakarCharacterL(); - iRakarPresent = EFalse; - } -#ifdef RD_MARATHI - else if( iEyeLashRaPresent ) - { - // Remove eye lash ra - TBuf<3>buf; - - // Get the EyeLashRa string. - TAknFepUiIndicInputManager:: - GetEyeLashRa( buf, iIndicLanguage ); - - fepMan->RemoveTextFromEditorL( buf.Length(), 0, ETrue ); - iEyeLashRaPresent = EFalse; - } -#endif // RD_MARATHI - else if( TAknFepUiIndicInputManager::IsCharMatra( - fepMan->PreviousToPreviousChar( ETrue ), iIndicLanguage ) ) - { - // Consider that a matra is applied to any base - // consonant and two nore spaces are left in the editor. - // On multitapping, user will get the first four modifiers. - // After that, rakar should be inserted which requires two - // spaces. But since the modifier is present, only one - // space is available. Here we need to free up the space - // by removing the previous character which is a modifier. - // For inserting repha, the existing inline text needs to - // be first committed and then removed. - - fepMan->RemovePreviousCharacterL(); - } - - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertRepha ); - iRephaPresent = ETrue; - } - } - break; - - case EIndicInputResponseInsertRakar: - { - if( !iIsKeyTimerExpired ) - { - // RemoveZWS is not invoked here as we are in inline - // editing state and we can as well overwrite the previous - // characters. Hence directly invoke NewCharacterSequenceL. - // Secondly, the flag iZWSPresent is not reset here since - // it will happen anyways after timeout. - - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertRakar ); - iRakarPresent = ETrue; - -#ifdef RD_MARATHI - // This check assumes that Rakar comes after EyelashRa in - // Key map order. - iEyeLashRaPresent = EFalse; -#endif - } - } - break; - - case EIndicInputResponseInsertDirectLigature: - { - if( !iIsKeyTimerExpired ) - { - TBuf<3> ligature; - ligature.Zero(); - TAknFepUiIndicInputManager:: - GetLigature( ligature, aPtiText[0], - iIndicLanguage ); - - fepMan->NewCharacterSequenceL( ligature, - EIndicInputResponseInsertDirectLigature ); - } - } - break; - - case EIndicInputResponseInsertViramaZWSandDirectLigature: - { - if( fepMan->EditorHasFreeSpace( 5 ) ) - { - if ( iIsKeyTimerExpired ) - { - fepMan->RemoveZWSCharacterL( iKey1Pressed ); - } - - TBuf<3> ligature; - ligature.Zero(); - TAknFepUiIndicInputManager:: - GetLigature( ligature, aPtiText[0], - iIndicLanguage ); - fepMan->NewCharacterSequenceL( ligature, - EIndicInputResponseInsertViramaZWSandDirectLigature ); - } - iIsKeyTimerExpired = EFalse; - iZWSPresent = ETrue; - } - break; - - case EIndicInputResponseZWSandDirectLigature: - { - if( fepMan->EditorHasFreeSpace( 4 ) ) - { - TBuf<3> ligature; - ligature.Zero(); - TAknFepUiIndicInputManager:: - GetLigature( ligature, aPtiText[0], - iIndicLanguage ); - - fepMan->NewCharacterSequenceL( ligature, - EIndicInputResponseZWSandDirectLigature ); - iZWSPresent = ETrue; - iIsKeyTimerExpired = EFalse; - } - } - break; - -#ifdef RD_MARATHI - case EIndicInputResponseInsertEyeLashRa: - { - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertEyeLashRa ); - iIsKeyTimerExpired = EFalse; - iEyeLashRaPresent = ETrue; - } - break; - - case EIndicInputResponseInsertChandraA: - { - fepMan->NewCharacterSequenceL( aPtiText, EIndicInputResponseInsertChandraA ); - iChandraAPresent = ETrue; - } - break; -#endif // RD_MARATHI - - case EindicInputResponseLast: - break; - default: - { - } - break; - } - return result; - } - -TBool TAknFepInputStateInitialIndicMultitap::IsFreeSpaceAvailable( - TIndicInputResponse aKeyResponse ) - { - TBool result = ETrue; - - MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); - - TBool isUnlimitedSpaceEditor; - - TInt freeSpaceLeft = - fepMan->EditorFreeSpace( isUnlimitedSpaceEditor, ETrue ); - - // Check if space is available. - if( ( !isUnlimitedSpaceEditor ) && - ( ( ( aKeyResponse == EIndicInputResponseInsertRepha || - aKeyResponse == EIndicInputResponseInsertRakar ) && ( freeSpaceLeft < 2 ) ) || - ( ( aKeyResponse == EIndicInputResponseInsertDirectLigature ) && ( freeSpaceLeft < 3 ) ) -#ifdef RD_MARATHI - || ( ( aKeyResponse == EIndicInputResponseInsertEyeLashRa ) && ( freeSpaceLeft < 3 ) ) - || ( ( aKeyResponse == EIndicInputResponseInsertChandraA ) && ( freeSpaceLeft < 2 ) ) -#endif // RD_MARATHI - ) ) - { - result = EFalse; - } - return result; - } - -#ifdef RD_MARATHI - -void TAknFepInputStateInitialIndicMultitap::HandleKeyMarathiL() - { - MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); - - if( fepMan ) - { - if( fepMan->IsChandraAPresentL() ) - { - TBuf<1> buf; - TAknFepUiIndicInputManager::GetChandraA( buf, ETrue ); - iPreviousCommittedChar = buf[0]; - } - } - } -#endif // RD_MARATHI -//End of File