fep/aknfep/src/AknFepUiInputStateEntryMiniQwertyZhuyinPhrase.cpp
changeset 0 eb1f2e154e89
child 12 5e18d8c489d6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/aknfep/src/AknFepUiInputStateEntryMiniQwertyZhuyinPhrase.cpp	Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,1010 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0""
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:           
+ *       Provides the CAknFepUIInputStateMiniQwertyZhuyinPhrase methods.
+ *
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+#include "AknFepUiInputStateEntryMiniQwertyZhuyinPhrase.h"
+#include "AknFepUIManagerStateInterface.h"
+
+#include "AknFepUICtrlInputPane.h"
+#include "AknFepUICtrlCandidatePane.h"
+#include "AknFepManagerUIInterface.h"       //MAknFepManagerUIInterface
+#include "AknFepManager.h"                  //FepMan flag
+#include "AknFepUICtrlPinyinPopup.h"		//Pinyin phrase
+#include "aknfepuictrleditpane.h"           //phrase creation
+#include "aknfepinputstateminiqwertyzhuyinkeymap.h"  //phrase creation
+#include <PtiEngine.h>
+#include <e32keys.h>
+#include <PtiDefs.h>    
+#include <avkon.rsg>            //keys
+#include <AknFep.rsg>
+
+const TInt KInputPaneLength = 32;
+_LIT(KSep, "'");
+_LIT(KReplace, "");
+_LIT(KLeftBracket, "(");
+_LIT(KRightBracket, ")");
+const TText KPinyinTone4Valid = 0x02D9;
+const TText KPinyinTone4Invalid = 0x0020;
+const TInt KMaxKeystrokeCount = 31;
+const TInt KKeystrokeMaxLength =5;
+const TInt KKeyBufferMaxLength =150;
+
+const TUint16 KSai = 0x311D;
+const TUint16 KToneMark1 = 0x0020;
+const TUint16 KToneMark2 = 0x02CA;
+const TUint16 KToneMark3 = 0x02c7;
+const TUint16 KToneMark4 = 0x02CB;
+const TUint16 KToneMark5 = 0x02D9;
+
+struct TToneZhuYinMap
+    {
+    TUint16 iValue;
+    TInt iInputTone;
+    };
+const TToneZhuYinMap ZhuyinToneMap[] =
+    {
+        {
+        KToneMark1, 1
+        },
+        {
+        KToneMark2, 2
+        },
+        {
+        KToneMark3, 3
+        },
+        {
+        KToneMark4, 4
+        },
+        {
+        KToneMark5, 5
+        }
+    };
+
+const TInt KMaxPhraseCount = 150;//This should be the same as that in pticpicore. 
+
+_LIT( KZhuyinNote,"\x9020\x65B0\x8BCD" );
+
+TAknFepInputStateEntryMiniQwertyZhuyinPhrase::TAknFepInputStateEntryMiniQwertyZhuyinPhrase(
+    MAknFepUIManagerStateInterface* aOwner,
+    MAknFepUICtrlContainerChinese* aUIContainer ) :
+    TAknFepInputStateEntryQwertyBaseChinesePhrase( aOwner, aUIContainer)
+    {
+    iState = EEntry;
+
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    uiContainer->FocusCandidatePane( EFalse );
+    uiContainer->CandidatePane()->ShowCandidateOrdinals( EFalse );
+    uiContainer->SetLayout( MAknFepUICtrlContainerChinese::ELayoutInput );
+    uiContainer->CandidatePane()->SelectFirstPhrase();
+    uiContainer->ShowVerticalScrollArrows( ETrue );
+    uiContainer->ShowHorizontalScrollArrows( EFalse );
+    uiContainer->InputPane()->SetOverrideFontId( 0 );
+    uiContainer->SetFepMan( iOwner->FepMan() );
+    
+    //For fix bug that the text in input pane could not be shown totally. 
+    if ( iOwner->FepMan()->KeyboardLayout() == EPtiKeyboardQwerty4x10 ||
+        iOwner->FepMan()->KeyboardLayout() == EPtiKeyboardQwerty3x11)
+        {
+        uiContainer->PinyinPopupWindow()->SetInputLayoutMiniQwertyZhuyin();
+        }
+    
+    iOwner->PtiEngine()->SetCandidatePageLength( KMaxPhraseCount );
+    // in the case that we are coming back to the input pane from the candidate pane, 
+    // we need to ensure that the current selection is selected correctly
+    ImplicitlyUpdateSelection();
+    // however we also need to clear the deliberate selection, in case we are not
+    // coming back to the input pane from the candidate pane
+    ClearDeliberateSelection();
+    UpdateIndicator();
+
+    iOwner->PtiEngine()->SetInputMode( EPtiEngineZhuyinPhraseQwerty );
+    iOwner->PtiEngine()->SetCase( EPtiCaseLower );
+    }
+
+TBool TAknFepInputStateEntryMiniQwertyZhuyinPhrase::HandleKeyL( TInt aKey,
+    TKeyPressLength aLength )
+    {
+    if ( iOwner->FepMan()->KeyboardLayout() == EPtiKeyboardQwerty4x10 ||
+        iOwner->FepMan()->KeyboardLayout() == EPtiKeyboardQwerty3x11)
+        {
+        return HandleKeyForMiniQwertyL( aKey, aLength );
+        }
+    else
+        {
+        return HandleKeyForHalfAndCustomQwertyL( aKey, aLength );
+        }
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::KeyTimerExpired()
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlInputPane* inputPane = uiContainer->InputPane();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = editPane->KeystrokeArray();
+
+    // set container's position
+    TPoint baseLine = TPoint( 0, 0 );
+    TInt height = 0;
+    TInt ascent = 0;
+    TRAPD(ret,iOwner->FepMan()->GetScreenCoordinatesL(baseLine,height,ascent))
+    ;
+    if ( ret == KErrNone )
+        {
+        uiContainer->SetContainerPosition( baseLine, height );
+        }
+
+    TInt pinyinCountWithoutToneMarks = ptiengine->PhoneticSpellingCount();
+    if ( editPane->GetEffictiveLength() < keystroke->Count()
+        || pinyinCountWithoutToneMarks == popup->CurrentSelection() )
+        {
+        TBuf<KKeyBufferMaxLength> keystrokeBuf;
+        for (TInt i = 0; i < keystroke->Count(); i++ )
+            {
+            keystrokeBuf.Append( keystroke->MdcaPoint( i ) );
+            }
+        inputPane->SetText( keystrokeBuf );
+        }
+    else
+        {
+        TPtrC ptr = ptiengine->GetPhoneticSpelling( 1 );
+        TBuf<KInputPaneLength> currentText;
+        inputPane->GetText( currentText );
+        if ( ptr.Length() < currentText.Length() )
+            {
+            iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+            }
+        inputPane->SetText( ptr );
+        }
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::DeliberatelyUpdateSelection()
+    {
+    TPtr deliberateSelection = iOwner->GetLatestDeliberateSelection();
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+
+    TInt selected = popup->CurrentSelection();
+    ptiengine->EnableToneMarks( EFalse );
+    TPtrC spelling = ptiengine->GetPhoneticSpelling( selected + 1 ); // our index is zero based, engine index is one based
+    deliberateSelection
+        = spelling.Left( MAknFepUICtrlInputPane::EMaxInputCharsPinyinPopupNotIncludingToneMark );
+    ptiengine->EnableToneMarks( ETrue );
+    UIContainer()->PinyinPopupWindow()->SetFlag( MAknFepUICtrlPinyinPopup::ESpellingNavigation );
+    RefreshUI( popup->CurrentVisibleSelection() );
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::ImplicitlyUpdateSelection()
+    {
+    TPtr oldDeliberateSelection = iOwner->GetLatestDeliberateSelection();
+    TInt oldDeliberateSelectionLength = oldDeliberateSelection.Length();
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+
+    // previously selected is compared in turn to each of the new candidates
+    ptiengine->EnableToneMarks( EFalse );
+    TInt pinyinCount = ptiengine->PhoneticSpellingCount();
+    TInt newSelection = 0;
+    for (TInt i = 0; i < pinyinCount; i++ )
+        {
+        TPtrC spelling = ptiengine->GetPhoneticSpelling( i + 1 ); // our index is zero based, engine index is one based
+        TInt spellingLength = spelling.Length();
+
+        // figure out how many characters we are comparing, this depends on the 
+        // direction of the edit
+        TInt compareLength = oldDeliberateSelectionLength <= spellingLength
+            ? oldDeliberateSelectionLength : spellingLength;
+
+        if ( oldDeliberateSelection.Left( compareLength )
+            == spelling.Left( compareLength ) )
+            {
+            // as soon as a substring match is found, the 
+            // highlight position is set to that candidate in the new list. 
+            // note that in the case of the first character entered, the
+            // oldBuf will be empty so it will always match... which is 
+            // fine as we want to select the top one anyway, so we will
+            // quit the loop early.
+            newSelection = i;
+            break;
+            }
+        }
+    ptiengine->EnableToneMarks( ETrue );
+    UIContainer()->PinyinPopupWindow()->SetFlag( MAknFepUICtrlPinyinPopup::ESpellingChanged );
+    RefreshUI( newSelection );
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::ClearDeliberateSelection()
+    {
+    // we must have just deleted the last character, 
+    // or we are starting a new zhuyin session, so wipe the last deliberate selection
+    CDesCArrayFlat* keystroke = UIContainer()->EditPaneWindow()->KeystrokeArray();
+    if ( keystroke->Count() == 0 )
+        {
+        TPtr oldDeliberateSelection = iOwner->GetLatestDeliberateSelection();
+        oldDeliberateSelection = KNullDesC;
+        }
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::RefreshUI( TInt aSelection )
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlInputPane* inputPane = uiContainer->InputPane();
+    CDesCArrayFlat* spelling = popup->PhoneticSpellingArray();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = editPane->KeystrokeArray();
+    TBuf<KKeyBufferMaxLength> keystrokeBuf;
+
+    // get cursor position
+    TPoint baseLine = TPoint( 0, 0 );
+    TInt height = 0;
+    TInt ascent = 0;
+
+    TRAPD(ret,iOwner->FepMan()->GetScreenCoordinatesL(baseLine,height,ascent));
+    if ( ret == KErrNone )
+        {
+        uiContainer->SetContainerPosition( baseLine, height );
+        }
+
+    TText toneMark;
+    TBool toneMarkEntered = ptiengine->ToneMark( toneMark );
+    TBuf<1> validToneMarkBuf;
+    if ( toneMarkEntered )
+        {
+        // override specific invalid tonemark character only, the others are the same character 
+        // when both valid and invalid
+        if ( toneMark == KPinyinTone4Invalid )
+            toneMark = KPinyinTone4Valid;
+        validToneMarkBuf.Append( toneMark );
+        }
+
+    // to start with, disable the tone marks so we can get the list of all zhuyin matches
+    // later we will figure out which ones are invalid
+    ptiengine->EnableToneMarks( EFalse );
+    TInt pinyinCountWithoutToneMarks = ptiengine->PhoneticSpellingCount();
+
+    for (TInt i = 0; i < keystroke->Count(); i++ )
+        {
+        keystrokeBuf.Append( keystroke->MdcaPoint( i ) );
+        }
+
+    if ( pinyinCountWithoutToneMarks > 0 )
+        {
+        if ( popup->IsFlagSet( MAknFepUICtrlPinyinPopup::ESpellingChanged ) )
+            {
+            if ( editPane->GetEffictiveLength() < keystroke->Count() )
+                {
+                spelling->Reset();
+                spelling->Compress();
+                }
+            else
+                {
+                TRAPD(ignore, ptiengine->GetPhoneticSpellingsL(*spelling));
+                if ( ignore != KErrNone )
+                    {
+                    return;
+                    }
+                }
+
+            TRAPD( retOptimize, spelling->AppendL( keystrokeBuf ) );
+            if ( KErrNone != retOptimize )
+                {
+                return;
+                }
+
+            popup->SplitPhraseSpellingIntoPages();
+            }
+
+        // set display page for delibrate selection
+        popup->SetDisplayPage( aSelection );
+        popup->SetPhraseItemTexts();
+
+        // fill in input pane although it's invisible
+        if ( editPane->GetEffictiveLength() < keystroke->Count()
+            || pinyinCountWithoutToneMarks == popup->CurrentSelection() )
+            {
+            inputPane->SetText( keystrokeBuf );
+            }
+        else
+            {
+            inputPane->SetText( ptiengine->GetPhoneticSpelling( popup->CurrentSelection()
+                + 1 ) );
+            }
+        popup->PopupSizeChanged(); // phrase input
+        }
+    // turn tone marks back on so that we know where we are.
+    ptiengine->EnableToneMarks( ETrue );
+
+    // this is where we start to figure out whether the tonemarks are valid,
+    // whether the selected tonemark is valid, and what is the index of the 
+    // selected candidate in the list of candidates with tonemarks...
+    TBool selectionToneMarkValid = EFalse;
+    TInt selectionIndexAdjustedForToneMarkValidity =
+        popup->CurrentSelection();
+
+    // we only need to deal with tone marks if there is one
+    if ( toneMarkEntered )
+        {
+        if ( pinyinCountWithoutToneMarks > 0 )
+            {
+            for (TInt i = popup->CurrentSelection() + 1; i < pinyinCountWithoutToneMarks; i++ )
+                {
+                TBool valid = EFalse;
+
+                TBuf<MAknFepUICtrlInputPane::EMaxInputCharsPinyinPopupNotIncludingToneMark>
+                    nextCandidateWithoutToneMark;
+                nextCandidateWithoutToneMark.Copy( ptiengine->GetPhoneticSpelling(i + 1).Left( MAknFepUICtrlInputPane::EMaxInputCharsPinyinPopupNotIncludingToneMark ) );
+
+                ptiengine->EnableToneMarks( EFalse );
+                ptiengine->SelectPhoneticSpelling( i + 1 );
+
+                valid = ptiengine->IsToneMarkValidForSpelling();
+                if ( valid )
+                    {
+                    ptiengine->EnableToneMarks( ETrue );
+                    TInt pinyinCountWithToneMarks =
+                        ptiengine->PhoneticSpellingCount();
+
+                    for (TInt j = popup->CurrentSelection() + 1; j < pinyinCountWithToneMarks; j++ )
+                        {
+                        // use j here not i as we are looking at the list with tonemarks
+                        TPtrC nextCandidateWithToneMark =
+                            ptiengine->GetPhoneticSpelling( j + 1 );
+                        if ( nextCandidateWithToneMark
+                            == nextCandidateWithoutToneMark )
+                            {
+                            if ( i == aSelection )
+                                {
+                                selectionToneMarkValid = ETrue;
+
+                                // fill in input pane even if it can't be seen, for when we have to hide popup window
+                                inputPane->SetText( nextCandidateWithoutToneMark );
+                                }
+                            break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    ptiengine->EnableToneMarks( EFalse );
+    ptiengine->SelectPhoneticSpelling( popup->CurrentSelection() + 1 );
+    // next two lines are for tonemark validity
+    ptiengine->EnableToneMarks( selectionToneMarkValid );
+    ptiengine->SelectPhoneticSpelling( selectionIndexAdjustedForToneMarkValidity
+        + 1 ); // our index is zero based, engine index is one based
+
+    // update the candidate pane.
+    if ( popup->IsFlagSet( MAknFepUICtrlPinyinPopup::ESpellingChanged )
+        || popup->IsFlagSet( MAknFepUICtrlPinyinPopup::ESpellingNavigation ) )
+        {
+        CDesCArrayFlat* phraseCandidates = uiContainer->CandidatePane()->CandidateArray();
+        if ( editPane->GetEffictiveLength() == keystroke->Count()
+            && pinyinCountWithoutToneMarks > popup->CurrentSelection() )
+            {
+            TRAPD(ignore, ptiengine->GetChinesePhraseCandidatesL(*phraseCandidates));
+            if ( ignore != KErrNone )
+                {
+                return;
+                }
+            }
+        else if ( keystroke->Count() != 0 )
+            {
+            phraseCandidates->Reset();
+            phraseCandidates->Compress();
+            TRAPD( retAddZhuyinNote, phraseCandidates->AppendL( KZhuyinNote ) );
+            if ( KErrNone != retAddZhuyinNote )
+                {
+                return;
+                }
+            }
+
+        uiContainer->CandidatePane()->SplitPhraseCandidatesIntoPages();
+        popup->ClearFlag( MAknFepUICtrlPinyinPopup::ESpellingChanged
+            | MAknFepUICtrlPinyinPopup::ESpellingNavigation );
+        }
+    uiContainer->CandidatePane()->SetCandidateBuffer();
+    uiContainer->Enable( ETrue );
+    // need to enable the pinyin popup after the container so that it is raised to the front
+    popup->Enable( pinyinCountWithoutToneMarks > 0 );
+    UpdateIndicator();
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::InitializeStateL( void )
+    {
+    iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS_OK_SELECT_CANCEL );
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::UpdateIndicator()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();        
+    MAknFepUICtrlCandidatePane* candidatePane = uiContainer->CandidatePane();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = editPane->KeystrokeArray();
+    TInt pinyinCountWithoutToneMarks = ptiengine->PhoneticSpellingCount();
+        
+    if (candidatePane->IsFirstPage())
+        {
+        uiContainer->CandidatePane()->ShowUpScrollArrows(EFalse);    
+        }
+    else
+        {
+        uiContainer->CandidatePane()->ShowUpScrollArrows(ETrue);    
+        }
+   
+    if (candidatePane->IsLastPage())
+        {
+        uiContainer->CandidatePane()->ShowDownScrollArrows(EFalse);     
+        }
+    else
+        {
+        uiContainer->CandidatePane()->ShowDownScrollArrows(ETrue);      
+        }
+    
+    if ( editPane->GetEffictiveLength() < keystroke->Count() ||
+        pinyinCountWithoutToneMarks == popup->CurrentSelection() )
+        {
+        uiContainer->ShowVerticalScrollArrows(EFalse);
+        }
+    else
+        {
+        uiContainer->ShowVerticalScrollArrows(ETrue);
+        }
+    }
+
+TBool TAknFepInputStateEntryMiniQwertyZhuyinPhrase::CheckToneMarkBorderUpon()
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = editPane->KeystrokeArray();
+    TPtrC ptr = keystroke->MdcaPoint( keystroke->Count() - 1 );
+    TInt num = sizeof(ZhuyinToneMap )/( sizeof(ZhuyinToneMap[0]));
+    for (TInt i = 0; i< num; i++ )
+        {
+        //if ( ptr.Compare( ZhuyinToneMap[i].iValue) == 0 )
+        if ( ptr[0] == ZhuyinToneMap[i].iValue )
+            {
+            return ETrue;
+            }
+        }
+
+    return EFalse;
+    }
+
+TBool TAknFepInputStateEntryMiniQwertyZhuyinPhrase::HandleKeyForMiniQwertyL( TInt aKey,
+    TKeyPressLength aLength )
+    {
+
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlInputPane* inputPane = uiContainer->InputPane();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    MAknFepUICtrlEditPane* editPane = uiContainer->EditPaneWindow();
+    CDesCArrayFlat* keystroke = editPane->KeystrokeArray();
+    RArray<TInt>* keycodeArray = editPane->KeycodeArray();
+    TInt keystrokeLength = keystroke->Count();
+
+    TBool ret = ETrue;
+
+    if ( (aKey == EPtiKeyQwertyE || aKey == EPtiKeyQwertyR || 
+        aKey == EPtiKeyQwertyY || aKey == EPtiKeyQwertyU || aKey == EStdKeySpace)
+        && (aLength == EShortKeyPress) )
+        {
+        if ( keystrokeLength == 0 )
+            {
+            iOwner->FepMan()->TryCloseUiL();
+            CommitToneMarkL( aKey );
+            return ETrue;
+            }
+        
+        if ( keystrokeLength < KMaxKeystrokeCount && 
+            !CheckToneMarkBorderUpon() )
+            {
+            if ( editPane->GetEffictiveLength() == keystrokeLength )
+            	{
+            	TBool isToneValid = ptiengine->SetToneMark(aKey);
+				TInt stringAfterLength =
+						ptiengine->GetPhoneticSpelling(1).Length();
+				TPtrC ptr = ptiengine->GetPhoneticSpelling(1);
+				TInt spellSepLen = 0;
+				TInt keySepLen = 0;
+				for (TInt i = 0; i < stringAfterLength; i++)
+					{
+					if (ptr.Mid(i, 1).Compare(KSep) == 0)
+            		{
+            		spellSepLen++;
+            		}
+            	}
+            for ( TInt j = 0; j < keystrokeLength; j++ )
+            	{
+            	if ( keystroke->MdcaPoint( j ).Compare(KSep) == 0 )
+            		{
+						keySepLen++;
+						}
+					}
+
+				// +1 is for we had add tone mark to engine, perhaps it is legal, but 
+				// We had not add it to keystroke array
+				if ((stringAfterLength - spellSepLen) == (keystrokeLength
+						- keySepLen + 1) && isToneValid)
+					{
+					inputPane->SetFlag(MAknFepUICtrlInputPane::EPhoneticChanged);
+
+					UIContainer()->ShowHorizontalScrollArrows(EFalse);
+					UIContainer()->ShowVerticalScrollArrows(ETrue);
+					SetInputPaneToneMark();
+					editPane->AddEffictiveLength();
+					}
+				}      
+
+            TBuf<KKeystrokeMaxLength> buf;
+            TAknFepInputStateMiniQwertyZhuyinKeyMap::GetKeyStroke(
+            		ptiengine, aKey, buf );
+            keystroke->AppendL( buf );
+            keycodeArray->AppendL( aKey );
+            ImplicitlyUpdateSelection();
+            }
+        else
+            {
+            UpdateIndicator();
+            iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+            }
+
+        }
+    else if ( CAknFepFnKeyManager::EFnKeyNext == iOwner->FepMan()->FnKeyState() || CAknFepFnKeyManager::EFnKeyLock
+        == iOwner->FepMan()->FnKeyState() || CAknFepFnKeyManager::EFnKeyDown
+        == iOwner->FepMan()->FnKeyState() )
+        {
+        iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+        }
+    else if ( iOwner->FepMan()->IsFlagSet( CAknFepManager::EFlagShiftKeyDepressed )
+        || iOwner->FepMan()->IsFlagSet( CAknFepManager::EFlagQwertyChrKeyDepressed )
+        || ((aKey == EStdKeyLeftFunc) && aLength == EShortKeyPress) )
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        ret = EFalse;
+        }
+    else if ( aKey == EKeyLeftShift || aKey ==EKeyLeftCtrl || aKey
+        == EKeyRightCtrl || aKey ==EKeyRightFunc )
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        ret = EFalse;
+        }
+    else if ( aKey == EStdKeyBackspace )
+        {
+        TBool state = ETrue;
+        if ( editPane->IsChangeState() && aLength == ELongKeyPress )
+            {
+            state = EFalse;
+            }
+        else
+            {
+            editPane->SetChangeState( EFalse );
+            }
+        if ( state )
+            {
+            if ( editPane->GetEffictiveLength() == keystrokeLength )
+                {
+                if ( iOwner->PtiEngine()->DeleteKeyPress().Length() && keystrokeLength != 1 )
+                    {
+                    editPane->DecEffictiveLength();
+                    keystroke->Delete( keystrokeLength - 1 );
+                    keycodeArray->Remove( keystrokeLength - 1 );
+                    inputPane->SetFlag( MAknFepUICtrlInputPane::EPhoneticChanged );
+                    ImplicitlyUpdateSelection();
+                    }
+                else
+                    {
+                    ClearDeliberateSelection();
+                    iOwner->FepMan()->TryCloseUiL(); //no more keys, close the UI.
+                    if ( aLength == ELongKeyPress )
+                        {
+                        iOwner->FepMan()->SetLongClearAfterCloseUI( ETrue );
+                        }
+                    }
+                }
+            else
+                {
+                keystroke->Delete( keystrokeLength - 1 );
+                keycodeArray->Remove( keystrokeLength - 1 );
+                ImplicitlyUpdateSelection();
+                }
+            }
+        }
+    else if ( aKey ==EStdKeyDevice1 )//sk2
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        }
+    else if ( aKey == EStdKeyRightArrow )
+        {
+        if ( popup->IsEnabled() )
+            {
+            if ( popup->SelectNextPhrase() )
+                {
+                DeliberatelyUpdateSelection();
+                UpdateIndicator();
+                }
+            }
+        }
+    else if ( aKey == EStdKeyLeftArrow )
+        {
+        if ( popup->IsEnabled() )
+            {
+            if ( popup->SelectPrevPhrase() )
+                {
+                DeliberatelyUpdateSelection();
+                UpdateIndicator();
+                }
+            }
+        }
+    else if ( aKey == EStdKeyDownArrow || aKey == EStdKeyDevice3 || aKey
+        == EStdKeyDevice0 )//selection key
+        {
+        editPane->SetChangeState( ETrue );
+        if ( editPane->GetEffictiveLength() == keystroke->Count()
+            && ptiengine->PhoneticSpellingCount()
+                > popup->CurrentSelection() )
+            {
+            if ( popup->IsEnabled() )
+                {
+                popup->Enable( EFalse );
+                }
+            iOwner->ChangeState( ECandidate );
+            }
+        else
+            {
+            if ( keystrokeLength > 0 && keystroke->MdcaPoint( 0 )[0] == KSai )
+                {
+                UIContainer()->SetControlInVisible( EFalse );
+                iOwner->ChangeState( EMiniQwertyEdit );
+                }
+            else
+                {
+                ClearDeliberateSelection();
+                editPane->SetNeedClearDeliberateSelection( ETrue );
+                iOwner->ChangeState( EZhuyinSpelling );
+                }
+            }
+        }
+    else if ( aKey == EStdKeyEnter )//enter the characters in the entry pane into the editor
+        {
+        TInt currentIndex = uiContainer->PinyinPopupWindow()->CurrentSelection();
+        TBuf<KInputPaneLength> currentText;
+        if ( currentIndex < ptiengine->PhoneticSpellingCount() )
+            {
+            currentText.Copy(ptiengine->GetPhoneticSpelling( currentIndex + 1 ));
+            }
+        else
+            {
+            inputPane->GetText( currentText );
+            }
+        
+
+        while (currentText.Find( KSep )> 0 )
+            {
+            currentText.Replace( currentText.Find( KSep ), 1, KReplace );
+            }
+        while (currentText.Find( KLeftBracket ) >= 0 )
+            {
+            currentText.Replace( currentText.Find( KLeftBracket ), 1,
+                KReplace );
+            }
+        while (currentText.Find( KRightBracket ) >= 0 )
+            {
+            currentText.Replace( currentText.Find( KRightBracket ), 1,
+                KReplace );
+            }
+
+        if ( currentText.Length() )
+            {
+            MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+            fepMan->NewTextL( currentText );
+            fepMan->CommitInlineEditL();
+            if ( fepMan->IsFlagSet( CAknFepManager::EFlagEditorFull ) )
+                {
+                fepMan->ClearFlag( CAknFepManager::EFlagEditorFull );
+                }
+            }
+
+        iOwner->FepMan()->TryCloseUiL();
+
+        }
+    else if ( aLength == EShortKeyPress ) // don't want repeats on these keys
+        {
+        iOwner->FepMan()->SetCcpuFlag( CAknFepManager::ECcpuStateIgnoreStarUp );
+
+        if ( keystroke->Count() < KMaxKeystrokeCount
+            && (iOwner->IsValidChineseInputKeyQwerty( aKey ) || aKey
+                ==EStdKeySpace ) ) //seperator
+            {
+            TInt stringBeforeLength(0);
+            TInt stringAfterLength(0);
+
+            stringBeforeLength = ptiengine->GetPhoneticSpelling(1).Length();
+            stringAfterLength = ptiengine->AppendKeyPress((TPtiKey)aKey).Length();
+
+            if ( stringBeforeLength != stringAfterLength )
+                {
+                if ( ptiengine->GetPhoneticSpelling(1).Length() == 1 )
+                    {
+                    iOwner->FepMan()->UpdateCbaL( R_AKNFEP_SOFTKEYS_OK_SELECT_CANCEL );
+                    }
+                editPane->AddEffictiveLength();
+                }
+
+            TBuf<KKeystrokeMaxLength> buf;
+            TAknFepInputStateMiniQwertyZhuyinKeyMap::GetKeyStroke(
+            		ptiengine, aKey, buf );
+            keystroke->AppendL( buf );
+            keycodeArray->AppendL( aKey );
+
+            ImplicitlyUpdateSelection();
+            }
+        else
+            {
+            iOwner->FepMan()->PlaySound( EAvkonSIDErrorTone );
+            }
+        }
+    return ret;
+    }
+
+TBool TAknFepInputStateEntryMiniQwertyZhuyinPhrase::HandleKeyForHalfAndCustomQwertyL( TInt aKey,
+    TKeyPressLength aLength )
+    {
+    CPtiEngine* ptiengine = iOwner->PtiEngine();
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlInputPane* inputPane = uiContainer->InputPane();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+
+    TBool ret = ETrue;
+
+    if((aKey == EPtiKeyQwertyE || 
+        aKey == EPtiKeyQwertyR || 
+        aKey == EPtiKeyQwertyY || 
+        aKey == EPtiKeyQwertyU ||
+        aKey == EStdKeySpace) && 
+        (aLength == EShortKeyPress))        
+        {
+        if(ptiengine->SetToneMark(aKey))
+            {
+            inputPane->SetFlag(MAknFepUICtrlInputPane::EPhoneticChanged);
+            
+            TBool multiplePages = !(uiContainer->CandidatePane()->IsLastPage() &&
+                                    uiContainer->CandidatePane()->IsFirstPage());
+            TInt bufLength = ptiengine->CandidatePage().Length();
+            TBool showHorizontalScrollArrows = multiplePages || bufLength>1;
+            
+            UIContainer()->ShowHorizontalScrollArrows(showHorizontalScrollArrows);
+            UIContainer()->ShowVerticalScrollArrows(multiplePages);
+            SetInputPaneToneMark();
+            ImplicitlyUpdateSelection();
+            }
+        }
+    if(( aKey == EStdKeyLeftFunc) && aLength == EShortKeyPress)     //chr key to tone mark   
+        {
+        if(ptiengine->IncrementToneMark(ETrue))
+            {
+            ImplicitlyUpdateSelection();
+            }
+        }
+    else if( CAknFepFnKeyManager::EFnKeyNext == iOwner->FepMan()->FnKeyState() ||
+        CAknFepFnKeyManager::EFnKeyLock == iOwner->FepMan()->FnKeyState() ||
+        CAknFepFnKeyManager::EFnKeyDown == iOwner->FepMan()->FnKeyState())
+        {
+        iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+        }                                               
+    else if (iOwner->FepMan()->IsFlagSet(CAknFepManager::EFlagShiftKeyDepressed)||
+             iOwner->FepMan()->IsFlagSet(CAknFepManager::EFlagQwertyChrKeyDepressed))
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        ret = EFalse;
+        }
+    else if (aKey == EKeyLeftShift || aKey ==EKeyLeftCtrl || aKey == EKeyRightCtrl)      
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        ret = EFalse;
+        }
+    else if (aKey ==EKeyRightFunc)//fn
+        {
+        iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+        }        
+    else if(aKey == EStdKeyBackspace )
+        {
+        if (iOwner->PtiEngine()->DeleteKeyPress().Length())
+            {
+            ImplicitlyUpdateSelection();
+            }
+        else
+            {
+            ClearDeliberateSelection();
+            iOwner->FepMan()->TryCloseUiL(); //no more keys, close the UI.
+            if (aLength == ELongKeyPress)
+                {
+                iOwner->FepMan()->SetLongClearAfterCloseUI(ETrue);
+                }
+            }
+        } 
+    else if(aKey ==EStdKeyDevice1)//sk2
+        {
+        iOwner->FepMan()->TryCloseUiL();
+        }
+    else if(aKey == EStdKeyRightArrow)
+        {
+        if(popup->IsEnabled())
+            {
+            if(popup->SelectNextPhrase())
+                {
+                DeliberatelyUpdateSelection();
+                }
+            }
+        }
+    else if(aKey == EStdKeyLeftArrow)
+        {
+        if(popup->IsEnabled())
+            {
+            if(popup->SelectPrevPhrase())
+                {
+                DeliberatelyUpdateSelection();
+                }
+            }
+        }
+    else if (aKey == EStdKeyDownArrow || aKey == EStdKeyDevice3 || aKey == EStdKeyDevice0)//selection key
+        {
+        if(popup->IsEnabled())
+            {
+            popup->Enable(EFalse);
+            }
+        iOwner->ChangeState(ECandidate);
+        }   
+   else if (aKey == EStdKeyEnter)//enter the characters in the entry pane into the editor
+        {
+        TBuf<KInputPaneLength> currentText;
+        inputPane->GetText(currentText);
+        
+        while(currentText.Find(KSep)> 0)
+            {
+            currentText.Replace(currentText.Find(KSep), 1,KReplace);
+            }
+        
+        
+        if(currentText.Length())
+            {            
+            MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+            fepMan->NewTextL(currentText);
+            fepMan->CommitInlineEditL();
+            if (fepMan->IsFlagSet(CAknFepManager::EFlagEditorFull))
+                {
+                fepMan->ClearFlag(CAknFepManager::EFlagEditorFull);
+                }
+            }
+            
+        iOwner->FepMan()->TryCloseUiL();  
+          
+        }
+    else if(aLength == EShortKeyPress) // don't want repeats on these keys
+        {
+        iOwner->FepMan()->SetCcpuFlag(CAknFepManager::ECcpuStateIgnoreStarUp);            
+        
+        if(iOwner->IsValidChineseInputKeyQwerty(aKey) || aKey ==EStdKeySpace ) //seperator
+            {
+            TInt stringBeforeLength(0);
+            TInt stringAfterLength(0);
+        
+            stringBeforeLength = ptiengine->GetPhoneticSpelling(1).Length();
+            stringAfterLength = ptiengine->AppendKeyPress((TPtiKey)aKey).Length();
+            
+            if (stringBeforeLength != stringAfterLength)
+                {
+                if (ptiengine->GetPhoneticSpelling(1).Length() == 1)
+                    {
+                    //iOwner->FepMan()->UpdateCbaL(R_AVKON_SOFTKEYS_EMPTY);                           iOwner->FepMan()->UpdateCbaL(R_AKNFEP_SOFTKEYS_OK_SELECT_CANCEL);
+                    iOwner->FepMan()->UpdateCbaL(R_AKNFEP_SOFTKEYS_OK_SELECT_CANCEL);
+                    }
+                
+                ImplicitlyUpdateSelection();
+                }
+            
+            else
+                {
+                iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+                }            
+            
+            }
+        else
+            {
+            iOwner->FepMan()->PlaySound(EAvkonSIDErrorTone);
+            }
+        }
+    return ret;
+    }
+
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::CommitToneMarkL( TInt aKey )
+    {
+    TBuf<1> ToneMarkBuf;
+    switch ( aKey )
+        {
+        case EPtiKeyQwertyE:
+            ToneMarkBuf.Append( KToneMark3 );
+            break;
+
+        case EPtiKeyQwertyR:
+            ToneMarkBuf.Append( KToneMark4 );
+            break;
+
+        case EPtiKeyQwertyY:
+            ToneMarkBuf.Append( KToneMark2 );
+            break;
+
+        case EPtiKeyQwertyU:
+            ToneMarkBuf.Append( KToneMark5 );
+            break;
+        default:
+            break;
+        }
+    MAknFepManagerUIInterface* fepMan = iOwner->FepMan();
+    fepMan->NewCharacterL(ToneMarkBuf);
+    fepMan->CommitInlineEditL();
+    if (fepMan->IsFlagSet(CAknFepManager::EFlagEditorFull))
+        {
+        fepMan->ClearFlag(CAknFepManager::EFlagEditorFull);
+        iOwner->FepMan()->TryCloseUiL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// TAknFepInputStateEntryMiniQwertyZhuyinPhrase::HandleCommandL
+// Handling Command
+// ---------------------------------------------------------------------------
+//
+void TAknFepInputStateEntryMiniQwertyZhuyinPhrase::HandleCommandL(
+    TInt aCommandId )
+    {
+    MAknFepUICtrlContainerChinese* uiContainer = UIContainer();
+    MAknFepUICtrlPinyinPopup* popup = uiContainer->PinyinPopupWindow();
+    switch ( aCommandId )
+        {
+        // Handle the event frome command.
+        case EAknSoftkeySelect:
+            //     case (TUint16)EAknSoftkeySelect: //the Selected in soft CBA
+            if ( popup->IsEnabled() )
+                {
+                popup->Enable( EFalse );
+                }
+            iOwner->ChangeState( ECandidate );
+            break;
+        default:
+            TAknFepInputStateChineseBase::HandleCommandL( aCommandId );
+            break;
+        }
+    }
+// End of file   
+