--- /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 <PtiEngine.h>
+#include <PtiDefs.h>
+#include <PtiKeyMappings.h>
+#include <centralrepository.h>
+#include <AknFepInternalCRKeys.h>
+
+
+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<KMaxName> 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<KMaxName> 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<TAknFepInputStateHalfQwerty*>(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;count<EPtiCaseMax;count++)
+ {
+ ptiengine->MappingDataForKey(static_cast<TPtiKey>(aKey), mapData, static_cast<TPtiTextCase> (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