/*
* 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 TAknFepUiInputStateEntryHalfQwertyWesternPredictive methods.
*
*/
#include "AknFepUiInputStateEntryHalfQwertyWesternPredictive.h"
#include "AknFepUIManagerStateInterface.h" //MAknFepUIManagerStateInterface
#include "AknFepManagerUIInterface.h" //MAknFepManagerUIInterface
#include "AknFepUiManagerWestern.h"
#include "AknFepManager.h"
#include "AknFepPanic.h"
#include "AknFepCaseManager.h"
#include <PtiEngine.h> //CPtiEngine
#include <PtiDefs.h> //keys
#include <PtiCompositionDataIF.h> //MPtiEngineCompositionDataInterface
#include <featmgr.h> //FeatureManager
#include <e32keys.h>
#include <AknFep.rsg>
#include <PtiUserDicEntry.h>
// TODO: Remove this include
#include <AvkonInternalCRKeys.h>
#include <AknUtils.h>
static const TInt KKeyMappingsLength = 63;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
TAknFepUiInputStateEntryHalfQwertyWesternPredictive::TAknFepUiInputStateEntryHalfQwertyWesternPredictive(MAknFepUIManagerStateInterface* aOwner)
:TAknFepInputStateBase(aOwner)
{
//this class insists on the existence of a case manager
__ASSERT_DEBUG(iOwner->CaseMan(), AknFepPanic(EAknFepPanicNoCaseManager));
iState = EEntry;
CPtiEngine* ptiengine = iOwner->PtiEngine();
ptiengine->SetInputMode( EPtiEngineHalfQwertyPredictive );
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
TPtiTextCase caseMode = ptiengine->Case();
ptiengine->SetCase(caseMode);
TBool isUnlimitedEditor = EFalse;
ptiengine->SetMaxLengthForAutoCompletedCandidates(fepMan->EditorFreeSpaceForAutoWordCompletion(isUnlimitedEditor ));
if(fepMan->IsAutoCompleteOn())
{
TRAP_IGNORE( ptiengine->HandleCommandL( EPtiCommandEnableAutoCompletion ) );
}
else
{
TRAP_IGNORE( ptiengine->HandleCommandL( EPtiCommandDisableAutoCompletion ) );
}
// TPtiErrorCorrectionLevel correctionLevel = (TPtiErrorCorrectionLevel)fepMan->AdvancedPredictiveTypingCorrectionLevel();
// TRAP_IGNORE( ptiengine->HandleCommandL( EPtiCommandSetCorrectionLevel, &correctionLevel ) );
TPtiKeyboardType keyboard = fepMan->KeyboardLayout();
ptiengine->SetKeyboardType(keyboard);
// TBool isNumberCandidateShown = fepMan->IsAdvancedPredictiveNumberCandidateShown();
// TRAP_IGNORE( ptiengine->HandleCommandL( EPtiCommandSetNumberCandidateStatus, &isNumberCandidateShown ) );
//
// TBool primaryCandidateState = fepMan->AdvancedPredictivePrimaryCandidate();
// TRAP_IGNORE( ptiengine->HandleCommandL( EPtiCommandSetProactiveCorrection, &primaryCandidateState ) );
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
TBool TAknFepUiInputStateEntryHalfQwertyWesternPredictive::HandleKeyL(TInt aKey, TKeyPressLength aLength)
{
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CPtiEngine* ptiengine = iOwner->PtiEngine();
CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState();
if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
ptiengine->SetCase(EPtiCaseFnLower);
}
// Handle the Chr cycling
if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) && aKey !=EKeyBackspace)
{
// if the key has no accented characters mapped to it, then just block the event
TBuf<KKeyMappingsLength> keyMappings;
ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseChrLower );
if( keyMappings.Length() == 0 )
{
return EFalse;
}
// if there is a no matches indicator remove it
if ( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) && fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
{
fepMan->TryRemoveNoMatchesIndicatorL();
fepMan->UpdateCbaL(NULL);
}
// if there is an autocompletion part rip it off
fepMan->RemoveSuggestedAdvanceCompletionL();
// now if the editor has no free space just return
if ( !fepMan->EditorHasFreeSpace() )
{
return EFalse;
}
// if we are in inline editing, break the word
if( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) )
{
TPtrC selectedWord = ptiengine->CurrentWord();
if( ptiengine->CurrentWord() != KNullDesC)
{
fepMan->UpdateInlineEditL( selectedWord, selectedWord.Length() ); //selection.iAnchorPosition
ptiengine->CommitCurrentWord();
}
fepMan->TryCloseUiL();
}
if ( iData && (iData != aKey) )
{
// Chr key is still pressed down but character key was changed from previous one
// to new one. The previous character is committed and PtiEngine starts
// processing new key.
ptiengine->CancelTimerActivity();
}
fepMan->SetFlag( CAknFepManager::EFlagInsideMultitapInlineEditingTransaction );
}
TBool response = EFalse;
// Handle dead keys with space or backspace. These keys are not mapped in PtiEngine, so they cannot
// be handled there.
/* if ( ptiengine->HandleCommandL(EPtiCommandDeadKeyWaiting) == 1 )
{
if ( aKey == EStdKeyBackspace )
{
// Pending dead key is removed with backspace. No other characters are removed.
ptiengine->HandleCommandL(EPtiCommandGetAndClearDeadKeyRootChar);
response = ETrue;
}
else if ( aKey == EStdKeySpace )
{
// Dead key followed by space enters the dead key root character
TText deadRoot = ptiengine->HandleCommandL(EPtiCommandGetAndClearDeadKeyRootChar);
ptiengine->HandleCommandL( EPtiCommandAppendCharacter, &deadRoot );
TPtrC newText = ptiengine->CurrentWord();
fepMan->UpdateInlineEditL( newText, newText.Length() );
iOwner->CaseMan()->UpdateCase(ENullNaviEvent);
response = ETrue;
}
}
*/
if (!response) // key not yet handled
{
switch (aKey)
{
case EStdKeySpace:
if( fepMan->FnKeyState()
== CAknFepFnKeyManager::EFnKeyNone )
{
response = HandleWordBreakingKeysL(aKey);
}
else
{
response = HandleQwertyKeysL( aKey, aLength);
}
break;
case EStdKeyFullStop:
if( aLength == ELongKeyPress )
{
// first commit the word if in inline editing
if( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction))
{
if (fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
{
fepMan->TryRemoveNoMatchesIndicatorL();
fepMan->UpdateCbaL(NULL);
}
TPtrC selectedWord = ptiengine->CurrentWord();
if( ptiengine->CurrentWord() != KNullDesC)
{
fepMan->UpdateInlineEditL( selectedWord, selectedWord.Length() ); //selection.iAnchorPosition
ptiengine->CommitCurrentWord();
}
fepMan->TryCloseUiL();
}
response = EFalse;
}
else
{
HandleShiftState(aKey);
response = HandleQwertyKeysL( aKey, aLength);
}
break;
case EStdKeyEnter:
case EStdKeyTab:
case EStdKeyLeftArrow:
case EStdKeyRightArrow:
case EStdKeyUpArrow:
case EStdKeyDownArrow:
response = HandleWordBreakingKeysL(aKey);
break;
// Long press of shift key start copy event.
// Its should handle by framework.
case EStdKeyF21:
case EKeyF21:
// Soft key handle by framework
// Selection key handle by AknFepManager.
case EStdKeyDevice0: // iCode:EKeyCBA1
case EStdKeyDevice1: // iCode:EKeyCBA2
case EStdKeyDevice3: // iCode:EKeyOK
case EKeyCBA1:
case EKeyCBA2:
case EKeyOK:
response = EFalse;
break;
case EKeyUpArrow:
if ( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) )
{
// Select the exact match with the up arrow and lock it.
// Another alternative could be to call function DoPreviousMatchL() from here
TPtrC exactWord = ptiengine->FirstCandidate();
ptiengine->HandleCommandL( EPtiCommandLockCurrentCandidate, NULL );
fepMan->UpdateInlineEditL(exactWord, exactWord.Length());
response = ETrue;
break;
}
// fall through
case EKeyDownArrow:
case EKeyLeftArrow:
case EKeyRightArrow:
case EKeyBackspace:
{
response = HandleNaviKeysL(aKey, aLength);
}
break;
case EStdKeyLeftShift:
case EStdKeyRightShift:
case EStdKeyLeftFunc:
{
if( EPtiCaseFnLower == fepMan->PtiEngine()->Case() )
{
if ( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) )
{
fepMan->TryRemoveNoMatchesIndicatorL();
}
fepMan->UpdateCbaL(NULL);
/*if (fepMan->IsFlagSet(CAknFepManager::EFlagCompoundWord))
{
if (fepMan->IsCursorAtEndOfWord())
{
fepMan->AddCompoundWordToUdbL();
}
fepMan->ClearFlag(CAknFepManager::EFlagCompoundWord);
}
*/
fepMan->RemoveSuggestedAdvanceCompletionL();
ptiengine->CommitCurrentWord();
fepMan->CommitInlineEditL();
fepMan->TryCloseUiL();
response = EFalse;
}
}
break;
default:
HandleShiftState(aKey);
response = HandleQwertyKeysL(aKey, aLength);
#ifdef __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__
if ( aLength == ELongKeyPress )
{
// Expire multitap timer after long press.
ptiengine->CancelTimerActivity();
}
#endif // __ITI_LONGPRESS_NUM_SHIFT_COPYPASTE__
break;
}
}
if ( aKey == EStdKeyEnter)
{
iData = 0;
return 0;
}
if (!iOwner->PtiEngine()->IsValidKey((TPtiKey)aKey))
{
iData = 0;
fepMan->ClearFlag(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction);
fepMan->PtiEngine()->CancelTimerActivity();
return response;
}
iData = aKey; // store the pressed key for future reference
return response;
}
//////////////////////////////////////////////////////////////////////////////////
//
void TAknFepUiInputStateEntryHalfQwertyWesternPredictive::HandleShiftState( TInt aKey )
{
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CPtiEngine* ptiengine = iOwner->PtiEngine();
CAknFepCaseManager* caseMan = iOwner->CaseMan();
CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState();
TPtiTextCase shiftedCase;
if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
shiftedCase = EPtiCaseFnLower;
}
else
{
shiftedCase= EPtiCaseLower;
}
// Find out if the key is alphabetic
TBuf<KKeyMappingsLength> keyMappings;
ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseUpper );
TBool isAlpha = ( keyMappings.Length() && TChar(keyMappings[0]).IsAlpha() );
if (isAlpha && (fnKeyState == CAknFepFnKeyManager::EFnKeyNone))
{
switch ( caseMan->CurrentCase() )
{
case EAknEditorTextCase:
{
// Alphabetic characters are always capitalized in "Abc" mode
// unless the shift is pressed
if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) )
{
shiftedCase = EPtiCaseUpper;
}
}
break;
case EAknEditorLowerCase:
{
// Pressing shift enters uppercae letters in the "abc" mode
if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) )
{
shiftedCase = EPtiCaseUpper;
}
}
break;
case EAknEditorUpperCase:
{
// In the "ABC" mode (capslock mode) the letters are uppercased
// unless the shift is pressed
if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) )
{
shiftedCase = EPtiCaseUpper;
}
}
break;
default:
break;
}
}
else
{
// non-alphabetic keys are shifted if and only if shift is pressed, no matter what is the input state
if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) && (fnKeyState == CAknFepFnKeyManager::EFnKeyNone))
{
shiftedCase = EPtiCaseUpper;
}
else if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) && (fnKeyState != CAknFepFnKeyManager::EFnKeyNone))
{
shiftedCase = EPtiCaseFnUpper;
}
}
// Handle the Chr key state
if ( fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) )
{
// Chr key is pressed down. Chr mode is used.
if (shiftedCase == EPtiCaseLower)
{
shiftedCase = EPtiCaseChrLower;
}
else if (shiftedCase == EPtiCaseUpper)
{
shiftedCase = EPtiCaseChrUpper;
}
}
ptiengine->SetCase(shiftedCase);
fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringShiftKeyPress);
}
//////////////////////////////////////////////////////////////////////////////////
//
TBool TAknFepUiInputStateEntryHalfQwertyWesternPredictive::HandleWordBreakingKeysL(TInt aKey)
{
TBool retVal = EFalse; // in most cases we let also the upper levels handle these key events
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CPtiEngine* ptiengine = iOwner->PtiEngine();
// Up and down arrows break the inline word input only when shift or chr is held down
if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) &&
!fepMan->IsFlagSet(CAknFepManager::EFlagQwertyShiftMode) &&
( aKey==EStdKeyUpArrow || aKey==EStdKeyDownArrow ) )
{
return retVal;
}
if ( fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction) )
{
TBool rightToLeftLang = fepMan->IsRightToLeftLanguage();
TInt tailLength = 0;
ptiengine->HandleCommandL( EPtiCommandGetAutoCompletionTailLength, &tailLength );
switch (aKey)
{
case EStdKeyLeftArrow:
case EStdKeyRightArrow:
// In case the inline editing is ongoing and there is a word completion
// currently shown, the first backwards tap will remove the suggested
// completion.
if(tailLength > 0)
{
if ((rightToLeftLang && aKey == EStdKeyLeftArrow)
|| (! rightToLeftLang && aKey == EStdKeyRightArrow ))
{
ptiengine->HandleCommandL( EPtiCommandLockCurrentCandidate);
TPtrC selectedWord = ptiengine->CurrentWord();
fepMan->UpdateInlineEditL( selectedWord, selectedWord.Length() ); //selection.iAnchorPosition
// To fix Suggested word is not committed when Arrow right key is pressed.
ptiengine->CommitCurrentWord();
fepMan->TryCloseUiL();
// Asyncronous case update after the editor has handled the key
fepMan->SimulateKeyEventL(EKeyF19);
retVal = ETrue;
}
else if((rightToLeftLang && aKey == EStdKeyRightArrow)
|| (! rightToLeftLang && aKey == EStdKeyLeftArrow ))
{
fepMan->RemoveSuggestedAdvanceCompletionL();
retVal = ETrue;
}
}
else
{
ptiengine->CommitCurrentWord();
retVal = EFalse;
}
break;
case EStdKeyUpArrow:
case EStdKeyDownArrow:
case EStdKeyEnter:
case EStdKeySpace:
case EStdKeyTab:
{
//retVal = ETrue;
if ( ( aKey == EStdKeySpace || aKey == EStdKeyEnter ||aKey == EStdKeyTab)
&& fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)
&& (fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)) )
{
fepMan->TryRemoveNoMatchesIndicatorL();
fepMan->UpdateCbaL(NULL);
}
TBool wasInlineEditing = EFalse;
wasInlineEditing = fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction);
ptiengine->CommitCurrentWord();
fepMan->CommitInlineEditL();
/* Temporary Fix */
//EFlagInsideInlineEditingTransaction flag check is not required
//but just to make sure.
if(aKey == EStdKeySpace && wasInlineEditing)
{
_LIT(KSpace," ");
fepMan->StartInlineEditL();
fepMan->UpdateInlineEditL(KSpace,0);
fepMan->CommitInlineEditL();
retVal = ETrue;
}
/* Temporary Fix */
fepMan->TryCloseUiL();
// Asyncronous case update after the editor has handled the key
fepMan->SimulateKeyEventL(EKeyF19);
}
break;
default:
__ASSERT_DEBUG( EFalse, AknFepPanic(EAknFepPanicNotSupportKey) );
}
}
else
{
iOwner->ChangeState( EInitial );
}
return retVal;
}
/////////////////////////////////////////////////////////////////////////////////
//
TBool TAknFepUiInputStateEntryHalfQwertyWesternPredictive::HandleQwertyKeysL(TInt aKey, TKeyPressLength aLength)
{
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CPtiEngine* ptiengine = iOwner->PtiEngine();
TBool retVal = EFalse;
CAknFepCaseManager* caseMan = iOwner->CaseMan();
CAknFepFnKeyManager::TFnKeyState fnKeyState = fepMan->FnKeyState();
// Key is consumed if the PtiEngine maps it to some character
TBuf<KKeyMappingsLength> keyMappings;
if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseFnLower);
}
else
{
ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseLower);
}
//ptiengine->MappingDataForKey( (TPtiKey)aKey, keyMappings, EPtiCaseLower);
//ITI : Pti Engine can be asked to give the proper data for the keys under Fn Key.
TBool keyIsMapped = ( keyMappings.Length() > 0 );
// The dead key handling inside the PtiDefaultCore assumes that no other key mapping queries
// have been made between handling the dead key and the next one (these queries change the
// internal state of the key mapping object). For this reason, we must return the key mappings
// to their previous state. This is quite dirty hack, but so is the dead key handling code which
// forces us to do this.
if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
ptiengine->MappingDataForKey( (TPtiKey)iData, keyMappings, EPtiCaseFnLower);
}
else
{
ptiengine->MappingDataForKey( (TPtiKey)iData, keyMappings, EPtiCaseLower);
}
if (fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches) && fnKeyState == CAknFepFnKeyManager::EFnKeyNone )
{
//no matches, so just play tone
fepMan->PlaySound(EAvkonSIDConfirmationTone);
return keyIsMapped;
}
if ( keyIsMapped )
{
if( fnKeyState != CAknFepFnKeyManager::EFnKeyNone )
{
//closing the UI will commit the current word and move to intial state
// break the word
if (fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
{
fepMan->TryRemoveNoMatchesIndicatorL();
}
fepMan->RemoveSuggestedAdvanceCompletionL();
TPtrC selectedWord = ptiengine->CurrentWord();
if( ptiengine->CurrentWord() != KNullDesC)
{
fepMan->UpdateInlineEditL( selectedWord, selectedWord.Length() ); //selection.iAnchorPosition
ptiengine->CommitCurrentWord();
}
fepMan->TryCloseUiL();
ptiengine->SetCase(EPtiCaseFnLower);
}
if ( !(fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) )
{ // 'new' inline edit
ptiengine->ClearCurrentWord();
if (caseMan->CurrentCase() == EAknEditorTextCase)
{
ptiengine->MarkAutoCapitalized();
}
fepMan->StartInlineEditL();
}
TPtrC newText;
if( aKey == EStdKeyFullStop )
{
TInt tailLength = 0;
ptiengine->HandleCommandL( EPtiCommandLockCurrentCandidate, &tailLength );
/* if( fepMan->IsAutoCompleteOn() )
{
TInt tailLength = 0;
ptiengine->HandleCommandL( EPtiCommandGetAutoCompletionTailLength, &tailLength );
if( tailLength > 0)
{
// if autoword part is visible update the input sequence
newText.Set(ptiengine->CurrentWord() );
ptiengine->ClearCurrentWord();
ptiengine->SetCurrentWord(newText);
}
}*/
}
newText.Set(ptiengine->AppendKeyPress((TPtiKey)aKey));
if ( aLength == EShortKeyPress )
{
SetShortKeyPressText(newText);
}
if (ptiengine->NumberOfCandidates() > 0 )
{
// more good words coming in from predictive text engine so carry on
if(newText.Length() == 1)
{
TDigitType digittype = fepMan->LocalDigit();
TChar chchar(newText[0]);
if(!chchar.IsDigit() || (chchar.IsDigit() && !digittype))
{
fepMan->UpdateInlineEditL(newText, newText.Length());
}
else
{
TBuf<1> tempbuf;
tempbuf.Append(newText[0]);
ConvertDigitToDigittype(digittype,tempbuf);
fepMan->UpdateInlineEditL(tempbuf, tempbuf.Length());
}
if(fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
ptiengine->CommitCurrentWord();
fepMan->CommitInlineEditL();
}
}
else
{
fepMan->UpdateInlineEditL(newText, newText.Length());
}
}
else
{
// engine has run out of matches
// we are not in the functionized state
fepMan->SetFlag(CAknFepManager::EFlagRemoveMatchesMenuItem);
fepMan->SetFlag(CAknFepManager::EFlagNoMatches);
fepMan->UpdateCbaL(R_AKNFEP_SOFTKEYS_SPELL_EMPTY);
if(newText.Length() == 1)
{
TDigitType digittype = fepMan->LocalDigit();
TChar chchar(newText[0]);
if(!chchar.IsDigit() || (chchar.IsDigit() && !digittype))
{
fepMan->UpdateInlineEditL(newText, newText.Length());
}
else
{
TBuf<1> tempbuf;
tempbuf.Append(newText[0]);
ConvertDigitToDigittype(digittype,tempbuf);
fepMan->UpdateInlineEditL(tempbuf, tempbuf.Length());
}
}
else
{
// Remove the autocompletion tail if present
if (fepMan->IsAutoCompleteOn())
{
TInt tailLength = 0;
ptiengine->HandleCommandL( EPtiCommandGetAutoCompletionTailLength, &tailLength );
if(tailLength > 0)
{
// To remove the autocompletion part, the below function is used.
// DeleteKeyPress was used earlier. This is removed to fix the bug :
// enter characters to show autocompletion part. Now press a
// character so that the no matches character is shown. Now press
// backspace key, last character is not deleted.
fepMan->RemoveSuggestedAdvanceCompletionL();
fepMan->PlaySound(EAvkonSIDConfirmationTone);
return ETrue;
}
}
fepMan->UpdateInlineEditL(newText, newText.Length());
}
fepMan->PlaySound(EAvkonSIDConfirmationTone);
}
// Normally we update the case after key press. However, if Chr key is held down, the case update
// must not happen until when the Chr is released or the timer expires (in both of these cases
// the function KeyTimerExpired() will get callled).
if ( !fepMan->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed) )
{
iOwner->CaseMan()->UpdateCase(ENullNaviEvent);
}
else
{
fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringChrKeyPress);
}
retVal = ETrue;
}
else
{
retVal = EFalse;
}
if(ptiengine->IsValidKey((TPtiKey)aKey))
retVal = ETrue;
if( aKey!=EStdKeyBackspace && fnKeyState != CAknFepFnKeyManager::EFnKeyNone)
{
retVal = ETrue;
}
if( !fepMan->IsFlagSet( CAknFepManager::EFlagLongShiftKeyPress ) &&
fnKeyState == CAknFepFnKeyManager::EFnKeyNext )
{
fepMan->SetFnKeyState(CAknFepFnKeyManager::EFnKeyNone);
}
return retVal;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
TBool TAknFepUiInputStateEntryHalfQwertyWesternPredictive::HandleNaviKeysL(TInt aKey, TKeyPressLength /*aLength*/)
{
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CPtiEngine* ptiengine = iOwner->PtiEngine();
if (!(fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)))
{
TBuf<CAknFepManager::EMaximumFepWordLength> textToUncommit;
TBool comsumeKey;
if (!(fepMan->TryGetTextToUncommitL(textToUncommit, aKey, comsumeKey)))
{
// If T9 word length > 32, the navi key is consumed without action.
// Maybe should navigate inside word.
return comsumeKey;
}
ptiengine->ClearCurrentWord();
ptiengine->SetCurrentWord(textToUncommit); // this set the input sequence of PtiEngine
fepMan->StartInlineEditL(fepMan->UncommittedText(), textToUncommit,
textToUncommit.Length(), EFalse);
}
if (aKey == EKeyBackspace)
{
if (fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))
{
fepMan->TryRemoveNoMatchesIndicatorL();
fepMan->UpdateCbaL(NULL);
ptiengine->HandleCommandL(EPtiCommandSetFlagToUpdateCandidates);
// Need to return as DeleteKeyPress should not be passed to ptiengine.
// This is because ptiengine does not maintain the input sequence
// if the key press does not increase the word length. So when no matches
// character is (?) is deleted, no need to pass to ptiengine. This is to done
// to solve the bug :enter characters till the no matches character is shown. Now press
// backspace, last character is not deleted.
return ETrue;
}
TPtrC newText = ptiengine->DeleteKeyPress();
// remove autocompletion part if any
// this has to be done before updateinlineedit to avoid flickering
TInt tailLength = 0;
ptiengine->HandleCommandL( EPtiCommandGetAutoCompletionTailLength,
&tailLength );
if(tailLength > 0)
{
fepMan->RemoveSuggestedAdvanceCompletionL();
newText.Set(ptiengine->CurrentWord());
}
fepMan->UpdateInlineEditL(newText, newText.Length());
fepMan->ClearFlag(CAknFepManager::EFlagRemoveMatchesMenuItem);
if (ptiengine->NumberOfCandidates() <= 1)
{
fepMan->SetFlag(CAknFepManager::EFlagRemoveMatchesMenuItem);
}
iOwner->CaseMan()->UpdateCase(EBackspaceEvent);
fepMan->ClearFlag(CAknFepManager::EFlagNoActionDuringChrKeyPress);
fepMan->CloseUiIfWordDeletedL();
}
return ETrue;
}
/////////////////////////////////////////////////////////////////////////////
//
void TAknFepUiInputStateEntryHalfQwertyWesternPredictive::LastWordInSelectionList()
{
}
//////////////////////////////////////////////////////////////////////////////
//
void TAknFepUiInputStateEntryHalfQwertyWesternPredictive::FirstWordInSelectionList()
{
}
/////////////////////////////////////////////////////////////////
//
void TAknFepUiInputStateEntryHalfQwertyWesternPredictive::KeyTimerExpired()
{
if (iData)
{
MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
CAknFepCaseManager* caseMan = iOwner->CaseMan();
caseMan->UpdateCase(ENullNaviEvent);
fepMan->ClearFlag( CAknFepManager::EFlagInsideMultitapInlineEditingTransaction );
iData = 0;
}
}
void TAknFepUiInputStateEntryHalfQwertyWesternPredictive::ConvertDigitToDigittype(TDigitType& digittype,TDes& aConvertedNumeral)
{
TChar chchar(aConvertedNumeral[0]);
switch(digittype)
{
case EDigitTypeDevanagari:
{
chchar = (aConvertedNumeral[0] + KLatinToDevanagariDigitsDelta);
}
break;
case EDigitTypeArabicIndic:
{
chchar = (aConvertedNumeral[0] + KLatinToArabicIndicDigitsDelta);
}
break;
case EDigitTypeEasternArabicIndic:
{
chchar = (aConvertedNumeral[0] + KLatinToEasternArabicIndicDigitsDelta);
}
}
aConvertedNumeral.Zero();
aConvertedNumeral.Append(chchar);
}
// End of file