fep/aknfep/src/aknfepuiinputstatestrokephrasebase.cpp
changeset 0 eb1f2e154e89
child 12 5e18d8c489d6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/aknfep/src/aknfepuiinputstatestrokephrasebase.cpp	Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,1286 @@
+/*
+* Copyright (c) 2008 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 TAknFepInputStateStrokePhraseCreationBase definition.
+*
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+// System includes
+#include <PtiEngine.h>
+#include <avkon.rsg>
+#include <AknFep.rsg>
+#include <PtiUserDicEntry.h>
+#include <aknnotewrappers.h> //CAknWarningNote 
+
+// User includes
+#include "AknFepUIManagerStateInterface.h"
+#include "AknFepUICtrlInputPane.h"
+#include "AknFepUICtrlPinyinPopup.h"        //Pinyin phrase
+#include "aknfepuictrleditpane.h"           //pinyin phrase creation
+#include "AknFepUICtrlCandidatePane.h"
+#include "AknFepManager.h"
+#include "aknfepuiinputstatestrokephrasebase.h"
+
+// Constant definition
+const TInt KMinCnadidateCount = 1;
+const TInt KMaxPhraseCount = 50;
+const TInt KEnginePhoneticIndex = 1;
+const TInt KMaxPhraseCreationCount = 7;
+const TInt KMaxKeystrokeCount = 31;
+const TInt KKey0Code = 48;
+const TInt KKey1Code = 49;
+const TInt KKey2Code = 50;
+const TInt KKey3Code = 51;
+const TInt KKey4Code = 52;
+const TInt KKey5Code = 53;
+const TInt KKey6Code = 54;
+const TInt KAutoChangeState = 1;
+const TInt KManualChangeState = 0; 
+const TUint16 KDelimiter = 0x2022;
+const TUint16 KStrokeKey1 = 0x4E00;
+const TUint16 KStrokeKey2 = 0x4E28;
+const TUint16 KStrokeKey3 = 0x4E3F;
+const TUint16 KStrokeKey4 = 0x4E36;
+const TUint16 KStrokeKey5 = 0x4E5B;
+const TUint16 KStrokeKey6 = 0x003F;
+
+const TUint16 KSegment = 0x0020;
+
+_LIT( KMaxPhraseNote,"\x8BCD\x7EC4\x6700\x957F\x4E3A\x4E03\x5B57" );
+
+const TKeyMap StrokeMap[] = 
+    {
+    {KDelimiter, KKey0Code},
+    {KStrokeKey1, KKey1Code},
+    {KStrokeKey2, KKey2Code},
+    {KStrokeKey3, KKey3Code},
+    {KStrokeKey4, KKey4Code},
+    {KStrokeKey5, KKey5Code},
+    {KStrokeKey6, KKey6Code}
+    };
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseCreationBase::TAknFepInputStateStrokePhraseCreationBase
+// C++ default constructor
+// ---------------------------------------------------------------------------
+//
+TAknFepInputStateStrokePhraseBase::TAknFepInputStateStrokePhraseBase(
+    MAknFepUIManagerStateInterface* aOwner,
+    MAknFepUICtrlContainerChinese* aUIContainer)
+    :TAknFepInputStateChineseBase(aOwner, aUIContainer)
+    {
+    if ( iOwner->PtiEngine()->InputMode() != EPtiEngineStrokeByPhrase )
+        {
+        iOwner->PtiEngine()->SetInputMode( EPtiEngineStrokeByPhrase );
+        }
+    iOwner->PtiEngine()->SetCandidatePageLength( KMaxPhraseCount );
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    uiContainer->SetFepMan( iOwner->FepMan() );
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleKeyL
+// Handle system key press event.
+// ---------------------------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::HandleKeyL( 
+                                        TInt aKey, 
+                                        TKeyPressLength aLength )
+    {    
+    switch( aKey )
+        {
+        case EKeyBackspace:
+            {
+            if ( CheckKeyNeedRepeat( aLength ) )
+                {
+                HandleKeyBackspaceL( aLength );
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+                }
+            break;
+            }
+        case EKeyUpArrow:
+            {
+            iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+            break;
+            }
+        case EKeyDownArrow:
+            {
+            if ( EStrokeSequenceEdit == iState )
+                {
+                if ( CheckFirstGroupStroke() )
+                    {
+                    UIContainer()->PinyinPopupWindow()->SetChangeState( ETrue );
+                    iOwner->ChangeState( EEntry );
+                    }
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+                }
+            break;
+            }
+        case EKeyLeftArrow:
+            {
+            if ( EStrokeSequenceEdit == iState )
+                {
+                MoveCursorLeft();
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+                }
+            break;
+            }    
+        case EKeyRightArrow:
+            {
+            if ( EStrokeSequenceEdit == iState )
+                {
+                MoveCursorRight();
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+                }
+            break;
+            }
+        case EKeyOK:
+        case EKeyCBA1:
+            {
+            if ( CheckKeyNeedRepeat( aLength ) )
+                {
+                HandleKeyCBA1OrKeyOKL( aLength );
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+                }
+            break;
+            }
+        case EKeyCBA2:
+            {
+            iOwner->FepMan()->TryCloseUiL();
+            break;
+            }
+        default:
+            {
+            if ( ( EShortKeyPress == aLength ) && 
+                ( iOwner->IsValidChineseInputKey( aKey ) ) )
+                {
+                HandleDefaultKeyL( aKey );
+                }
+            else
+                {
+                iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+                }
+            break;
+            }
+        }
+    
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::RefreshUI
+// Update input window.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::RefreshUI( TBool aRefresh )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    // get cursor position
+    if ( aRefresh )
+        {
+        TPoint baseLine;
+        TInt height(0);
+        TInt ascent(0);
+        TRAPD(ret,iOwner->FepMan()->GetScreenCoordinatesL(baseLine,height,ascent));
+        if (ret == KErrNone)
+            {
+            uiContainer->SetContainerPosition(baseLine, height);    
+            }
+        }
+    
+    ShowInfoOnEEPPane();
+    if ( !CheckAllKeystroke() )
+        {
+        SetWarningColor();
+        }
+    ShowInfoOnCandidatePane();
+    UpdateIndicator();
+    TRAP_IGNORE( ChangeCbaL() );
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleHorizontalNavigation
+// Handle horizontal navigation.
+// ---------------------------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::CheckFirstGroupStroke()
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    CDesCArrayFlat* keystroke = uiContainer->
+        PinyinPopupWindow()->KeystrokeArrayForStroke();
+    
+    TInt stringBeforeLength = 0;
+    TInt stringAfterLength = 0;
+    TInt keyCode = 0;
+    TInt pos = 0;
+    if ( 0 == keystroke->Count() )
+        {
+        return EFalse;
+        }
+    
+    ClearPtiEngineKeystroke();
+    TBuf<1> delimiter;
+    delimiter.Append( KDelimiter );
+    if ( 0 == keystroke->Find( delimiter, pos ) )
+        {
+        if ( 0 == pos )
+            {
+            return EFalse;
+            }
+        }
+    else
+        {
+        pos = keystroke->Count();
+        }
+    
+    for ( TInt i = 0; i < pos; ++i )
+        {
+        GetKeystrokeCode( keyCode, keystroke->MdcaPoint( i ) );
+        stringBeforeLength = 
+            ptiengine->GetPhoneticSpelling(KEnginePhoneticIndex).Length();
+        stringAfterLength = 
+            ptiengine->AppendKeyPress((TPtiKey)keyCode).Length();
+        //the keystroke is invalid.
+        if ( stringBeforeLength == stringAfterLength )
+            {
+            ClearPtiEngineKeystroke();
+            return EFalse;
+            }
+        } 
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleKeyBackspaceL
+// Handle KeyBackspace event.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::HandleKeyBackspaceL(
+                                                    TKeyPressLength aLength )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    CDesCArrayFlat* keystroke = popup->KeystrokeArrayForStroke();
+    TInt phraseCount = popup->ChooseChineseCharacterArrayForStroke()->Count();
+    TBool firstGroup = CheckFirstGroupStroke();
+    
+    if ( ( 0 == index ) && ( phraseCount != 0 ) )
+        {
+        RevertPhraseToKeystrokeL();
+        }
+    else if ( ( 0 == index ) && ( keystroke->Count() > 0 ) )
+        {
+        iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+        return;
+        }
+    else
+        {
+        if ( !DeleteKeystroke() )
+            {
+            iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+            return;
+            }
+        }
+    
+    if ( popup->ChooseChineseCharacterArrayForStroke()->Count() == 0 )
+        {
+        iOwner->FepMan()->PhraseCreation( EFalse );
+        }
+    
+    //if the keystroke is null and phrase is null then close input window.
+    if ( ( 0 == phraseCount ) && ( keystroke->Count() == 0 ) )
+        {
+        iOwner->FepMan()->TryCloseUiL(); //no more keys, close the UI.
+        if ( aLength == ELongKeyPress )
+            {
+            iOwner->FepMan()->SetLongClearAfterCloseUI( ETrue );
+            }
+        return;
+        }
+    
+    //Auto change from EStrokeSequenceEdit state to EEntry state. 
+    if ( EStrokeSequenceEdit == iState )
+        {
+        if ( ( KAutoChangeState == popup->GetState() ) && 
+              ( !firstGroup ) && CheckFirstGroupStroke() )
+            {
+            popup->SetChangeState( EFalse );
+            iOwner->ChangeState( EEntry );
+            return;
+            }
+        }
+    
+    //Auto change from EEntry state to EStrokeSequenceEdit state.
+    if ( EEntry == iState )
+        {
+        if ( ( firstGroup ) && ( !CheckFirstGroupStroke() ) )
+            {
+            popup->SetChangeState( EFalse );
+            popup->SetState( KAutoChangeState );
+            iOwner->ChangeState( EStrokeSequenceEdit );
+            return;
+            }
+        }
+    
+    RefreshUI();
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKEntryL
+// Entry handle CBA1 or OK key press event.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKEntry(
+                                                    TKeyPressLength aLength )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    TBool state = ETrue;
+    if ( popup->IsChangeStatet() && aLength == ELongKeyPress )
+        {
+        state = EFalse;
+        }
+    else
+        {
+        popup->SetChangeState( EFalse );
+        }
+    
+    if ( state )
+        {
+        popup->SetChangeState( ETrue );
+        iOwner->ChangeState( ECandidate );        
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKEditL
+// Edit state handle CBA1 or OK key press event.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKEditL()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    CDesCArrayFlat* phrase = popup->ChooseChineseCharacterArrayForStroke();
+    CDesCArrayFlat* keystrokeArray = popup->KeystrokeArrayForStroke();
+    TBuf<KMaxPhraseCreationCount> phraseCreated;
+    if ( (phrase->Count() >= 2 ) && ( 0 == keystrokeArray->Count() ) )
+        {
+        //commit the chinese character.
+        for (TInt i = 0; i < phrase->Count(); ++i )
+            {
+            phraseCreated.Append( phrase->MdcaPoint( i ) );
+            }
+        AddPhraseToDB( phraseCreated );
+        iOwner->FepMan()->NewTextL( phraseCreated );
+        iOwner->FepMan()->CommitInlineEditL();
+        iOwner->FepMan()->TryCloseUiL(); //no more keys, close the UI.
+        }
+    else if ( CheckFirstGroupStroke() )
+        {
+        popup->SetState( KManualChangeState );
+        popup->SetChangeState( ETrue );
+        iOwner->ChangeState( EEntry );
+        }
+    else
+        {
+        iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKL
+// Handle CBA1 or OK key press event.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::HandleKeyCBA1OrKeyOKL(
+                                                    TKeyPressLength aLength )
+    {
+    if ( EStrokeSequenceEdit == iState )
+        {
+        HandleKeyCBA1OrKeyOKEditL();
+        }
+    else if ( EEntry == iState )
+        {
+        HandleKeyCBA1OrKeyOKEntry( aLength );
+        }
+    else
+        {
+        iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleDefaultKeyL
+// Handle default key press event.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::HandleDefaultKeyL( TInt aKey )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    TBool firstGroup = CheckFirstGroupStroke();
+    
+    if ( !AddKeystrokeL( aKey ) )
+        {
+        iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+        return;
+        }
+    
+    //Auto change from EStrokeSequenceEdit state to EEntry state. 
+    if ( EStrokeSequenceEdit == iState )
+        {
+        if ( ( KAutoChangeState == popup->GetState() ) && 
+              ( !firstGroup ) && CheckFirstGroupStroke() )
+            {
+            popup->SetChangeState( ETrue );
+            iOwner->ChangeState( EEntry );
+            return;
+            }
+        }
+    
+    //Auto change from EEntry state to EStrokeSequenceEdit state.
+    if ( EEntry == iState )
+        {
+        if ( ( firstGroup ) && ( !CheckFirstGroupStroke() ) )
+            {
+            popup->SetState( KAutoChangeState );
+            popup->SetChangeState( ETrue );
+            iOwner->ChangeState( EStrokeSequenceEdit );
+            return;
+            }
+        }
+    
+    RefreshUI();
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::ShowInfoOnEEP
+// Show the showinfo on the EEP ctrl.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::ShowInfoOnEEPPane()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = popup->KeystrokeArrayForStroke();
+    CDesCArrayFlat* phrase = popup->ChooseChineseCharacterArrayForStroke();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    TBuf<KMaxKeystrokeCount> showInfo;
+    
+    for (TInt i = 0; i < phrase->Count(); ++i )
+        {
+        showInfo.Append( phrase->MdcaPoint( i ) );
+        }
+
+    for (TInt ii = 0; ii < keystroke->Count(); ++ii )
+        {
+        showInfo.Append( keystroke->MdcaPoint( ii ) );
+        }
+    
+    editPane->SetText( showInfo, phrase->Count() + index );
+    if ( EStrokeSequenceEdit == iState )
+        {
+        editPane->ActiveCursor();
+        }
+    else if ( EEntry == iState )
+        {
+        editPane->DeactiveCursor();
+        }
+    else
+        {
+        editPane->DisableCursor();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::ShowInfoOnEEP
+// Show the showinfo on the EEP ctrl.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::ShowInfoOnCandidatePane()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    uiContainer->SetControlInVisible( ETrue );
+    CDesCArrayFlat* phrase = uiContainer->CandidatePane()->CandidateArray();
+    if ( KMaxPhraseCreationCount == uiContainer->PinyinPopupWindow()->
+            ChooseChineseCharacterArrayForStroke()->Count() )
+        {
+        phrase->Reset();
+        TRAP_IGNORE( phrase->AppendL( KMaxPhraseNote ) );
+        uiContainer->SetControlInVisible( ETrue );
+        uiContainer->CandidatePane()->SplitPhraseCandidatesIntoPages();
+        uiContainer->CandidatePane()->SetCandidateBuffer();
+        uiContainer->Enable( ETrue );
+        uiContainer->ShowHorizontalScrollArrows( EFalse );
+        uiContainer->ShowVerticalScrollArrows( EFalse );
+        }
+    
+    TRAP_IGNORE( GetCandidateL() );
+    if ( phrase->Count() > 0 )
+        {
+        // layout candidate and fill candidate buffer for first display page
+        uiContainer->SetControlInVisible( ETrue );
+        uiContainer->CandidatePane()->SplitPhraseCandidatesIntoPages();
+        uiContainer->CandidatePane()->SetCandidateBuffer();
+        uiContainer->Enable( ETrue );
+        uiContainer->ShowVerticalScrollArrows( ETrue );
+        }
+    else
+        {
+        uiContainer->SetControlInVisible( EFalse );
+        uiContainer->CandidatePane()->SplitPhraseCandidatesIntoPages();
+        uiContainer->CandidatePane()->SetCandidateBuffer();
+        uiContainer->Enable( ETrue );
+        uiContainer->ShowHorizontalScrollArrows( EFalse );
+        uiContainer->ShowVerticalScrollArrows( EFalse );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::GetShowKeystroke
+//Handle horizontal navigation.
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::GetShowKeystroke(
+                                                        TInt aKey, 
+                                                        TDes& aKeystroke )
+    {
+    TInt count = sizeof( StrokeMap )/sizeof( StrokeMap[0] );
+    for ( TInt i = 0; i < count ; i++ )
+        {
+        if (aKey == StrokeMap[i].iKeyCode)
+            {
+            aKeystroke.Append(StrokeMap[i].iValue);
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::HandleHorizontalNavigation
+//Handle horizontal navigation.
+// ---------------------------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::HandleHorizontalNavigation(
+                                                                   TInt aKey )
+    {
+    MAknFepUICtrlCandidatePane* candidatePane = UIContainer()->CandidatePane();
+    TBool response = EFalse;
+
+    // Do navigation...
+    if (aKey == EKeyLeftArrow)
+        {        
+        if(!candidatePane->SelectPrev())
+            {
+            candidatePane->SetCandidateBuffer();
+            candidatePane->SelectLastPhrase();
+            }
+        response = ETrue;
+        }
+    else if (aKey == EKeyRightArrow)
+        {              
+        if(!candidatePane->SelectNext())
+            {
+            candidatePane->SetCandidateBuffer();
+            candidatePane->SelectFirstPhrase();
+            }
+        response = ETrue;
+        }
+        
+    if (response)
+        {
+        UpdateIndicator();
+        }   
+             
+    return response;
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::UpdateIndicator
+// Update Indicator.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::UpdateIndicator()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();        
+    MAknFepUICtrlCandidatePane* candidatePane = uiContainer->CandidatePane();
+    
+    if ( candidatePane->IsFirstPage() )
+        {
+        uiContainer->CandidatePane()->ShowUpScrollArrows( EFalse );
+        }
+    else
+        {
+        uiContainer->CandidatePane()->ShowUpScrollArrows( ETrue );
+        }
+
+    if ( candidatePane->IsLastPage() )
+        {
+        uiContainer->CandidatePane()->ShowDownScrollArrows( EFalse );
+        }
+    else
+        {
+        uiContainer->CandidatePane()->ShowDownScrollArrows( ETrue );
+        }
+    }      
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::DeleteKeystroke
+// Delete current keystroke.
+// ---------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::DeleteKeystroke()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystrokeArray = popup->KeystrokeArrayForStroke();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    
+    if ( ( 0 == index ) || ( keystrokeArray->Count() == 0 ) )
+        {
+        return EFalse;
+        }
+    
+    if ( 1 == index )
+        {
+        keystrokeArray->Delete( 0 );
+        editPane->SetCursorIndexOfKeystroke( 0 );
+        editPane->Reset();
+        }
+    else if ( index >= keystrokeArray->Count() )
+        {
+        keystrokeArray->Delete( keystrokeArray->Count() - 1 );
+        editPane->SetCursorIndexOfKeystroke( keystrokeArray->Count() );
+        }
+    else
+        {
+        keystrokeArray->Delete( index - 1 );
+        editPane->SetCursorIndexOfKeystroke( index - 1 );
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::AddPhraseToDB
+// Add phrase to DB.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::AddPhraseToDB( 
+                                                     const TDesC& aPhraseAdd )
+    {   
+    TPtiUserDictionaryEntry addUdbEntry( aPhraseAdd );
+    //Add the phrase to the DB by PTI Engine
+    iOwner->PtiEngine()->AddUserDictionaryEntry( addUdbEntry );
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::RefreshCandidate
+// Refresh candidate
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::RefreshCandidate()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    uiContainer->CandidatePane()->SetCandidateBuffer();
+    uiContainer->Enable( ETrue );
+
+    TBool multiplePages = !(uiContainer->CandidatePane()->IsLastPage() && 
+            uiContainer->CandidatePane()->IsFirstPage());
+    TInt bufLength = iOwner->PtiEngine()->CandidatePage().Length();
+    TBool showArrows = multiplePages || bufLength > KMinCnadidateCount;
+
+    uiContainer->ShowHorizontalScrollArrows( showArrows );
+    uiContainer->ShowVerticalScrollArrows( multiplePages );
+
+    uiContainer->CandidatePane()->SelectFirstPhrase();
+    UpdateIndicator();
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::CheckKeyNeedRepeat
+//  Check key whether need repeat.
+// ---------------------------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::CheckKeyNeedRepeat( TKeyPressLength aLength )
+    {
+    MAknFepUICtrlPinyinPopup* popup = UIContainer()->PinyinPopupWindow();
+    if ( popup->IsChangeStatet() && aLength == ELongKeyPress )
+        {
+        return EFalse;
+        }
+    else
+        {
+        popup->SetChangeState( EFalse );
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::ClearPtiEngineKeystroke
+// clear the ptiengine keystroke;
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::ClearPtiEngineKeystroke()
+    {
+    iOwner->PtiEngine()->ClearCurrentWord();
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::AddKeystrokeL
+// Add keystroke.
+// ---------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::AddKeystrokeL( TInt aKey )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystrokeArray = popup->KeystrokeArrayForStroke();
+    TInt phraseCount = popup->ChooseChineseCharacterArrayForStroke()->Count();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    
+    if ( phraseCount + keystrokeArray->Count() >= KMaxKeystrokeCount )
+        {
+        return EFalse;
+        }
+    
+    TBuf<1> keystroke;
+    GetShowKeystroke( aKey, keystroke );
+    if ( index >= keystrokeArray->Count() )
+        {
+        keystrokeArray->AppendL( keystroke );
+        editPane->SetCursorIndexOfKeystroke( keystrokeArray->Count() );
+        }
+    else
+        {
+        keystrokeArray->InsertL( index, keystroke );
+        editPane->SetCursorIndexOfKeystroke( index + 1 );
+        }
+    return ETrue;
+    }
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::GetCandidateL
+// Get the candidate info.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::GetCandidateL()
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    CDesCArrayFlat* phraseCandidates = 
+        uiContainer->CandidatePane()->CandidateArray();
+    CDesCArrayFlat* keystroke = popup->KeystrokeArrayForStroke();
+    phraseCandidates->Reset();
+    TBuf<KMaxKeystrokeCount> buf;
+    TBuf<1> delimiter;
+    delimiter.Append( KDelimiter );
+    if ( !CheckFirstGroupStroke() )
+        {
+        return;
+        }
+    else if ( CheckAllKeystroke() )
+        {
+        for( TInt i = 0; i < keystroke->Count(); ++i )
+            {
+            buf.Append( keystroke->MdcaPoint( i ) );
+            }
+        }
+    else
+        {
+        TInt pos = 0;
+        if ( 0 == keystroke->Find( delimiter,pos ) )
+            {
+            for( TInt i = 0; i < pos; ++i )
+                {
+                buf.Append( keystroke->MdcaPoint( i ) );
+                }
+            }
+        else
+            {
+            for( TInt i = 0; i < keystroke->Count(); ++i )
+                {
+                buf.Append( keystroke->MdcaPoint( i ) );
+                }
+            }
+        }
+    extern void CleanArray( TAny* aAny );
+    RPointerArray<HBufC> list;
+    TCleanupItem cleanitem( CleanArray, &list );
+    CleanupStack::PushL( cleanitem );
+    HBufC* retString = ptiengine->GetCandidatesByInputString( 
+                                              buf, 
+                                              list,
+                                              EFalse );
+    
+    delete retString;
+    retString = NULL;
+    
+    for ( TInt i = 0; i < list.Count(); ++i )
+        {
+        phraseCandidates->AppendL( *(list[i]) );
+        }
+    CleanupStack::PopAndDestroy();   
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::GetKeystrokeCode
+// get Code of the key stroke. 
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::GetKeystrokeCode(
+                                                     TInt& aKey, 
+                                                     const TDesC& aKeystroke )
+    {
+    TInt count = sizeof( StrokeMap )/sizeof( StrokeMap[0] );
+    for ( TInt i = 0; i < count ; i++ )
+        {
+        TBuf<1> buf;
+        buf.Append(StrokeMap[i].iValue);
+        if (0 == aKeystroke.Compare(buf))
+            {
+            aKey = StrokeMap[i].iKeyCode;
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::CheckAllKeystroke
+// Get the candidate info.
+// ---------------------------------------------------------
+//
+TBool TAknFepInputStateStrokePhraseBase::CheckAllKeystroke()
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    CDesCArrayFlat* keystrokeArray = uiContainer->
+        PinyinPopupWindow()->KeystrokeArrayForStroke();
+    
+    TInt chineseCount = uiContainer->PinyinPopupWindow()->
+        ChooseChineseCharacterArrayForStroke()->Count();
+    TInt stringBeforeLength = 0;
+    TInt stringAfterLength = 0;
+    TInt keyCode = 0;
+    TInt delimiterCount = 0; 
+    TBuf<1> delimiter;
+    delimiter.Append( KDelimiter );
+    if ( chineseCount > 0 )
+        {
+        return EFalse;
+        }
+    
+    if ( keystrokeArray->Count() > 0 )
+        {
+        if ( 0 == keystrokeArray->MdcaPoint( 0 ).Compare( delimiter ) )
+            {
+            return EFalse;
+            }
+        }
+    ClearPtiEngineKeystroke();
+    for ( TInt i = 0; i < keystrokeArray->Count(); ++i )
+        {
+        if ( 0 == keystrokeArray->MdcaPoint( i ).Compare( delimiter ) )
+            {
+            delimiterCount = delimiterCount + 1;
+            }
+        GetKeystrokeCode( keyCode, keystrokeArray->MdcaPoint( i ) );
+        stringBeforeLength = 
+            ptiengine->GetPhoneticSpelling(KEnginePhoneticIndex).Length();
+        stringAfterLength = 
+            ptiengine->AppendKeyPress((TPtiKey)keyCode).Length();
+
+        if ( stringBeforeLength == stringAfterLength )
+            {
+            ClearPtiEngineKeystroke();
+            return EFalse;
+            }
+        }
+    if ( delimiterCount >= KMaxPhraseCreationCount )
+        {
+        return EFalse;
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::RevertPhraseToKeystrokeL
+// Revert the phrase to keystroke.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::RevertPhraseToKeystrokeL()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystrokeArray = popup->KeystrokeArrayForStroke();
+    CDesCArrayFlat* phrase = popup->ChooseChineseCharacterArrayForStroke();
+    CDesCArrayFlat* phraseStroke = 
+        popup->ChooseChineseCharacterArrayKeystrokeForStroke();
+
+    TBuf<KMaxKeystrokeCount> buf;
+    if ( ( phrase->Count() == 0 ) || ( phraseStroke->Count() == 0 ) )
+        {
+        return;
+        }
+    
+    buf.Append( phraseStroke->MdcaPoint( phraseStroke->Count() - 1 ) );
+    
+    for ( TInt i = buf.Length() - 1; i >= 0; --i )
+        {
+        keystrokeArray->InsertL( 0, buf.Mid( i, 1 ) );
+        }
+    phrase->Delete( phrase->Count() - 1 );
+    phraseStroke->Delete( phraseStroke->Count() - 1 );
+    
+    TInt leng = phrase->Count() + keystrokeArray->Count();
+    if ( leng > KMaxKeystrokeCount )
+        {
+        for ( TInt i = 0; i < leng - KMaxKeystrokeCount; ++i )
+            {
+            keystrokeArray->Delete( keystrokeArray->Count() - 1 );
+            }
+        }
+    editPane->SetCursorIndexOfKeystroke( buf.Length() );
+    keystrokeArray->Compress();
+    phrase->Compress();
+    phraseStroke->Compress();
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::SetWarningColor
+// Set warning color.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::SetWarningColor()
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    CDesCArrayFlat* keystrokeArray = UIContainer()->
+        PinyinPopupWindow()->KeystrokeArrayForStroke();
+    MAknFepUICtrlEditPane* editPane = UIContainer()->EditPaneWindow();
+    TInt phraseCount = UIContainer()->PinyinPopupWindow()->
+        ChooseChineseCharacterArrayForStroke()->Count();
+
+    TInt indexStart = phraseCount;
+    TInt keyCode = 0;
+    TInt stringBeforeLength = 0;
+    TInt stringAfterLength = 0;
+    TInt keystrokeCount = 0;
+    TInt validKeystrokeCountOfPti = 0;
+    TBool valid = ETrue;
+    TInt delimiterCount = 0;
+    TInt delimiterADD = 0;
+    TBuf<1> delimiter;
+    delimiter.Append( KDelimiter );
+    ClearPtiEngineKeystroke();
+
+    for ( TInt i = 0; i < keystrokeArray->Count(); ++i )
+        {
+        keystrokeCount = keystrokeCount + 1;
+        if ( phraseCount + delimiterCount >= KMaxPhraseCreationCount )
+            {
+            break;
+            }
+        if ( 0 == keystrokeArray->MdcaPoint( i ).Compare( delimiter ) )
+            {
+            delimiterADD = i;
+            delimiterCount = delimiterCount + 1;
+            }
+        GetKeystrokeCode( keyCode, keystrokeArray->MdcaPoint( i ) );
+        stringBeforeLength = ptiengine->GetPhoneticSpelling(
+            KEnginePhoneticIndex).Length();
+        stringAfterLength = 
+            ptiengine->AppendKeyPress((TPtiKey)keyCode).Length();
+
+        if ( stringBeforeLength == stringAfterLength )
+            {
+            valid = EFalse;
+            }
+        else if ( valid )
+            {
+            validKeystrokeCountOfPti = validKeystrokeCountOfPti + 1;
+            }
+
+        if ( ( i == keystrokeArray->Count() - 1 ) && ( KKey0Code != keyCode )
+            && ( 1 != keystrokeCount ) && ( !valid ) )
+            {
+            editPane->SetHighlight( indexStart, indexStart + keystrokeCount - 1 );
+            validKeystrokeCountOfPti = 0;
+            keystrokeCount = 0;
+            valid = ETrue;
+            }
+
+        if ( KKey0Code == keyCode )
+            {
+            ClearPtiEngineKeystroke();
+            if ( 0 == i )
+                {
+                editPane->SetHighlight( indexStart, indexStart
+                    + keystrokeCount - 1 );
+                indexStart = phraseCount + i + 1;
+                validKeystrokeCountOfPti = 0;
+                keystrokeCount = 0;
+                valid = ETrue;
+                }
+            else
+                {
+                if ( ( 0 == keystrokeArray->MdcaPoint( i ).
+                Compare( delimiter ) ) && ( 0
+                    == keystrokeArray->MdcaPoint( i - 1 ).
+                    Compare( delimiter ) ) )
+                    {
+                    editPane->SetHighlight( indexStart, indexStart
+                        + keystrokeCount - 1 );
+                    indexStart = phraseCount + i + 1;
+                    validKeystrokeCountOfPti = 0;
+                    keystrokeCount = 0;
+                    valid = ETrue;
+                    }
+                else
+                    {
+                    if (  ( !valid ) && ( 1 != keystrokeCount ) && 
+                        ( validKeystrokeCountOfPti < keystrokeCount - 1 ) )
+                        {
+                        editPane->SetHighlight( indexStart, indexStart
+                            + keystrokeCount - 1 );
+                        indexStart = phraseCount + i + 1;
+                        validKeystrokeCountOfPti = 0;
+                        keystrokeCount = 0;
+                        valid = ETrue;
+                        }
+                    else
+                        {
+                        indexStart = phraseCount + i + 1;
+                        validKeystrokeCountOfPti = 0;
+                        keystrokeCount = 0;
+                        valid = ETrue;
+                        }
+                    }
+                }
+            }
+        }
+    
+    if ( phraseCount + delimiterCount >= KMaxPhraseCreationCount )
+        {
+        editPane->SetHighlight( 
+                phraseCount + delimiterADD, 
+                phraseCount + keystrokeArray->Count() );
+        }
+
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::SetWarningColor
+// Set warning color.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::ChangeCbaL()
+    {
+    MAknFepUICtrlPinyinPopup* popup = UIContainer()->PinyinPopupWindow();
+    TInt keystrokeCount = popup->KeystrokeArrayForStroke()->Count();
+    TInt phraseCount = popup->ChooseChineseCharacterArrayForStroke()->Count();
+    TInt lastRes = popup->GetLastResouce();
+    
+    TBool first = CheckFirstGroupStroke();
+    CheckAllKeystroke();
+    if ( phraseCount == KMaxPhraseCreationCount )
+        {
+        if ( lastRes == R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE )
+            {
+            return;
+            }
+        //User cba done-done-cancel
+        iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE );
+        popup->SetLastResouce( R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE );
+        }
+    else if ( 0 != keystrokeCount && first )
+        {
+        if ( lastRes == R_AKNFEP_SOFTKEYS_PHRASE_CREATION_SELECT_CANCEL_SELECT )
+            {
+            return;
+            }
+        //User cba select-select-cancel
+        iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS_PHRASE_CREATION_SELECT_CANCEL_SELECT );
+        popup->SetLastResouce( R_AKNFEP_SOFTKEYS_PHRASE_CREATION_SELECT_CANCEL_SELECT );
+        }
+    else if ( phraseCount > 1 && 0 == keystrokeCount )
+        {
+        if ( lastRes == R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE )
+            {
+            return;
+            }
+        //User cba done-done-cancel
+        iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE );
+        popup->SetLastResouce( R_AKNFEP_SOFTKEYS_DONE_CANCEL_DONE );
+        }
+    else
+        {
+        if ( lastRes == R_AKNFEP_SOFTKEYS__PHRASE_CREATION_EMPTY_CANCEL_EMPTY )
+            {
+            return;
+            }
+        iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS__PHRASE_CREATION_EMPTY_CANCEL_EMPTY );
+        popup->SetLastResouce( R_AKNFEP_SOFTKEYS__PHRASE_CREATION_EMPTY_CANCEL_EMPTY );
+        }
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::MoveCursorLeft
+// Move the cursor to Left.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::MoveCursorLeft()
+    {
+    MAknFepUICtrlPinyinPopup* popup = UIContainer()->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = UIContainer()->EditPaneWindow();
+    TInt keystrokeCount = popup->KeystrokeArrayForStroke()->Count();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    if ( 0 == keystrokeCount )
+        {
+        iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+        return;
+        }
+    else
+        {
+        popup->SetState( KManualChangeState );
+        }
+    
+    if ( index > 1 )
+        {
+        editPane->SetCursorIndexOfKeystroke( index - 1 );
+        editPane->MoveCursorLeft();
+        }
+    else
+        {
+        if ( 1 == index )
+            {
+            editPane->SetCursorIndexOfKeystroke( 0 );
+            }
+        else
+            {
+            editPane->SetCursorIndexOfKeystroke( keystrokeCount );
+            }
+        ShowInfoOnEEPPane();
+        if ( !CheckAllKeystroke() )
+            {
+            SetWarningColor();
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::MoveCursorRight
+// Move the cursor to Right.
+// ---------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::MoveCursorRight()
+    {
+    MAknFepUICtrlPinyinPopup* popup = UIContainer()->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = UIContainer()->EditPaneWindow();
+    TInt keystrokeCount = popup->KeystrokeArrayForStroke()->Count();
+    TInt index = editPane->GetCursorIndexOfKeystroke();
+    if ( 0 == keystrokeCount )
+        {
+        iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+        return;
+        }
+    else
+        {
+        popup->SetState( KManualChangeState );
+        }
+    
+    if ( index < keystrokeCount )
+        {
+        editPane->SetCursorIndexOfKeystroke( index + 1 );
+        editPane->MoveCursorRight();
+        }
+    else
+        {
+        editPane->SetCursorIndexOfKeystroke( 0 );
+        ShowInfoOnEEPPane();
+        if ( !CheckAllKeystroke() )
+            {
+            SetWarningColor();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateStrokePhraseBase::GetNewCandidatesL 
+// Get new candidate
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateStrokePhraseBase::GetNewCandidatesL(const TDesC& aSource, 
+                                                    RPointerArray<HBufC>& aList)
+    {
+    TInt start = 0;
+    TInt length = 0;
+
+    for (TInt ii = 0; ii < aSource.Length(); ii++)
+        {
+        if (aSource[ii] == KSegment)
+            {
+            TPtrC segment(aSource.Ptr() + start, length);
+            aList.AppendL(segment.AllocL());
+            start += (length + 1);
+            length = 0;
+            }
+        else
+            {
+            length++;
+            }
+        }
+
+    if (length)
+        {
+        TPtrC segm(aSource.Ptr() + start, length);
+        aList.AppendL(segm.AllocL());
+        }
+    }
+
+// End of file