diff -r 000000000000 -r eb1f2e154e89 fep/aknfep/src/AknFepUiInputStateHalfQwerty.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fep/aknfep/src/AknFepUiInputStateHalfQwerty.cpp Tue Feb 02 01:02:04 2010 +0200 @@ -0,0 +1,668 @@ +/* +* Copyright (c) 2007 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 TAknFepInputStateHalfQwerty methods. +* +*/ + + + + + + + + + + + + +#include "AknFepUiInputStateHalfQwerty.h" +#include "AknFepUIManagerStateInterface.h" //MAknFepUIManagerStateInterface +#include "AknFepManagerUIInterface.h" //MAknFepManagerUIInterface +#include "AknFepCaseManager.h" + +#include +#include +#include +#include +#include + + +TAknFepInputStateHalfQwerty::TAknFepInputStateHalfQwerty(MAknFepUIManagerStateInterface* aOwner) + :TAknFepInputStateBase(aOwner) + { + iState = EInitial; + iData = 0; + CPtiEngine* ptiengine = iOwner->PtiEngine(); + ptiengine->ClearCurrentWord(); + ptiengine->SetInputMode(EPtiEngineHalfQwerty); + } + +TBool TAknFepInputStateHalfQwerty::HandleKeyL(TInt aKey, TKeyPressLength aLength) + { + TBool ret = EFalse; + CPtiEngine* ptiengine = iOwner->PtiEngine(); + if( ptiengine == NULL || aKey == EStdKeyNull || + aKey == EStdKeyF21 || aKey == EKeyF21 || aKey == EKeyF20 || aKey == EKeyF19 || + aKey == EStdKeyLeftArrow || aKey == EStdKeyRightArrow || aKey == EStdKeyDownArrow || aKey == EStdKeyUpArrow ) + return ret; + MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); + CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState(); + TPtiTextCase CurCase = ptiengine->Case(); + + if (iData && (iData != aKey) ) + { + ptiengine->CancelTimerActivity(); + fepMan->CommitInlineEditL(); + ptiengine->ClearCurrentWord(); + fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); + iData = 0; + } + // if it is a long key press of the punctuation key, + + if( aLength == ELongKeyPress && aKey == EStdKeyFullStop) + { + // Commit the current word and then do the usual stuff + ptiengine->CancelTimerActivity(); + } + if( !fepMan->EditorHasFreeSpace() && !iData ) + { + // Do not proceed as we have reached max limit and timer has expired + ptiengine->CancelTimerActivity(); + ptiengine->ClearCurrentWord(); + fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); + return 0; + } + + if( EStdKeyEnter == aKey ) + { + // Asynchronous case update. + fepMan->SimulateKeyEventL(EKeyF19); + return 0; + } + + if (!iOwner->PtiEngine()->IsValidKey((TPtiKey)aKey)) + { + iData = 0; + ChrKeyTimerExpired(); + fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); + ptiengine->CancelTimerActivity(); + return ret; + } + TPtrC text; + /* + if ( fepMan->IsOnlyNumericPermitted() ) + { + ptiengine->CancelTimerActivity(); + text.Set(ptiengine->AppendKeyPress((TPtiKey)aKey)); + TPtrC numericChars(KAllAllowedNumericChars, KNumAllowedIdleNumericChars); + if (text.Length() && numericChars.Locate(text[0]) != KErrNotFound) + { + TBuf<1> chr; + chr.Append(text[0]); + fepMan->NewCharacterL(chr); + ptiengine->CancelTimerActivity(); + fepMan->CommitInlineEditL(); + ptiengine->ClearCurrentWord(); + } + + return ETrue; + } + */ +#ifdef __REVERSE_FN_KEY_SUPPORTED + TInt origLanguage = ptiengine->CurrentLanguage()->LanguageCode(); + TPtiEngineInputMode origInputMode = ptiengine->InputMode(); + TBool languageChanged = EFalse; + + // In reverse fn key mapping filter the char applicable for + // Numeric editor. + if( fepMan->IsOnlyNumericPermitted() ) + { + + if( EStdKeyLeftFunc == aKey ) + { + TCallBack timerExpire(TimerExpire, this); + fepMan->MultitapThroughSCTCharL(timerExpire); + return ETrue; + } + else + { + ChrKeyTimerExpired(); + } + if( !fepMan->IsValidCharForNumericInFnReverseL( aKey, iOwner->PtiEngine()->Case() ) ) + { + if(CheckHasValidNumerKeyMappedL(aKey,languageChanged)) + return ETrue; + } + } + +#endif //__REVERSE_FN_KEY_SUPPORTED + + +// if( aLength == EShortKeyPress ) + { + /* + if (aKey == EStdKeySpace && (fnKeyState == CAknFepFnKeyManager::EFnKeyNone)) + { + _LIT(KSpaceCharacter, " "); + text.Set(KSpaceCharacter); + } + else*/ + if( aKey == EStdKeySpace && fepMan->FnKeyState() == CAknFepFnKeyManager::EFnKeyNone) + { + _LIT(KSpace," "); + fepMan->StartInlineEditL(); + fepMan->UpdateInlineEditL(KSpace,0); + fepMan->CommitInlineEditL(); + return ETrue; + } + else + { + TBool isCharacter = ETrue; + if (!iData) + { + isCharacter = IsCharacterKey(aKey); + } + HandleCaseChange(aKey, isCharacter); + CurCase = ptiengine->Case(); + + if(( (fepMan->IsHybridAplhaEditor() && !fepMan->IsHybridAlphaModeChangedtoAplhanumeric()) + || fepMan->IsPhoneNumberEditor() ) + && fepMan->FnKeyState() != CAknFepFnKeyManager::EFnKeyNone) + { + if( EStdKeyLeftFunc == aKey ) + { + TCallBack timerExpire(TimerExpire, this); + fepMan->MultitapThroughSCTCharL(timerExpire); + return ETrue; + } + else + { + ChrKeyTimerExpired(); + } + + if(!fepMan->IsPhoneNumberEditor()) + { + TChar validchr; + if(!CheckHasValidNumerKeyMappedL(aKey,languageChanged)) + ptiengine->SetCase((TPtiTextCase)EPtiCaseLower); + else + return ETrue; + } + } + if(!iData) + { + // this should be called after case change + // so that the shift state is taken care of + #ifdef __HALF_QWERTY_PREVIEW_PANE + fepMan->PreparePreviewPaneL((TPtiKey)aKey); + #endif //__HALF_QWERTY_PREVIEW_PANE + } + + // Over ride the case changes, force to fnLower for + // long key press. + if( aLength == ELongKeyPress && aKey == EStdKeyFullStop) + { + iOwner->PtiEngine()->SetCase( EPtiCaseFnLower ); + } + + // Get keymapping from PtiEngine. + text.Set(ptiengine->AppendKeyPress((TPtiKey)aKey)); + + // send the text to be highlighted here + #ifdef __HALF_QWERTY_PREVIEW_PANE + fepMan->ShowPaneL(); + #endif //__HALF_QWERTY_PREVIEW_PANE + } + + if (text.Length() > 0) + { + TBuf<1> chr; + chr.Append(text[0]); + if( fepMan->IsOnlyNumericPermitted() + && !iOwner->FepMan()->IsValidCharInNumericEditorL(text[0]) ) + { + ptiengine->CancelTimerActivity(); + +#ifdef __REVERSE_FN_KEY_SUPPORTED + if(languageChanged) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + } +#endif + if(fepMan->IsHybridAplhaEditor() && !fepMan->IsHybridAlphaModeChangedtoAplhanumeric()) + ptiengine->SetCase(CurCase); + return ETrue; + } + if(fepMan->IsHybridAplhaEditor() && !fepMan->IsHybridAlphaModeChangedtoAplhanumeric() + && fepMan->FnKeyState() != CAknFepFnKeyManager::EFnKeyNone) + { + if(!iOwner->FepMan()->IsValidCharInNumericEditorL(text[0]) ) + { + ptiengine->CancelTimerActivity(); + +#ifdef __REVERSE_FN_KEY_SUPPORTED + if(languageChanged) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + } +#endif + } + } + fepMan->NewCharacterL(chr); + + if ( aKey == EStdKeyEnter) + { + fepMan->CommitInlineEditL(); + ptiengine->ClearCurrentWord(); + iData = 0; + } + else + { + iData = aKey; + fepMan->SetFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); + } + + } + if((text.Length() > 0) || (IsKeymapped(aKey))) + { + ret = ETrue; + } + TBuf<32> mappedCharacters; + iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey, mappedCharacters, iOwner->PtiEngine()->Case()); + if( mappedCharacters.Length() < 2 ) + { + ptiengine->CancelTimerActivity(); + if( aLength == EShortKeyPress ) + { + SetShortKeyPressText(text); + } + } + if(fepMan->IsHybridAplhaEditor() && !fepMan->IsHybridAlphaModeChangedtoAplhanumeric()) + ptiengine->SetCase(CurCase); + } + +// else +// //Long key press +// { +// if (aKey == EStdKeyEnter) +// { + // PtiEngine does not have mapping for the enter key. +// const TText KAknFEPLineFeedSymbol = 0x21B2; +// TBuf<1> lineFeed; +// lineFeed.Zero(); +// lineFeed.Append(KAknFEPLineFeedSymbol); +// text.Set(lineFeed); +// } +// else +// { +// TBool isCharacter = ETrue; +// if (!iData) +// { +// isCharacter = IsCharacterKey(aKey); +// } +// //HandleCaseChange(aKey, isCharacter); +// //Forcing Fn mode for long key press +// +// /* +// //Start of Option-1 +// ptiengine->SetCase(EPtiCaseFnLower); +// text.Set(ptiengine->AppendKeyPress((TPtiKey)aKey)); +// // End of Option-1 +// */ +// +// //Start of Option-2 +// //To do: Space key lower case being mapped and removing +// //hard coding of space in UI State. +// TBuf<5> allFnMappedCharacters; +// ptiengine->MappingDataForKey((TPtiKey)aKey, allFnMappedCharacters, EPtiCaseFnLower); +// text.Set(allFnMappedCharacters); +// // End of Option-2 +// +// } +// #ifdef __HALF_QWERTY_PREVIEW_PANE +// // in any case hide the preview pane +// fepMan->HidePane(); +// #endif //__HALF_QWERTY_PREVIEW_PANE +// +// if (text.Length() > 0) +// { +// TBuf<1> chr; +// chr.Append(text[0]); +// fepMan->NewCharacterL(chr); +// fepMan->CommitInlineEditL(); +// ptiengine->ClearCurrentWord(); +// iData = 0; +// /* +// if (aKey == EStdKeyEnter) +// { +// fepMan->CommitInlineEditL(); +// ptiengine->ClearCurrentWord(); +// iLastKey = 0; +// } +// else +// { +// iLastKey = aKey; +// fepMan->SetFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); +// } +// */ +// +// ret = ETrue; +// } +// else +// { +// // text.Length is zero. Handle long key. +// if( aKey == EStdKeyFullStop ) +// { +// ptiengine->CancelTimerActivity(); +// } +// } +// } + if( aKey!=EStdKeyBackspace && fnKeyState != CAknFepFnKeyManager::EFnKeyNone) + return ETrue; + + if(ptiengine->IsValidKey((TPtiKey)aKey)) + ret = ETrue; + +#ifdef __REVERSE_FN_KEY_SUPPORTED + if(languageChanged) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + } +#endif + + return ret; + } + +// Functions from MPtiObserver interface +void TAknFepInputStateHalfQwerty::KeyTimerExpired() + { + if (iData) + { + MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); + TRAP_IGNORE(fepMan->CommitInlineEditL()) + + CPtiEngine* ptiengine = iOwner->PtiEngine(); + ptiengine->ClearCurrentWord(); + #ifdef __HALF_QWERTY_PREVIEW_PANE + fepMan->HidePane(); + #endif //__HALF_QWERTY_PREVIEW_PANE + iData = 0; + fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction); + CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState(); + if( !fepMan->IsFlagSet( CAknFepManager::EFlagLongShiftKeyPress ) ) + { + if(fnKeyState == CAknFepFnKeyManager::EFnKeyNext) + fepMan->SetFnKeyState(CAknFepFnKeyManager::EFnKeyNone); + } + } + } + +void TAknFepInputStateHalfQwerty::HandleCaseChange(TInt /*aKey*/, TBool aIsCharacter) + { + // Punctuation key multitapping should not change case + if( iData ) + return; + + TPtiTextCase caseMode = EPtiCaseLower; + + if (aIsCharacter) + { + if( iData == 0 || !( iOwner->FepMan()->IsOnlyNumericPermitted() ) ) + { + // use the Edwin case only when timer expires + // To handle cases like insert fn character empty editor + // followed by alpa character + switch(iOwner->CaseMan()->CurrentCase()) + { + case EAknEditorLowerCase: + caseMode = EPtiCaseLower; + break; + case EAknEditorTextCase: + case EAknEditorUpperCase: + caseMode = EPtiCaseUpper; + default: + break; + } + } + else + { + // user is still multitapping, use the existing PtiEngine case + caseMode = iOwner->PtiEngine()->Case(); + } + } + + TPtiTextCase shiftedCase = caseMode; + + TPtiTextCase curCase = iOwner->PtiEngine()->Case(); + if(curCase == EPtiCaseFnUpper || curCase == EPtiCaseFnLower) + return; + + if ( iOwner->FepMan()->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) && + ( !aIsCharacter|| iOwner->CaseMan()->IsAbleChangeCase() ) ) + { + // Case mode is changed to opposite because shift key is/was pressed and + // in case of character key case changes are allowed. In case of + // number or special key, shift mode is used always when + // shift key is pressed + + + // clear this flag so that the shift key mode gets reset + // when shift key up event is received + + iOwner->FepMan()->ClearFlag(CAknFepManager::EFlagNoActionDuringShiftKeyPress); + + // Do not toggle case while multitapping + if( !iData ) + { + switch ( caseMode ) + { + case EPtiCaseUpper: + shiftedCase = EPtiCaseLower; + break; + case EPtiCaseLower: + shiftedCase = EPtiCaseUpper; + break; + default: + break; + } + } + } + + if ( iOwner->FepMan()->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) ) + { + // Chr key is pressed down. Chr mode is used. + if (shiftedCase == EPtiCaseLower) + { + shiftedCase = EPtiCaseChrLower; + } + else if (shiftedCase == EPtiCaseUpper) + { + shiftedCase = EPtiCaseChrUpper; + } + } + iOwner->FepMan()->ClearFlag( CAknFepManager::EFlagNoActionDuringChrKeyPress ); + iOwner->PtiEngine()->SetCase(shiftedCase); + + } + +TBool TAknFepInputStateHalfQwerty::IsCharacterKey(const TInt aKey) + { + CPtiEngine* ptiengine = iOwner->PtiEngine(); + // Max length doesn't matter because we'll need only the first character. + TBuf lowerdata; + + ptiengine->MappingDataForKey((TPtiKey)aKey, lowerdata, EPtiCaseLower); + if (lowerdata.Length() > 0) + { + TChar lower = lowerdata[0]; + TUint upper = lower.GetUpperCase(); + + if ( TUint(lower) != upper ) + { + return ETrue; + } + } + + return EFalse; + } +TBool TAknFepInputStateHalfQwerty::TryGetValidCharForKey(const TInt& aKey, TChar& aChar) + { + if( ! TryGetValidCharForKeyAndCase( aKey, aChar, EPtiCaseFnLower) ) + { + if(! TryGetValidCharForKeyAndCase( aKey, aChar, EPtiCaseUpper)) + { + if(! TryGetValidCharForKeyAndCase( aKey, aChar, EPtiCaseLower)) + { + return EFalse; + } + } + } + return ETrue; + } +TBool TAknFepInputStateHalfQwerty::TryGetValidCharForKeyAndCase(const TInt& aKey, TChar& aChar, TPtiTextCase aCase) + { + TBuf mappedCharacters; + + iOwner->PtiEngine()->MappingDataForKey((TPtiKey)aKey, mappedCharacters, aCase); + TRAP_IGNORE( + for (TInt i = 0; i < mappedCharacters.Length(); i++ ) + { + if( iOwner->FepMan()->IsValidCharInNumericEditorL( mappedCharacters[i] ) ) + { + aChar = mappedCharacters[i]; + return ETrue; + } + }); + return EFalse; + } +TInt TAknFepInputStateHalfQwerty::TimerExpire(TAny* aPtr) + { + reinterpret_cast(aPtr)->ChrKeyTimerExpired(); + return 1; + } +TInt TAknFepInputStateHalfQwerty::ChrKeyTimerExpired() + { + if(iOwner->FepMan()->IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction)) + { + // this function is only called for number only editors + + TRAP_IGNORE(iOwner->FepMan()->CommitInlineEditL()); + } + return 1; + } + + +TBool TAknFepInputStateHalfQwerty::IsKeymapped(TInt aKey) + { + TBuf<20> mapData; + TBool ret = EFalse; + CPtiEngine* ptiengine = iOwner->PtiEngine(); + for(TInt count=0;countMappingDataForKey(static_cast(aKey), mapData, static_cast (count)); + if(mapData.Length()) + { + ret = ETrue; + break; + } + } + return ret; + } + +TBool TAknFepInputStateHalfQwerty::CheckHasValidNumerKeyMappedL(TInt aKey, TBool &aLangChanged) + { + CPtiEngine* ptiengine = iOwner->PtiEngine(); + TInt origLanguage = ptiengine->CurrentLanguage()->LanguageCode(); + TPtiEngineInputMode origInputMode = ptiengine->InputMode(); + MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); + + //TBool languageChanged = EFalse; + + TChar chr; + + if( ! TryGetValidCharForKey(aKey, chr) ) + { + // If the key in not valid char in the current input language in Fn reverse mode, + // then we will check if against English language. And if its valid then we will + // insert the char based out of key for English input language and revert back + // the change in input language at the end. + + if(ptiengine->CurrentLanguage()->LanguageCode() == ELangEnglish) + { + if(fepMan->IsOnlyNumericPermitted()) + return ETrue; + else + return EFalse; + } + + aLangChanged = ETrue; + ptiengine->ActivateLanguageL(ELangEnglish); + ptiengine->SetInputMode(EPtiEngineHalfQwerty); + + if( !fepMan->IsValidCharForNumericInFnReverseL(aKey, iOwner->PtiEngine()->Case()) ) + { + if( ! TryGetValidCharForKey(aKey, chr) ) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + if(fepMan->IsHybridAplhaEditor() && !fepMan->IsHybridAlphaModeChangedtoAplhanumeric()) + return EFalse; + else + return ETrue; + } + else + { + if(aLangChanged) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + } + + TBuf<1> buf; + buf.Append(chr); + fepMan->NewCharacterL(buf); + fepMan->CommitInlineEditL(); + ptiengine->ClearCurrentWord(); + iData = 0; + ptiengine->CancelTimerActivity(); + return ETrue; + } + } + } + else + { + if(aLangChanged) + { + ptiengine->ActivateLanguageL(origLanguage); + ptiengine->SetInputMode(origInputMode ); + } + + TBuf<1> buf; + buf.Append(chr); + fepMan->NewCharacterL(buf); + fepMan->CommitInlineEditL(); + ptiengine->ClearCurrentWord(); + iData = 0; + ptiengine->CancelTimerActivity(); + return ETrue; + } + + + return EFalse; + } +// End of file