textinput/peninputhwrfscn/src/peninputhwrengine.cpp
changeset 0 eb1f2e154e89
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of HWR engine
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //FEP INCLUDES
       
    20 #include <AknFepGlobalEnums.h>
       
    21 #include <aknfeppeninputenums.h>
       
    22 #include <PtiHwrRecognizer.h>
       
    23 
       
    24 //USER INCLUDES
       
    25 #include "peninputhwrengine.h"
       
    26 #include "peninputhwrfscndatastore.h"
       
    27 
       
    28 // CONSTANT DEFINITION HEADER
       
    29 #include "peninputhwrfscnstoreconstants.h"
       
    30 
       
    31 // ---------------------------------------------------------------------------
       
    32 // SplitString()
       
    33 // ---------------------------------------------------------------------------
       
    34 //
       
    35 static TInt SplitString( const TPtrC &aPtr, 
       
    36     TUint16 aSeperator, 
       
    37     RPointerArray<HBufC>& aStringArray )
       
    38 	{
       
    39 	// phrase input mode
       
    40     TInt start = 0;
       
    41     TInt length = 0;
       
    42 	
       
    43     for ( TInt i = 0; i < aPtr.Length(); i++ )
       
    44         {
       
    45         if ( aPtr[i] == aSeperator )
       
    46             {
       
    47             TPtrC segment( aPtr.Ptr() + start, length );
       
    48             TRAP_IGNORE( aStringArray.AppendL( segment.AllocL() ) );
       
    49             start += ( length + 1 );
       
    50             length = 0;
       
    51             }
       
    52         else
       
    53             {
       
    54             length++;               
       
    55             }
       
    56         }
       
    57 
       
    58     if ( length )
       
    59         {
       
    60         TPtrC segm( aPtr.Ptr() + start, length );
       
    61         TRAP_IGNORE( aStringArray.AppendL( segm.AllocL() ) );
       
    62         }
       
    63         
       
    64     return aStringArray.Count();
       
    65 	}
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // Symbian constructor
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 CAknFepHwrEngine* CAknFepHwrEngine::NewL( CPtiEngine* aPtiEngine, 
       
    72     CPeninputHwrfscnDataStore* aOwner )
       
    73     {
       
    74     CAknFepHwrEngine* self = new ( ELeave ) CAknFepHwrEngine();
       
    75     
       
    76     CleanupStack::PushL( self );
       
    77     self->ConstructL( aPtiEngine, aOwner );
       
    78     CleanupStack::Pop( self );//self
       
    79 
       
    80     return self;
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // C++ constructor
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 CAknFepHwrEngine::CAknFepHwrEngine()
       
    88     {
       
    89     iNeedSetNumberMode = EFalse;
       
    90     iNeedSetCase = EFalse;
       
    91     iNeedSetRange = EFalse;
       
    92     iRecognizer = NULL;    
       
    93     iOwnPtiEngine = EFalse;
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // destructor
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 CAknFepHwrEngine::~CAknFepHwrEngine()
       
   101     {
       
   102     if( iOwnPtiEngine )
       
   103         {
       
   104         delete iPtiEngine;
       
   105         }
       
   106     delete iCustomKeymap;
       
   107     
       
   108     delete iIdle;
       
   109     
       
   110     iNeedPermittedRanges.Close();
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------------------------
       
   114 // Second phase constructor
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 void CAknFepHwrEngine::ConstructL( CPtiEngine* aPtiEngine, 
       
   118     CPeninputHwrfscnDataStore* aOwner )
       
   119     {
       
   120     if( !aPtiEngine )
       
   121         {
       
   122         iPtiEngine = CPtiEngine::NewL( ETrue );
       
   123         iOwnPtiEngine = ETrue;
       
   124         }
       
   125     else
       
   126     	{
       
   127     	iPtiEngine = aPtiEngine;
       
   128     	}
       
   129 
       
   130     iIdle = CIdle::NewL( CActive::EPriorityIdle );
       
   131     iOwner = aOwner;
       
   132     }
       
   133 
       
   134 // ---------------------------------------------------------------------------
       
   135 // Convert stroke end mark
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 void CAknFepHwrEngine::ConvertStrokeEndMark( RArray<TPoint>& aTraceData, 
       
   139     TPoint aPnt1, TPoint aPnt2 )
       
   140     {
       
   141     TInt count = aTraceData.Count();
       
   142 
       
   143     for ( TInt i = 0; i < count; i++ )
       
   144         {
       
   145     	if ( aTraceData[i] == aPnt1 )
       
   146     	    {
       
   147     		aTraceData.Remove( i );
       
   148     		aTraceData.Insert( aPnt2, i );
       
   149     	    }
       
   150         }
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // Do recoginize by engine
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 void CAknFepHwrEngine::DoRecognizeL( const RArray<TPoint>& aTraceData, 
       
   158     RPointerArray<HBufC>& aCandidates )
       
   159     {
       
   160     if ( !iRecognizer )
       
   161         {
       
   162         DoIdleConstructL();
       
   163         }
       
   164         
       
   165     TPoint ctrlStrokeEndMark = iOwner->StrokeEndMarkFromControl();
       
   166         
       
   167     if ( ctrlStrokeEndMark != iRecognizer->StrokeEndMark() )
       
   168         {
       
   169         ConvertStrokeEndMark( CONST_CAST( RArray<TPoint>&, aTraceData ), 
       
   170             iOwner->StrokeEndMarkFromControl(), 
       
   171             iRecognizer->StrokeEndMark() );
       
   172         iOwner->SetStrokeEndMark(); // make control's stroke end mark info same to engine
       
   173         }
       
   174     
       
   175     aCandidates.ResetAndDestroy();
       
   176     
       
   177     //Do recognition for number only    
       
   178     if ( iOwner->IsNumberOnly() )
       
   179         {     
       
   180         DoRecognizeOfNumberOnly( aTraceData,aCandidates );
       
   181         return;
       
   182         }
       
   183 
       
   184     TInt primaryCount = iRecognizer->Recognize( aTraceData, aCandidates ); 
       
   185 
       
   186     // filter recognized candidate, set start position for all ranges    
       
   187     TPtrC ptr( KSeparator );
       
   188     
       
   189     // remove uncessary aux candidate, including range separator 
       
   190     for ( TInt i=0; i<aCandidates.Count(); i++ )
       
   191         {
       
   192         if ( aCandidates[i]->Compare( KGestureBackspace ) == 0 )
       
   193         	{
       
   194         	// convert backspace returned by engine, to make sure it display correctly.
       
   195             *aCandidates[i] = KDisplayBackspace;
       
   196             break;
       
   197         	}
       
   198         }
       
   199     
       
   200     //reorder the secondary range
       
   201     ReorderSecondaryRange( aCandidates );
       
   202     
       
   203     // remove uncessary primary candidate
       
   204     TInt totallyCount = aCandidates.Count();
       
   205     TInt removePos = iTotalCandidateNum;        
       
   206     
       
   207     for ( TInt i = removePos; i < totallyCount; i++ )
       
   208          {
       
   209          delete aCandidates[removePos];
       
   210          aCandidates.Remove( removePos );
       
   211          } 
       
   212    
       
   213     // not allowing '-' to be the first char in chinese range 
       
   214     // not allowing '/' to be the first char in English and Number range 
       
   215     TPtrC dashPtr( KDash );
       
   216     TPtrC solidusPtr( KSolidus );
       
   217     if ( ( iPremaryRange == ERangeNative ) && 
       
   218         ( aCandidates[0]->Compare( dashPtr ) == 0 ) )
       
   219         {
       
   220         *aCandidates[0] = *aCandidates[1];
       
   221         *aCandidates[1] = dashPtr;
       
   222         }
       
   223     else if ( ( ( iPremaryRange == ERangeEnglish ) || 
       
   224         ( iPremaryRange == ERangeNumber ) ) 
       
   225         && ( aCandidates[0]->Compare( solidusPtr ) == 0 ) )
       
   226         {
       
   227         *aCandidates[0] = *aCandidates[1];
       
   228         *aCandidates[1] = solidusPtr;
       
   229         }
       
   230     }
       
   231 
       
   232 // ---------------------------------------------------------------------------
       
   233 // Do recognition when the range is only number
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 void CAknFepHwrEngine::DoRecognizeOfNumberOnly( const RArray<TPoint>& aTraceData, 
       
   237     RPointerArray<HBufC>& aCandidates )
       
   238     {
       
   239     if ( iNumberMode == EAknEditorPlainNumberModeKeymap )
       
   240         {
       
   241         TBuf<KPlainNumSize> buf;
       
   242         buf.Append( KNumberString() );
       
   243         buf.Append( KGestureBackspace );
       
   244         iRecognizer->RecognizeWithCharSet( aTraceData, aCandidates, buf );
       
   245         }
       
   246     else
       
   247         {
       
   248         iRecognizer->Recognize( aTraceData, aCandidates );
       
   249         }
       
   250         
       
   251     //find special char and do special handling
       
   252     TInt count = aCandidates.Count();
       
   253     for ( TInt i = count - 1; i >= 0; i-- )
       
   254         {
       
   255          //the space and enter are not allowed to be appeared in candidates
       
   256          if( ( *aCandidates[i] )[0] == KGestureSpace()[0] || 
       
   257              ( *aCandidates[i] )[0] == KGestureEnter()[0] )
       
   258              {
       
   259              delete aCandidates[i];
       
   260              aCandidates.Remove( i );
       
   261              }
       
   262          else if( aCandidates[i]->Compare( KGestureBackspace ) == 0 )
       
   263              {
       
   264              *aCandidates[i] = KDisplayBackspace; 
       
   265              }                    
       
   266         }
       
   267     
       
   268     if ( iCustomKeymap )
       
   269         {
       
   270         count = aCandidates.Count();
       
   271         for( TInt i = count - 1; i >= 0; i-- )
       
   272             {
       
   273             if( iCustomKeymap->Find( *aCandidates[i] ) == KErrNotFound )
       
   274                 {
       
   275                 delete aCandidates[i];
       
   276     	    	aCandidates.Remove( i );
       
   277                 }
       
   278             }
       
   279         }
       
   280         
       
   281     // remove uncessary primary candidate
       
   282     count = aCandidates.Count() - iTotalCandidateNum;
       
   283     for ( TInt i = 0; i < count; i++ )
       
   284         {
       
   285         delete aCandidates[iTotalCandidateNum];
       
   286         aCandidates.Remove( iTotalCandidateNum );
       
   287         }
       
   288     }
       
   289 
       
   290 // ---------------------------------------------------------------------------
       
   291 // Reorder secondary range in candidate list
       
   292 // ---------------------------------------------------------------------------
       
   293 //
       
   294 void CAknFepHwrEngine::ReorderSecondaryRange( RPointerArray<HBufC>& aCandidates )
       
   295     {
       
   296     if( iRangeCount <= 1 )
       
   297         {
       
   298         return;
       
   299         }
       
   300 
       
   301     RPointerArray<HBufC> secondary;
       
   302     TInt auxCandidateNum = GetAuxCandidateNum();
       
   303     
       
   304     HBufC* secCandidate = NULL;          
       
   305     TInt candiateCount = aCandidates.Count();
       
   306    
       
   307     TInt primaryCountFromEng = 0;
       
   308     
       
   309     // Get all secondary candidates
       
   310     for( TInt i = 0; i < candiateCount; i++ )// "i" is the index of separater 
       
   311         {
       
   312         if( aCandidates[i]->CompareC( KSeparator ) == 0 )
       
   313             {
       
   314             if(primaryCountFromEng == 0)
       
   315                 {
       
   316                 // Save the primary candidates count from ptiengine
       
   317                 primaryCountFromEng = i;
       
   318                 }
       
   319             TInt auxCountFromEng = 0;
       
   320             while(i < candiateCount - 1 && aCandidates[++i]->CompareC( KSeparator ) != 0)
       
   321                 {
       
   322                 // calculate the secondary range candidate count
       
   323                 auxCountFromEng++;
       
   324                 
       
   325                 // Copy all the secondary candidate to an array
       
   326                 secCandidate = aCandidates[i]->Alloc();
       
   327                 secondary.Append( secCandidate );
       
   328                 }
       
   329             
       
   330             for(TInt j = 0; j < auxCandidateNum - auxCountFromEng ; j++ )
       
   331                 {
       
   332                 // supply empty secondary candidate when engine not return
       
   333                 // enough cell
       
   334                 secondary.Append( KNullDesC().Alloc() );
       
   335                 }
       
   336             i--; // go back to the separator index
       
   337             }
       
   338         }
       
   339 
       
   340    
       
   341     // caculate the primary candidate count
       
   342     TInt primaryCount = 0;
       
   343     TInt rowCount = 0;
       
   344     
       
   345     if( iPremaryRange == ERangeNumber )
       
   346         {
       
   347         primaryCount = KCandidateCountNumMode - iRangeCount + 1;
       
   348         rowCount = 1;
       
   349         }
       
   350     else
       
   351         {
       
   352         primaryCount = KCandidateCountPerRow - iRangeCount + 1;
       
   353         rowCount = KCandidateRowCount;
       
   354         }
       
   355 
       
   356     // supply empty primary candidate when engine not return
       
   357     // enough cell
       
   358     if(primaryCountFromEng < primaryCount * rowCount)
       
   359         {
       
   360         for(TInt y = 0; y < primaryCount * rowCount - primaryCountFromEng; y++)
       
   361             {
       
   362             aCandidates.Insert( KNullDesC().Alloc(), primaryCountFromEng );
       
   363             }
       
   364         }   
       
   365     
       
   366     // insert secondary candidates into the end of each row
       
   367    	for( ; rowCount > 0; rowCount-- )
       
   368         {
       
   369         for( TInt m = 0; m < iRangeCount - 1; m++ )
       
   370             {
       
   371             TInt secondaryIndex = rowCount - 1 + m * auxCandidateNum;
       
   372             TInt insertPos = primaryCount * rowCount + m;
       
   373             aCandidates.Insert( secondary[secondaryIndex], insertPos );
       
   374             }
       
   375         }
       
   376     secondary.Reset();
       
   377     secondary.Close();
       
   378     }
       
   379     
       
   380 
       
   381 // ---------------------------------------------------------------------------
       
   382 // Do predictive using trigger string
       
   383 // ---------------------------------------------------------------------------
       
   384 //
       
   385 void CAknFepHwrEngine::DoPredictiveL( const TDesC& aTriggerStr, 
       
   386     RPointerArray<HBufC>& aPredictives,
       
   387     TBool aNextPage )
       
   388     {
       
   389     // predictive only valid for Chinese
       
   390     if ( ( iLanguage != ELangPrcChinese ) &&
       
   391         ( iLanguage != ELangTaiwanChinese ) && 
       
   392         ( iLanguage != ELangHongKongChinese ) )
       
   393     	{
       
   394     	return;    	
       
   395     	}
       
   396 
       
   397     // activate correct pti language according to given language
       
   398     if ( !aNextPage )
       
   399         {
       
   400     	iPtiEngine->SetCandidatePageLength( KPredictiveCountPerPage );
       
   401     	
       
   402     	aPredictives.ResetAndDestroy();
       
   403     	if( !iPtiEngine->SetPredictiveChineseChar( aTriggerStr ) )
       
   404     		{
       
   405     		return;
       
   406     		}
       
   407         }
       
   408     else
       
   409         {
       
   410         if ( !iPtiEngine->NextCandidatePage() )
       
   411             {
       
   412         	return;
       
   413             }
       
   414         }
       
   415         
       
   416     TPtrC ptr = iPtiEngine->CandidatePage();    
       
   417     
       
   418     if ( ( iPtiEngine->InputMode() == EPtiEnginePinyinVkb ) || 
       
   419         ( iPtiEngine->InputMode() == EPtiEngineStrokeByPhrase ) ||
       
   420         ( iPtiEngine->InputMode() == EPtiEngineZhuyinVkb ) )
       
   421     	{
       
   422     	SplitString( ptr, KSegment, aPredictives );
       
   423     	}
       
   424     else
       
   425         {
       
   426         TInt predictiveCandidateNum = ptr.Length();
       
   427 
       
   428         for ( TInt i=0; i<predictiveCandidateNum; i++ )
       
   429             {
       
   430             aPredictives.Append( ptr.Mid( i,1 ).AllocL() );
       
   431             }
       
   432         }	
       
   433     }
       
   434  
       
   435     
       
   436 // ---------------------------------------------------------------------------
       
   437 // Do homophonic using trigger string
       
   438 // ---------------------------------------------------------------------------
       
   439 //
       
   440 void CAknFepHwrEngine::DoHomophonicL( const TDesC& aTriggerStr, 
       
   441                                       RPointerArray<HBufC>& aHomophonic )
       
   442     {
       
   443     // homophonic only valid for PRC Chinese and Taiwan Chinese
       
   444     if ( ( iLanguage == ELangPrcChinese ) || 
       
   445         ( iLanguage == ELangTaiwanChinese ) )
       
   446         {
       
   447         iPtiEngine->SetCandidatePageLength( KMaxHomophonicCandidateCount );
       
   448         aHomophonic.ResetAndDestroy();
       
   449         
       
   450         // get the spelling of the character
       
   451         TBuf<KMaxSpellingsLettersNum> spelling;
       
   452         TPtiSpelling spellingType = EPtiPinyin;
       
   453         
       
   454         if ( iPtiEngine->InputMode() == EPtiEnginePinyinVkb )
       
   455             {
       
   456             spellingType = EPtiPinyin;
       
   457             }
       
   458         else if ( iPtiEngine->InputMode() == EPtiEngineZhuyinVkb )
       
   459             {
       
   460             spellingType = EPtiZhuyin;
       
   461             }
       
   462         
       
   463         TInt result = iPtiEngine->GetSpelling( aTriggerStr[0], 
       
   464             spelling, spellingType );    
       
   465         if( KErrNone != result )
       
   466             {
       
   467             return;
       
   468             }
       
   469             
       
   470         // get homophonic or polyphonic candidates by spelling    
       
   471         GetHomophonicAndPolyphonic( spelling, aHomophonic );  
       
   472            
       
   473         // delete the repeated characters                                        
       
   474         TInt count = aHomophonic.Count();
       
   475         for ( TInt i = count - 1; i >= 0; i-- )
       
   476             {
       
   477             if ( aTriggerStr == *( aHomophonic[i] ) )
       
   478                 {
       
   479                 delete aHomophonic[i];
       
   480                 aHomophonic.Remove( i );
       
   481                 }
       
   482             }
       
   483         // remove the seleted character to the first cell    
       
   484         aHomophonic.Insert( aTriggerStr.AllocL(), 0 );       
       
   485         }
       
   486     }
       
   487 
       
   488 // ---------------------------------------------------------------------------
       
   489 // Get homophonic or polyphonic candidates
       
   490 // ---------------------------------------------------------------------------
       
   491 //
       
   492 void CAknFepHwrEngine::GetHomophonicAndPolyphonic( TDes& aSpelling, 
       
   493     RPointerArray<HBufC>& aHomophonic )
       
   494     {
       
   495     TInt index = KErrNotFound;
       
   496     TBuf<KMaxOneSpellingLettersNum> tmpSpelling;
       
   497     
       
   498     while( aSpelling != KNullDesC16 )
       
   499         {
       
   500         tmpSpelling.Zero();    
       
   501 		// find the separator
       
   502         index = aSpelling.Find( KPolyphonicSeparator );
       
   503         if( index != KErrNotFound )
       
   504             {
       
   505 			// get one spelling in the polyphonic string
       
   506             tmpSpelling = aSpelling.Left( index );
       
   507 
       
   508 			// remove the left spelling and a separator
       
   509             aSpelling = aSpelling.Right( aSpelling.Length() - index - 1 );
       
   510             }
       
   511         else // only one spelling
       
   512             {
       
   513             tmpSpelling = aSpelling;
       
   514             aSpelling = KNullDesC16;
       
   515             }
       
   516            
       
   517 		// get candidate for each spelling
       
   518         RPointerArray<HBufC> candidates;
       
   519         HBufC* formatString = iPtiEngine->GetCandidatesByInputString( 
       
   520             tmpSpelling, 
       
   521             candidates, 
       
   522             EFalse );
       
   523                                                 
       
   524         for( TInt i = 0; i < candidates.Count(); i++ )
       
   525             {
       
   526             aHomophonic.Append( candidates[i] );        
       
   527             }
       
   528         delete formatString;
       
   529         candidates.Reset();
       
   530         }
       
   531     }
       
   532  
       
   533 
       
   534 // ---------------------------------------------------------------------------
       
   535 // Set primary and auxiliary ranges for hwr engine
       
   536 // ---------------------------------------------------------------------------
       
   537 //
       
   538 void CAknFepHwrEngine::SetRanges( const RArray<TInt>& aPermittedRanges )
       
   539     {
       
   540    	ASSERT( aPermittedRanges.Count() > 0 );
       
   541 
       
   542     if ( !iRecognizer )
       
   543         {
       
   544     	iNeedPermittedRanges.Reset();
       
   545     	
       
   546     	for ( TInt i = 0; i < aPermittedRanges.Count(); i++ )
       
   547     	    {
       
   548             iNeedPermittedRanges.Append( aPermittedRanges[i] );
       
   549     	    }
       
   550     	
       
   551     	iNeedSetRange = ETrue;
       
   552     	return;    
       
   553         }
       
   554     else 
       
   555     	{
       
   556         iPremaryRange = aPermittedRanges[0];
       
   557         iRangeCount = aPermittedRanges.Count();
       
   558         
       
   559         if( iPremaryRange == ERangeNumber )
       
   560             {
       
   561             SetCandidatesMaxCount( KCandidateCountNumMode );
       
   562             SetAuxCandidateNum( KAuxCandidateCountNumMode );
       
   563             }
       
   564         else
       
   565             {
       
   566             SetCandidatesMaxCount( KCandidateCount );
       
   567             SetAuxCandidateNum( KAuxCandidateCount );
       
   568             }
       
   569 
       
   570         TRecognitionRange range;
       
   571 
       
   572         SetRecognitionRange( aPermittedRanges[0], range );
       
   573         iRecognizer->SetRange( range );
       
   574 
       
   575         // set auxiliary ranges for hwr engine
       
   576         for ( TInt i=1; i<aPermittedRanges.Count(); i++ )
       
   577             {
       
   578             SetRecognitionRange( aPermittedRanges[i], range );
       
   579 
       
   580             iRecognizer->AddAuxiliaryRange( range );
       
   581             }
       
   582         
       
   583         SetCase( iCase );
       
   584     	}
       
   585     }
       
   586 
       
   587     
       
   588 // ---------------------------------------------------------------------------------------------
       
   589 // Set case
       
   590 // ---------------------------------------------------------------------------------------------
       
   591 //
       
   592 void CAknFepHwrEngine::SetCase( TInt aCase )
       
   593     {
       
   594     iCase = aCase;
       
   595     
       
   596     if ( !iRecognizer )
       
   597         {
       
   598     	iNeedSetCase = ETrue;
       
   599         }
       
   600     else
       
   601         {
       
   602         // set letter to lower first when LowerCase
       
   603 	    // set letter to upper first when UpperCase and TextCase
       
   604         if ( aCase == ECaseLower )
       
   605             {
       
   606             iRecognizer->SetFirstLetterOrder( ELowerFirst );
       
   607             }
       
   608         else
       
   609             {
       
   610             iRecognizer->SetFirstLetterOrder( EUpperFirst );
       
   611             }
       
   612         }
       
   613     }
       
   614 
       
   615 // ---------------------------------------------------------------------------------------------
       
   616 // Set number mode for hwr engine
       
   617 // ---------------------------------------------------------------------------------------------
       
   618 //
       
   619 void CAknFepHwrEngine::SetNumberMode( const TAknEditorNumericKeymap& aNumberMode )
       
   620     {
       
   621     iNumberMode = aNumberMode;
       
   622     
       
   623     if ( !iRecognizer )
       
   624         {
       
   625         iNeedSetNumberMode = ETrue;
       
   626         }
       
   627     else
       
   628         {
       
   629         iRecognizer->SetNumberMode( aNumberMode );
       
   630         if( aNumberMode !=  EKeymapFromResource )
       
   631             {
       
   632             ResetCustomKeyMap();
       
   633             }
       
   634         }
       
   635     }
       
   636 
       
   637 // ---------------------------------------------------------------------------------------------
       
   638 // Get stroke end mark from hwr engine
       
   639 // ---------------------------------------------------------------------------------------------
       
   640 //
       
   641 TPoint CAknFepHwrEngine::StrokeEndMark() const
       
   642     {
       
   643     if ( iRecognizer )
       
   644         {
       
   645         return iRecognizer->StrokeEndMark();
       
   646         }
       
   647     else
       
   648         {
       
   649         return TPoint( KDefaultStrokeEndMarkX, KDefaultStrokeEndMarkY );
       
   650         }
       
   651     }
       
   652 
       
   653 // ---------------------------------------------------------------------------------------------
       
   654 // Set primary candidate num for hwr engine
       
   655 // ---------------------------------------------------------------------------------------------
       
   656 //
       
   657 TInt CAknFepHwrEngine::SetPrimaryCandidateNum( TInt aNum )
       
   658     {
       
   659     if ( iRecognizer )
       
   660         {
       
   661         return iRecognizer->SetCandidateNum( aNum );
       
   662         }
       
   663     else
       
   664         {
       
   665         return KErrGeneral;
       
   666         }
       
   667     }
       
   668 
       
   669 // ---------------------------------------------------------------------------------------------
       
   670 // Set aux candidate num that should be shown
       
   671 // ---------------------------------------------------------------------------------------------
       
   672 //
       
   673 TInt CAknFepHwrEngine::SetAuxCandidateNum( TInt aNum )
       
   674     {
       
   675     if ( iRecognizer )
       
   676         {
       
   677         return iRecognizer->SetAuxCandidateNum( aNum );
       
   678         }
       
   679     else
       
   680         {
       
   681         return KErrGeneral;
       
   682         }
       
   683     }
       
   684 
       
   685 
       
   686 // ---------------------------------------------------------------------------------------------
       
   687 // Get aux candidate num that should be shown
       
   688 // ---------------------------------------------------------------------------------------------
       
   689 //
       
   690 TInt CAknFepHwrEngine::GetAuxCandidateNum()
       
   691     {
       
   692     if ( iRecognizer )
       
   693         {
       
   694         return iRecognizer->GetAuxCandidateNum();
       
   695         }
       
   696     else
       
   697         {
       
   698         return KErrGeneral;
       
   699         }
       
   700     }
       
   701         
       
   702 // ---------------------------------------------------------------------------------------------
       
   703 // Set total candidate num that should be shown
       
   704 // ---------------------------------------------------------------------------------------------
       
   705 //
       
   706 TInt CAknFepHwrEngine::SetCandidatesMaxCount( TInt aCount )
       
   707     {
       
   708     if ( aCount > 0 )
       
   709         {
       
   710         iTotalCandidateNum = aCount;
       
   711         return KErrNone;
       
   712         }
       
   713     else
       
   714         {
       
   715         return KErrGeneral;
       
   716         }    
       
   717     }
       
   718     
       
   719 // ---------------------------------------------------------------------------------------------
       
   720 // Set language
       
   721 // ---------------------------------------------------------------------------------------------
       
   722 //
       
   723 void CAknFepHwrEngine::SetLanguageL( TInt aLanguage )
       
   724     {
       
   725     if ( ( iLanguage == aLanguage ) ||
       
   726          ( aLanguage != ELangPrcChinese && 
       
   727           aLanguage != ELangHongKongChinese && 
       
   728           aLanguage != ELangTaiwanChinese ) )
       
   729         {
       
   730         return;
       
   731         }
       
   732         
       
   733     iLanguage = aLanguage;
       
   734 	switch ( iLanguage )
       
   735     {
       
   736     case ELangPrcChinese:
       
   737         {
       
   738         if ( iPtiEngine->ActivateLanguageL( iLanguage, EPtiEnginePinyinVkb ) != KErrNone )
       
   739         	{
       
   740         	iPtiEngine->ActivateLanguageL( iLanguage, EPtiEnginePinyin );
       
   741         	}
       
   742         }
       
   743         break;
       
   744     case ELangHongKongChinese:
       
   745         if ( iPtiEngine->ActivateLanguageL( iLanguage, EPtiEngineStrokeByPhrase ) != KErrNone )
       
   746         	{
       
   747         	iPtiEngine->ActivateLanguageL( ELangHongKongChinese, EPtiEngineStroke );
       
   748         	}
       
   749         break;
       
   750     case ELangTaiwanChinese:
       
   751         if ( iPtiEngine->ActivateLanguageL( iLanguage, EPtiEngineZhuyinVkb ) != KErrNone )
       
   752         	{
       
   753         	iPtiEngine->ActivateLanguageL( ELangTaiwanChinese, EPtiEngineZhuyin );
       
   754         	}
       
   755         break;
       
   756     default:
       
   757         return;
       
   758     }
       
   759 
       
   760 	iRecognizer = NULL;
       
   761 	
       
   762 	if( !iIdle->IsActive() )
       
   763 	    {
       
   764 	    iIdle->Start( TCallBack( BackgroundTaskL, this ) );
       
   765 	    }
       
   766     }
       
   767     
       
   768 // ---------------------------------------------------------------------------------------------
       
   769 // CAknFepHwrEngine::DoIdleConstructL
       
   770 // Do background construct.
       
   771 // ---------------------------------------------------------------------------------------------
       
   772 //
       
   773 void CAknFepHwrEngine::DoIdleConstructL()
       
   774     {
       
   775     if ( iRecognizer )
       
   776         {
       
   777         return;
       
   778         }
       
   779 
       
   780 	iRecognizer = iPtiEngine->GetHwrRecognizerL( TLanguage( iLanguage ) );
       
   781 
       
   782 	iOwner->SetStrokeEndMark();
       
   783 	SetPrimaryCandidateNum( KPremaryCandidateCount );
       
   784 	SetAuxCandidateNum( KAuxCandidateCount );
       
   785 	
       
   786     if ( iNeedSetRange )
       
   787         {
       
   788         SetRanges( iNeedPermittedRanges );
       
   789         iNeedPermittedRanges.Reset();
       
   790         iNeedSetRange = EFalse;        
       
   791         }
       
   792     
       
   793     if ( iNeedSetCase )
       
   794         {
       
   795     	SetCase( iCase );
       
   796     	iNeedSetCase = EFalse;
       
   797         }
       
   798     
       
   799     if ( iNeedSetNumberMode )
       
   800         {
       
   801     	SetNumberMode( TAknEditorNumericKeymap( iNumberMode ) );
       
   802     	iNeedSetNumberMode = EFalse;
       
   803         }
       
   804     }
       
   805 
       
   806 // ---------------------------------------------------------------------------------------------
       
   807 // CAknFepHwrEngine::BackgroundConstructL
       
   808 // Do background construct.
       
   809 // ---------------------------------------------------------------------------------------------
       
   810 //
       
   811 TBool CAknFepHwrEngine::BackgroundTaskL( TAny* aPtr )
       
   812     {
       
   813     CAknFepHwrEngine* self = static_cast<CAknFepHwrEngine*>( aPtr );
       
   814     self->DoIdleConstructL();
       
   815     return EFalse;
       
   816     }
       
   817     
       
   818 // ---------------------------------------------------------------------------
       
   819 // Set recognition range for hwr engine
       
   820 // ---------------------------------------------------------------------------
       
   821 //
       
   822 void CAknFepHwrEngine::SetRecognitionRange( const TInt aRange, 
       
   823     TRecognitionRange& aRecognitionRange )
       
   824     {
       
   825     aRecognitionRange.iLanguage = TLanguage( iLanguage );
       
   826 
       
   827     switch ( aRange )
       
   828         {
       
   829         case ERangeNative:
       
   830 			{
       
   831             if ( iLanguage == ELangPrcChinese )
       
   832                 {
       
   833                 aRecognitionRange.iSubRange = EPtiRangePRCChinese;
       
   834                 }
       
   835             else if ( iLanguage == ELangHongKongChinese )
       
   836                 {
       
   837                 aRecognitionRange.iSubRange = EPtiRangeHKChinese;
       
   838                 }
       
   839             else
       
   840             	{
       
   841                 aRecognitionRange.iSubRange = EPtiRangeTWChinese;
       
   842                 }
       
   843             break;
       
   844 			}
       
   845         case ERangeEnglish:
       
   846             aRecognitionRange.iLanguage = ELangEnglish;
       
   847             aRecognitionRange.iSubRange = EPtiRangeLatin;
       
   848 
       
   849             break;
       
   850         case ERangeNumber:
       
   851             aRecognitionRange.iSubRange = EPtiRangeNumber;
       
   852 
       
   853             break;
       
   854         case ERangeSymbol:
       
   855             // The symbol mode is associated with iLanguage instead of iPremaryRange
       
   856             aRecognitionRange.iLanguage = TLanguage( iLanguage );
       
   857             aRecognitionRange.iSubRange = EPtiRangeSymbol;
       
   858 
       
   859             break;
       
   860         default:
       
   861             break;
       
   862         }
       
   863     }
       
   864 
       
   865 // ---------------------------------------------------------------------------
       
   866 // Set recognition range for hwr engine
       
   867 // ---------------------------------------------------------------------------
       
   868 //
       
   869 void CAknFepHwrEngine::SetCustomKeymapL( const TDesC& aKeyMap )
       
   870     {
       
   871     ResetCustomKeyMap();
       
   872     
       
   873     iCustomKeymap = HBufC::NewL( aKeyMap.Length() + KNumberString().Length() );
       
   874     iCustomKeymap->Des().Copy( KNumberString() );
       
   875     iCustomKeymap->Des().Append( aKeyMap );
       
   876     }
       
   877 
       
   878 // ---------------------------------------------------------------------------
       
   879 // Set recognition range for hwr engine
       
   880 // ---------------------------------------------------------------------------
       
   881 //
       
   882 void CAknFepHwrEngine::ResetCustomKeyMap()
       
   883     {
       
   884     delete iCustomKeymap;
       
   885     iCustomKeymap = NULL;
       
   886     }
       
   887 TInt CAknFepHwrEngine::SetInputAreaSize(TSize& aSize)
       
   888     {
       
   889     if(iRecognizer)
       
   890         {
       
   891         return iRecognizer->SetInputAreaSize(aSize);        
       
   892         }
       
   893     else
       
   894         {
       
   895         return KErrNotFound;
       
   896         } 
       
   897     }    
       
   898 TInt CAknFepHwrEngine::SetScreenSize(TSize& aSize)    
       
   899     {
       
   900       if(iRecognizer)
       
   901         {
       
   902         return iRecognizer->SetScreenSize(aSize);        
       
   903         }
       
   904     else
       
   905         {
       
   906         return KErrNotFound;
       
   907         }  
       
   908     }    
       
   909 //End Of File