textinput/peninputhwrboxcn/src/peninputhwrengine.cpp
branchRCL_3
changeset 21 ecbabf52600f
parent 0 eb1f2e154e89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textinput/peninputhwrboxcn/src/peninputhwrengine.cpp	Wed Sep 01 12:23:33 2010 +0100
@@ -0,0 +1,717 @@
+/*
+* Copyright (c) 2002-2005 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:  Implementation of HWR engine
+*
+*/
+
+
+#include <AknFepGlobalEnums.h>
+#include <aknfeppeninputenums.h>
+#include <PtiHwrRecognizer.h>
+
+#include "peninputhwrengine.h"
+#include "peninputhwrbxdatastore.h"
+
+// constant definition
+const TInt KInvalidStrokeEndMarkX = -65536;
+const TInt KInvalidStrokeEndMarkY = -65536;
+
+//const TInt KMaxPredictiveCount = 50;
+const TInt K1PagePredictiveCount = 36;
+const TUint16 KGestureSpace = 0xF800;
+const TUint16 KGestureEnter = 0xF801;
+const TUint16 KSegment = 0x0020;
+const TUint16 KGestureBackspace = 0x2408;
+const TUint16 KDisplayBackspace = 0x2190;
+const TInt KPremaryCandidateCount = 13;
+const TInt KAuxCandidateCount = 1;
+
+_LIT(KNumberSet,"0123456789");
+_LIT(KSeparator,"\0");
+_LIT(KDash,"-");
+_LIT(KSolidus,"/");
+
+// ---------------------------------------------------------
+// Symbian constructor
+// ---------------------------------------------------------
+//
+CAknFepHwrEngine* CAknFepHwrEngine::NewL(CPtiEngine* aPtiEngine, CAknFepHwrBxDataStore* aOwner)
+    {
+    CAknFepHwrEngine* self = new (ELeave) CAknFepHwrEngine();
+    
+    CleanupStack::PushL(self);
+    self->ConstructL(aPtiEngine, aOwner);
+    CleanupStack::Pop(self);//self
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// C++ constructor
+// ---------------------------------------------------------
+//
+CAknFepHwrEngine::CAknFepHwrEngine():iRecognizerInited(EFalse),
+                                     iNeedSetNumberMode(EFalse),
+                                     iNeedSetCase(EFalse),
+                                     iNeedSetRange(EFalse)
+    {
+    }
+
+// ---------------------------------------------------------
+// destructor
+// ---------------------------------------------------------
+//
+CAknFepHwrEngine::~CAknFepHwrEngine()
+    {
+    if(iOwnPtiEngine)
+        {
+        delete iPtiEngine;
+        }
+    delete iCustomKeymap;
+    
+    delete iIdle;
+    
+    iPermittedRanges.Reset();
+    iPermittedRanges.Close();
+    }
+
+// ---------------------------------------------------------
+// Second phase constructor
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::ConstructL(CPtiEngine* aPtiEngine, CAknFepHwrBxDataStore* aOwner)
+    {
+    iPtiEngine = aPtiEngine;
+
+    if( !iPtiEngine )
+        {
+        iPtiEngine = CPtiEngine::NewL(ETrue);
+        iOwnPtiEngine = ETrue;
+        }
+
+    iIdle = CIdle::NewL(CActive::EPriorityIdle);
+    iOwner = aOwner;
+    }
+
+// ---------------------------------------------------------
+// Convert stroke end mark
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::ConvertStrokeEndMark(RArray<TPoint>& aTraceData, TPoint aPnt1, TPoint aPnt2)
+    {
+    TInt count = aTraceData.Count();
+
+    for (TInt i = 0; i < count; i++)
+        {
+    	if (aTraceData[i] == aPnt1)
+    	    {
+    		aTraceData.Remove(i);
+    		aTraceData.Insert(aPnt2, i);
+    	    }
+        }
+    }
+
+// ---------------------------------------------------------
+// Do recoginize by engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::DoRecognizeL(const RArray<TPoint>& aTraceData,
+                                    RPointerArray<HBufC>& aCandidates)
+    {
+    if (!iRecognizer)
+        {
+        return;
+        }
+        
+    TPoint ctrlStrokeEndMark = iOwner->StrokeEndMarkFromControl();
+    
+    if (!iRecognizerInited)
+        {
+        DoIdleConstructL();
+        }
+        
+    if (ctrlStrokeEndMark != iRecognizer->StrokeEndMark())
+        {
+        ConvertStrokeEndMark(CONST_CAST(RArray<TPoint>&, aTraceData), 
+                             iOwner->StrokeEndMarkFromControl(), 
+                             iRecognizer->StrokeEndMark());
+        iOwner->SetStrokeEndMark(); // make control's stroke end mark info same to engine
+        }
+    
+    aCandidates.ResetAndDestroy();
+    
+    TInt primaryCount;  
+    TBuf<1> bufBackspace;
+    bufBackspace.Append(KGestureBackspace);
+    TBuf<1> bufDisplayBackspace;
+    bufDisplayBackspace.Append(KDisplayBackspace);
+        
+    if (iOwner->IsNumberOnly())
+        {     
+        if ( iNumberMode == EAknEditorPlainNumberModeKeymap )
+            {
+            TBuf<1> bufEnter;
+            bufEnter.Append( KGestureEnter );
+            TBuf<1> bufSpace;
+            bufSpace.Append( KGestureSpace );
+            
+            TBuf<13> buf;
+            buf.Append( KNumberSet() );
+            buf.Append( bufBackspace );
+            buf.Append( bufEnter );
+            buf.Append( bufSpace );
+            primaryCount = iRecognizer->RecognizeWithCharSet(
+                aTraceData, aCandidates, buf );
+            }
+        else
+            {
+            primaryCount = iRecognizer->Recognize(aTraceData, aCandidates);
+            }
+        
+        for ( TInt i = aCandidates.Count() - 1; i >= 0; i-- )
+            {
+            if (aCandidates[i]->Compare(bufBackspace) == 0)
+            	{
+                *aCandidates[i] = bufDisplayBackspace;
+            	}
+            }
+        
+        if (iCustomKeymap)
+            {
+            for(TInt i=0; i<aCandidates.Count(); i++)
+                {
+                if( iCustomKeymap->Find(*aCandidates[i]) == KErrNotFound )
+                    {
+                    delete aCandidates[i];
+    		    	aCandidates.Remove(i);
+    		    	primaryCount--;
+    		    	i--;
+                    }
+                }
+            }
+                	
+        for (TInt i = 0; i < primaryCount-iTotalCandidateNum; i++)
+            {
+            delete aCandidates[iTotalCandidateNum];
+            aCandidates.Remove(iTotalCandidateNum);
+            }
+        return;
+        }
+
+    primaryCount = iRecognizer->Recognize(aTraceData, aCandidates); 
+    
+    // remove uncessary primary candidate
+    TInt removePos = iTotalCandidateNum - (iRangeCount - 1);        
+    if (removePos >= 0)
+        {
+        for (TInt i = 0; i < primaryCount - removePos; i++)
+            {
+            delete aCandidates[removePos];
+            aCandidates.Remove(removePos);
+            }
+        }     
+
+    // filter recognized candidate, set start position for all ranges    
+    TPtrC ptr(KSeparator);
+    
+    // remove uncessary aux candidate, including range separator 
+    for (TInt i=0; i<aCandidates.Count(); i++)
+        {
+        if (aCandidates[i]->Compare(bufBackspace) == 0)
+        	{
+        	// convert backspace returned by engine, to make sure it display correctly.
+            *aCandidates[i] = bufDisplayBackspace;
+        	}
+        
+        else if ( (aCandidates[i]->CompareC(ptr) == 0) )
+            {
+            // remove separator from candidate list
+            delete aCandidates[i];
+            aCandidates.Remove(i);
+            }
+        }
+    
+    TPtrC dashPtr(KDash);
+    TPtrC solidusPtr(KSolidus);
+    
+    // not allowing '-' to be the first char in chinese range 
+    // not allowing '/' to be the first char in English and Number range 
+    if ( ( iPremaryRange == ERangeNative ) && (aCandidates[0]->Compare(dashPtr) == 0) )
+        {
+        *aCandidates[0] = *aCandidates[1];
+        *aCandidates[1] = dashPtr;
+        }
+    else if ( ( (iPremaryRange == ERangeEnglish)||(iPremaryRange == ERangeNumber) ) 
+        && (aCandidates[0]->Compare(solidusPtr) == 0) )
+        {
+        *aCandidates[0] = *aCandidates[1];
+        *aCandidates[1] = solidusPtr;
+        }
+    }
+
+// ---------------------------------------------------------
+// Judge if candidate exist in given position
+// ---------------------------------------------------------
+//
+TBool CAknFepHwrEngine::CandidateExisted()
+    {
+	return iPtiEngine->MoreCandidatePages();
+    }
+
+// ---------------------------------------------------------
+// Do predictive using trigger string
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::DoPredictiveL(const TDesC& aTriggerStr, 
+                                     RPointerArray<HBufC>& aPredictives,
+                                     TBool aNextPage)
+    {
+    // predictive only valid for Chinese
+    if (((iLanguage == ELangPrcChinese) || 
+        (iLanguage == ELangTaiwanChinese) || 
+        (iLanguage == ELangHongKongChinese)) &&
+        (iPtiEngine))
+        {
+        // activate correct pti language according to given language
+        
+        if (!aNextPage)
+            {
+        	iPtiEngine->SetCandidatePageLength(K1PagePredictiveCount);
+        	aPredictives.ResetAndDestroy();
+        	
+        	if(!iPtiEngine->SetPredictiveChineseChar(aTriggerStr))
+        	    {
+        	    return;
+        	    }
+            }
+        else
+            {
+            if (!iPtiEngine->NextCandidatePage())
+                {
+            	return;
+                }
+            }
+            
+        TPtrC ptr = iPtiEngine->CandidatePage();    
+        
+        if ((iPtiEngine->InputMode() == EPtiEnginePinyinByPhrase) || 
+            (iPtiEngine->InputMode() == EPtiEngineStrokeByPhrase) ||
+            (iPtiEngine->InputMode() == EPtiEngineZhuyinByPhrase))
+        	{
+        	// phrase input mode
+            TInt start = 0;
+            TInt length = 0;
+        	
+            for (TInt i = 0; i <ptr.Length(); i++)
+                {
+                if (ptr[i] == KSegment)
+                    {
+                    TPtrC segment(ptr.Ptr() + start, length);
+                    TRAP_IGNORE(aPredictives.AppendL(segment.AllocL()));
+                    start += (length + 1);
+                    length = 0;
+                    }
+                else
+                    {
+                    length++;               
+                    }
+                }
+
+            if (length)
+                {
+                TPtrC segm(ptr.Ptr() + start, length);
+                TRAP_IGNORE(aPredictives.AppendL(segm.AllocL()));
+                }
+        	}
+        else
+            {
+            TInt predictiveCandidateNum = ptr.Length();
+
+            for (TInt i=0; i<predictiveCandidateNum; i++)
+                {
+                aPredictives.Append(ptr.Mid(i,1).AllocL());
+                }
+            }	
+        }
+    }
+
+// ---------------------------------------------------------
+// Set primary and auxiliary ranges for hwr engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetRanges(const RArray<TInt>& aPermittedRanges)
+    {
+    if (!iRecognizerInited)
+        {
+    	iNeedSetRange = ETrue;
+    	iPermittedRanges.Reset();
+    	
+    	for (TInt i = 0; i < aPermittedRanges.Count(); i++)
+    	    {
+            iPermittedRanges.Append(aPermittedRanges[i]);
+    	    }
+    	
+    	return;    
+        }
+
+    if ((aPermittedRanges.Count() > 0) && (iRecognizer))
+        {
+        iPremaryRange = aPermittedRanges[0];
+        iRangeCount = aPermittedRanges.Count();
+
+        TRecognitionRange range;
+
+        SetRecognitionRange(aPermittedRanges[0], range);
+        iRecognizer->SetRange(range);
+
+        // set auxiliary ranges for hwr engine
+        for (TInt i=1; i<aPermittedRanges.Count(); i++)
+            {
+            SetRecognitionRange(aPermittedRanges[i], range);
+
+            iRecognizer->AddAuxiliaryRange(range);
+            }
+        
+        SetCase(iCase);
+        }
+    }
+    
+// ---------------------------------------------------------
+// Set case
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetCase(TInt aCase)
+    {
+    if (!iRecognizerInited)
+        {
+    	iNeedSetCase = ETrue;
+    	iCase = aCase;
+    	return;
+        }
+    
+    // set letter to lower first when LowerCase
+    // set letter to upper first when UpperCase and TextCase
+    if (iRecognizer)
+        {
+        if (aCase == ELowerCase)
+            {
+            iRecognizer->SetFirstLetterOrder(ELowerFirst);
+            }
+        else
+            {
+            iRecognizer->SetFirstLetterOrder(EUpperFirst);
+            }
+        
+        iCase = aCase;
+        }
+    }
+
+// ---------------------------------------------------------
+// Set number mode for hwr engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetNumberMode(const TAknEditorNumericKeymap& aNumberMode)
+    {
+    iNumberMode = aNumberMode;
+    
+    if (!iRecognizerInited)
+        {
+        iNeedSetNumberMode = ETrue;
+    	
+    	return;
+        }
+
+    if (iRecognizer)
+        {
+        iRecognizer->SetNumberMode(aNumberMode);
+        if( aNumberMode !=  EKeymapFromResource)
+            {
+            ResetCustomKeyMap();
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// Get stroke end mark from hwr engine
+// ---------------------------------------------------------
+//
+TPoint CAknFepHwrEngine::StrokeEndMark() const
+    {
+    if (iRecognizer)
+        {
+        return iRecognizer->StrokeEndMark();
+        }
+    else
+        {
+        return TPoint(KInvalidStrokeEndMarkX, KInvalidStrokeEndMarkY);
+        }
+    }
+
+// ---------------------------------------------------------
+// Set primary candidate num for hwr engine
+// ---------------------------------------------------------
+//
+TInt CAknFepHwrEngine::SetPrimaryCandidateNum(TInt aNum)
+    {
+    if (iRecognizer)
+        {
+        return iRecognizer->SetCandidateNum(aNum);
+        }
+    else
+        {
+        return KErrGeneral;
+        }
+    }
+
+// ---------------------------------------------------------
+// Set aux candidate num that should be shown
+// ---------------------------------------------------------
+//
+TInt CAknFepHwrEngine::SetAuxCandidateNum(TInt aNum)
+    {
+    if (iRecognizer)
+        {
+        return iRecognizer->SetAuxCandidateNum(aNum);
+        }
+    else
+        {
+        return KErrGeneral;
+        }
+    }
+
+
+// ---------------------------------------------------------
+// Get aux candidate num that should be shown
+// ---------------------------------------------------------
+//
+TInt CAknFepHwrEngine::GetAuxCandidateNum()
+    {
+    if (iRecognizer)
+        {
+        return iRecognizer->GetAuxCandidateNum();
+        }
+    else
+        {
+        return KErrGeneral;
+        }
+    }
+        
+// ---------------------------------------------------------
+// Set total candidate num that should be shown
+// ---------------------------------------------------------
+//
+TInt CAknFepHwrEngine::SetCandidateNum(TInt aNum)
+    {
+    if (aNum > 0)
+        {
+        iTotalCandidateNum = aNum;
+        return KErrNone;
+        }
+    else
+        {
+        return KErrGeneral;
+        }    
+    }
+    
+// ---------------------------------------------------------
+// Set language
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetLanguageL(TInt aLanguage)
+    {
+    if ( (iLanguage == aLanguage) ||
+         (aLanguage != ELangPrcChinese && 
+          aLanguage != ELangHongKongChinese && 
+          aLanguage != ELangTaiwanChinese) )
+        {
+        return;
+        }
+        
+    iLanguage = aLanguage;
+  switch (iLanguage)
+    {
+    case ELangPrcChinese:
+        {
+        if (iPtiEngine->ActivateLanguageL(iLanguage, EPtiEnginePinyinByPhrase) != KErrNone)
+        	{
+        	iPtiEngine->ActivateLanguageL(iLanguage, EPtiEnginePinyin);
+        	}
+        }
+        break;
+    case ELangHongKongChinese:
+        if (iPtiEngine->ActivateLanguageL(iLanguage, EPtiEngineStrokeByPhrase) != KErrNone)
+        	{
+        	iPtiEngine->ActivateLanguageL(ELangHongKongChinese, EPtiEngineStroke);
+        	}
+        break;
+    case ELangTaiwanChinese:
+        if (iPtiEngine->ActivateLanguageL(iLanguage, EPtiEngineZhuyinByPhrase) != KErrNone)
+        	{
+        	iPtiEngine->ActivateLanguageL(ELangTaiwanChinese, EPtiEngineZhuyin);
+        	}
+        break;
+    default:
+        return;
+    }
+
+    iRecognizerInited = EFalse;
+    
+    iIdle ->Start(TCallBack(BackgroundTaskL,this));
+    }
+    
+// ---------------------------------------------------------------------------
+// CAknFepHwrEngine::DoIdleConstructL
+// Do background construct.
+// ---------------------------------------------------------------------------
+//
+void CAknFepHwrEngine::DoIdleConstructL()
+    {
+    if (iRecognizerInited)
+        {
+        return;
+        }
+
+	iRecognizer = iPtiEngine->GetHwrRecognizerL(TLanguage(iLanguage));
+	iRecognizerInited = ETrue;
+	iOwner->SetStrokeEndMark();
+	SetPrimaryCandidateNum(KPremaryCandidateCount);
+	SetAuxCandidateNum(KAuxCandidateCount);
+	
+    if (iNeedSetRange)
+        {
+        SetRanges(iPermittedRanges);
+        iNeedSetRange = EFalse;
+        iPermittedRanges.Reset();
+        }
+    
+    if (iNeedSetCase)
+        {
+    	SetCase(iCase);
+    	iNeedSetCase = EFalse;
+        }
+    
+    if (iNeedSetNumberMode)
+        {
+    	SetNumberMode(TAknEditorNumericKeymap(iNumberMode));
+    	iNeedSetNumberMode = EFalse;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CAknFepHwrEngine::BackgroundConstructL
+// Do background construct.
+// ---------------------------------------------------------------------------
+//
+TInt CAknFepHwrEngine::BackgroundTaskL(TAny* aPtr)
+    {
+    CAknFepHwrEngine* self = static_cast<CAknFepHwrEngine*>(aPtr);
+    self->DoIdleConstructL();
+    return EFalse;
+    }
+    
+// ---------------------------------------------------------
+// Set recognition range for hwr engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetRecognitionRange(const TInt aRange, TRecognitionRange& aRecognitionRange)
+    {
+    aRecognitionRange.iLanguage = TLanguage(iLanguage);
+
+    switch (aRange)
+        {
+        case ERangeNative:
+
+            if (iLanguage == ELangPrcChinese)
+                {
+                aRecognitionRange.iSubRange = EPtiRangePRCChinese;
+                }
+            else
+                {
+                if (iLanguage == ELangHongKongChinese)
+                    {
+                    aRecognitionRange.iSubRange = EPtiRangeHKChinese;
+                    }
+                else
+                    {
+                    aRecognitionRange.iSubRange = EPtiRangeTWChinese;
+                    }
+                }
+
+            break;
+        case ERangeEnglish:
+            aRecognitionRange.iLanguage = ELangEnglish;
+            aRecognitionRange.iSubRange = EPtiRangeLatin;
+
+            break;
+        case ERangeNumber:
+            aRecognitionRange.iSubRange = EPtiRangeNumber;
+
+            break;
+        case ERangeSymbol:
+            // The symbol mode is associated with iLanguage instead of iPremaryRange
+            aRecognitionRange.iLanguage = TLanguage(iLanguage);
+            aRecognitionRange.iSubRange = EPtiRangeSymbol;
+
+            break;
+        default:
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// Set recognition range for hwr engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::SetCustomKeymapL(const TDesC& aKeyMap)
+    {
+    delete iCustomKeymap;
+    iCustomKeymap = NULL;
+    iCustomKeymap = HBufC::NewL(aKeyMap.Length() + KNumberSet().Length());
+    iCustomKeymap->Des().Copy(KNumberSet());
+    iCustomKeymap->Des().Append(aKeyMap);
+    }
+
+// ---------------------------------------------------------
+// Set recognition range for hwr engine
+// ---------------------------------------------------------
+//
+void CAknFepHwrEngine::ResetCustomKeyMap()
+    {
+    delete iCustomKeymap;
+    iCustomKeymap = NULL;
+    }
+TInt CAknFepHwrEngine::SetInputAreaSize(TSize& aSize)
+    {
+    if(iRecognizer)
+        {
+        return iRecognizer->SetInputAreaSize(aSize);        
+        }
+    else
+        {
+        return KErrNotFound;
+        }        
+    }
+TInt CAknFepHwrEngine::SetScreenSize(TSize& aSize)    
+    {
+      if(iRecognizer)
+        {
+        return iRecognizer->SetScreenSize(aSize);        
+        }
+    else
+        {
+        return KErrNotFound;
+        }  
+    }
+    
+//End Of File