predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsKeyMap.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     1 /*
       
     2 * Copyright (c) 2007 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:  Retrieves the character map for each of the numeric keys.
       
    15 *               Uses services provided by the PTI Engine.
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "CPcsDebug.h"
       
    21 #include "CPcsKeyMap.h"
       
    22 #include <CPcsDefs.h>
       
    23 #include <bldvariant.hrh>
       
    24 #include <PtiEngine.h>
       
    25 #include <PtiKeyMapData.h>
       
    26 #include <AknFepInternalCRKeys.h>
       
    27 #include <AvkonInternalCRKeys.h>
       
    28 #include <centralrepository.h>
       
    29 #include <CPsQuery.h>
       
    30 #include <CPsQueryItem.h>
       
    31 
       
    32 // Unnamed namespace for local definitions
       
    33 namespace {
       
    34 
       
    35 #ifdef _DEBUG
       
    36     enum TPanicCode
       
    37     {
       
    38         EPanicPreCond_MultipleSingleCharMatching = 1,
       
    39         EPanicPreCond_MultipleUIPriorityMatching = 2,
       
    40         EPanicPreCond_MultipleEnglishPriorityMatching = 3,
       
    41         EPanicPreCond_MultipleOthersPriorityMatching = 4,
       
    42         EPanic_OverflowInPoolIndex = 5,
       
    43         EPanic_InvalidKeyboardType = 6
       
    44    };
       
    45 
       
    46     void Panic(TInt aReason)
       
    47     {
       
    48         _LIT(KPanicText, "CPcsKeyMap");
       
    49         User::Panic(KPanicText, aReason);
       
    50     }
       
    51 #endif // DEBUG
       
    52 
       
    53 } // namespace
       
    54 
       
    55 // ============================== MEMBER FUNCTIONS ============================
       
    56 
       
    57 // ----------------------------------------------------------------------------
       
    58 // CPcsKeyMap::NewL
       
    59 // Two Phase Construction
       
    60 // ----------------------------------------------------------------------------
       
    61 CPcsKeyMap* CPcsKeyMap::NewL()
       
    62     {
       
    63     PRINT ( _L("Enter CPcsKeyMap::NewL") );
       
    64 
       
    65     CPcsKeyMap* self = new ( ELeave ) CPcsKeyMap();
       
    66     CleanupStack::PushL( self );
       
    67     self->ConstructL();
       
    68     CleanupStack::Pop( self );
       
    69 
       
    70     PRINT ( _L("End CPcsKeyMap::NewL") );
       
    71 
       
    72     return self;
       
    73     }
       
    74 
       
    75 // ----------------------------------------------------------------------------
       
    76 // CPcsKeyMap::CPcsKeyMap
       
    77 // Constructor
       
    78 // ----------------------------------------------------------------------------
       
    79 CPcsKeyMap::CPcsKeyMap()
       
    80     {
       
    81     }
       
    82 
       
    83 // ----------------------------------------------------------------------------
       
    84 // CPcsKeyMap::ConstructL
       
    85 // 2nd Phase Constructor
       
    86 // ----------------------------------------------------------------------------
       
    87 void CPcsKeyMap::ConstructL()
       
    88     {
       
    89     PRINT ( _L("Enter CPcsKeyMap::ConstructL") );
       
    90 
       
    91     // UI Language
       
    92     iUILanguage = User::Language();
       
    93     
       
    94     // List of non-supported languages for this Algorithm
       
    95     iLanguageNotSupported.Append(ELangJapanese);
       
    96     iLanguageNotSupported.Append(ELangPrcChinese);
       
    97     iLanguageNotSupported.Append(ELangHongKongChinese);
       
    98     iLanguageNotSupported.Append(ELangTaiwanChinese);
       
    99     iLanguageNotSupported.Append(ELangKorean);
       
   100 
       
   101     TPtiKeyboardType physicalItutKbType;
       
   102     TPtiKeyboardType physicalQwertyKbType;    
       
   103     GetPhysicalKeyboardTypesL( physicalItutKbType, physicalQwertyKbType );
       
   104 
       
   105     iItutKeyboardType = EPtiKeyboard12Key; // We want to support Virtual Itu-T in most devices
       
   106     CreateKeyMappingL( EPredictiveItuT ); // Create structure for holding characters<-->key mappings
       
   107     if (iItutKeys.Count() == 0)
       
   108         {
       
   109         iItutKeyboardType = EPtiKeyboardNone;
       
   110         }
       
   111 
       
   112     iQwertyKeyboardType = physicalQwertyKbType;
       
   113     if (physicalQwertyKbType != EPtiKeyboardNone)
       
   114         {
       
   115         CreateKeyMappingL( EPredictiveQwerty ); // Create structure for holding characters<-->key mappings
       
   116         if (iQwertyKeys.Count() == 0)
       
   117             {
       
   118             iQwertyKeyboardType = EPtiKeyboardNone;
       
   119             }
       
   120         }
       
   121 
       
   122     // Set the Default Predictive keyboard mode. If Qwerty keyboard exists, it is always physical.
       
   123     iPredictiveDefaultKeyboardMode =
       
   124         (IsItutPredictiveAvailable() && physicalItutKbType != EPtiKeyboardNone) || !IsQwertyPredictiveAvailable() ?
       
   125             EPredictiveItuT : EPredictiveQwerty;
       
   126 
       
   127     PRINT1 ( _L("CPcsKeyMap::ConstructL: ITU-T Keyboard chosen for Predictive Search = %d"), iItutKeyboardType );
       
   128     PRINT1 ( _L("CPcsKeyMap::ConstructL: QWERTY Keyboard chosen for Predictive Search = %d"), iQwertyKeyboardType );
       
   129 
       
   130     // Sets attribute for holding info if "0" and " " are on the same key
       
   131     // Needed for decision if the "0" should be considered as a possible separator
       
   132     SetSpaceAndZeroOnSameKey();
       
   133     
       
   134     PRINT ( _L("CPcsKeyMap::ConstructL: ----------------------------------------"));
       
   135 
       
   136     PRINT ( _L("End CPcsKeyMap::ConstructL") );
       
   137     }
       
   138 
       
   139 // ----------------------------------------------------------------------------
       
   140 // CPcsKeyMap::~CPcsKeyMap
       
   141 // Destructor
       
   142 // ----------------------------------------------------------------------------
       
   143 CPcsKeyMap::~CPcsKeyMap()
       
   144     {
       
   145     PRINT ( _L("Enter CPcsKeyMap::~CPcsKeyMap") );
       
   146 
       
   147     // Cleanup local arrays
       
   148     iLanguageNotSupported.Reset();
       
   149 
       
   150     for (TInt i = 0; i < iItutKeyMaps.Count(); i++)
       
   151         {
       
   152         for (TInt j = 0; j < TKeyMappingData::EKeyMapNumberArr; j++)
       
   153             {
       
   154             iItutKeyMaps[i]->iKeyMapCharArr[j].Close();
       
   155             }
       
   156         }
       
   157     iItutKeyMaps.ResetAndDestroy();
       
   158     
       
   159     for (TInt i = 0; i < iQwertyKeyMaps.Count(); i++)
       
   160         {
       
   161         for (TInt j = 0; j < TKeyMappingData::EKeyMapNumberArr; j++)
       
   162             {
       
   163             iQwertyKeyMaps[i]->iKeyMapCharArr[j].Close();
       
   164             }
       
   165         }
       
   166     iQwertyKeyMaps.ResetAndDestroy();
       
   167     
       
   168     iItutKeys.Close();
       
   169     iQwertyKeys.Close();
       
   170 
       
   171     PRINT ( _L("End CPcsKeyMap::~CPcsKeyMap") );
       
   172     }
       
   173 
       
   174 // ----------------------------------------------------------------------------
       
   175 // CPcsKeyMap::IsItutPredictiveAvailable
       
   176 // 
       
   177 // ----------------------------------------------------------------------------
       
   178 TBool CPcsKeyMap::IsItutPredictiveAvailable() const
       
   179     {
       
   180     return ( iItutKeyboardType != EPtiKeyboardNone );
       
   181     }
       
   182 
       
   183 // ----------------------------------------------------------------------------
       
   184 // CPcsKeyMap::IsQwertyPredictiveAvailable
       
   185 // 
       
   186 // ----------------------------------------------------------------------------
       
   187 TBool CPcsKeyMap::IsQwertyPredictiveAvailable() const
       
   188     {
       
   189     return ( iQwertyKeyboardType != EPtiKeyboardNone );
       
   190     }
       
   191 
       
   192 // ----------------------------------------------------------------------------
       
   193 // CPcsKeyMap::IsModePredictive
       
   194 // 
       
   195 // ----------------------------------------------------------------------------
       
   196 TBool CPcsKeyMap::IsModePredictive( TKeyboardModes aKbMode )
       
   197     {
       
   198     return ( (EPredictiveDefaultKeyboard == aKbMode) ||
       
   199              (EPredictiveItuT == aKbMode) ||
       
   200              (EPredictiveQwerty == aKbMode) );
       
   201     }
       
   202 
       
   203 // ----------------------------------------------------------------------------
       
   204 // CPcsKeyMap::ResolveKeyboardMode
       
   205 // Resolve EPredictiveDefaultKeyboard or ENonPredictive mode to EPredictiveItuT
       
   206 // or EPredictiveQwerty mode
       
   207 // ----------------------------------------------------------------------------
       
   208 TKeyboardModes CPcsKeyMap::ResolveKeyboardMode( TKeyboardModes aKbMode,
       
   209                                                 TKeyboardModes aKbModeToResolve ) const
       
   210     {    
       
   211     // Substitute "default predictive" mode with actual mode
       
   212     if ( (aKbMode == aKbModeToResolve) &&
       
   213          ((aKbMode == ENonPredictive) || (aKbMode == EPredictiveDefaultKeyboard)) )
       
   214         {
       
   215         return iPredictiveDefaultKeyboardMode;
       
   216         }
       
   217     else
       
   218         {
       
   219         return aKbMode;
       
   220         }
       
   221     }
       
   222 
       
   223 // ----------------------------------------------------------------------------
       
   224 // CPcsKeyMap::GetMixedKeyStringForQueryL
       
   225 // aDestStr will have the length as the number of items in aSrcQuery.
       
   226 // ----------------------------------------------------------------------------
       
   227 void CPcsKeyMap::GetMixedKeyStringForQueryL(
       
   228         CPsQuery& aSrcQuery, TDes& aDestStr) const
       
   229     {
       
   230     PRINT ( _L("Enter CPcsKeyMap::GetMixedKeyStringForQueryL") ); 
       
   231 
       
   232     GetMixedKeyStringForDataL( aSrcQuery, aSrcQuery.QueryAsStringLC(), aDestStr );
       
   233     CleanupStack::PopAndDestroy(); //result of QueryAsStringLC
       
   234 
       
   235     PRINT ( _L("End CPcsKeyMap::GetMixedKeyStringForQueryL") );
       
   236     }
       
   237 
       
   238 // ----------------------------------------------------------------------------
       
   239 // CPcsKeyMap::GetMixedKeyStringForDataL
       
   240 // aDestStr will have the same length as aSrcData. aSrcQuery can be shorter.
       
   241 // ----------------------------------------------------------------------------
       
   242 void CPcsKeyMap::GetMixedKeyStringForDataL(
       
   243         CPsQuery& aSrcQuery, const TDesC& aSrcData, TDes& aDestStr) const
       
   244     {
       
   245     PRINT ( _L("Enter CPcsKeyMap::GetMixedKeyStringForDataL") );
       
   246 
       
   247     for ( TInt i = 0; i < aSrcData.Length(); ++i )
       
   248         {
       
   249         TChar character( aSrcData[i] );
       
   250         character.LowerCase();
       
   251         if ( i < aSrcQuery.Count() )
       
   252             {
       
   253             CPsQueryItem& currentItem = aSrcQuery.GetItemAtL(i);
       
   254             TPtiKey key = KeyForCharacterMultiMatch( aSrcData[i], currentItem.Mode() );
       
   255             // If a character is not mapped to any key or it's entered in non-predictive mode,
       
   256             // then append the character.
       
   257             if ( EPtiKeyNone == key )
       
   258                 {
       
   259                 PRINT3 ( _L("CPcsKeyMap::GetMixedKeyStringForDataL: Char at index %d not mapped to a key, appending char '%c' (#%d)"),
       
   260                          i, (TUint) character, (TUint) character );
       
   261 
       
   262                 aDestStr.Append( character );
       
   263                 }
       
   264             else 
       
   265                 {
       
   266                 aDestStr.Append( key );
       
   267                 }
       
   268             }
       
   269         else
       
   270             {            
       
   271             PRINT2 ( _L("CPcsKeyMap::GetMixedKeyStringForDataL: Char '%c' (#%d) is taken exact (over query length)"),
       
   272                     (TUint) character, (TUint) character );
       
   273 
       
   274             aDestStr.Append( character );
       
   275             }
       
   276         }
       
   277 
       
   278     PRINT1 ( _L("CPcsKeyMap::GetMixedKeyStringForDataL: Return string: \"%S\""),
       
   279              &aDestStr );
       
   280 
       
   281     PRINT ( _L("End CPcsKeyMap::GetMixedKeyStringForDataL") );
       
   282     }
       
   283 
       
   284 // ----------------------------------------------------------------------------
       
   285 // CPcsKeyMap::CharacterForKeyMappingExists
       
   286 // Returns true if the character is mapped to the key
       
   287 // ----------------------------------------------------------------------------
       
   288 TBool CPcsKeyMap::CharacterForKeyMappingExists(
       
   289         TKeyMappingData& aKeyMap, TUint aIntChar) const
       
   290     {
       
   291     TBool found = EFalse;
       
   292     
       
   293     for (TInt j = TKeyMappingData::EKeyMapUILangArr; j <= TKeyMappingData::EKeyMapOthersLangArr; j++)
       
   294         {
       
   295         if ( KErrNotFound != aKeyMap.iKeyMapCharArr[j].Find(aIntChar) )
       
   296             {
       
   297             found = ETrue;
       
   298             break;
       
   299             }
       
   300         
       
   301         }
       
   302     
       
   303     return found;
       
   304     }
       
   305 
       
   306 #ifdef _DEBUG
       
   307 // ----------------------------------------------------------------------------
       
   308 // CPcsKeyMap::CheckPotentialErrorConditions
       
   309 //
       
   310 // ----------------------------------------------------------------------------
       
   311 void CPcsKeyMap::CheckPotentialErrorConditions(const RArray<TInt>& aPoolIndexArr, 
       
   312                                                const TChar& aChar,
       
   313                                                const RArray<TPtiKey>& aPtiKeys,
       
   314                                                const RPointerArray<TKeyMappingData>& aKeyMappings) const
       
   315     {
       
   316     PRINT ( _L("CPcsKeyMap::CheckPotentialErrorConditions: ===================================================") );
       
   317     PRINT ( _L("CPcsKeyMap::CheckPotentialErrorConditions: Checking potential error conditions") );
       
   318     PRINT ( _L("CPcsKeyMap::CheckPotentialErrorConditions: ---------------------------------------------------") );
       
   319 
       
   320     _LIT(KTextCharArr0, "is single char");
       
   321     _LIT(KTextCharArr1, "has \"UI\" priority");
       
   322     _LIT(KTextCharArr2, "has \"English\" priority");
       
   323     _LIT(KTextCharArr3, "has \"Others\" priority");
       
   324     const TPtrC charArrStr[] =
       
   325         { KTextCharArr0(), KTextCharArr1(), KTextCharArr2(), KTextCharArr3() };
       
   326     
       
   327     TFixedArray<TUint, TKeyMappingData::EKeyMapNumberArr> countArr;
       
   328 
       
   329     for ( TInt j = TKeyMappingData::EKeyMapSingleCharArr; j <= TKeyMappingData::EKeyMapOthersLangArr; j++ )
       
   330         {
       
   331         countArr[j] = 0;
       
   332         for ( TInt i = 0; i < aPoolIndexArr.Count(); i++ )
       
   333             {
       
   334             if ( KErrNotFound != aKeyMappings[aPoolIndexArr[i]]->iKeyMapCharArr[j].Find((TUint) aChar) )
       
   335                 {
       
   336                 PRINT5 ( _L("CPcsKeyMap::CheckPotentialErrorConditions: Char '%c' (0x%04X) %S for pool %d with key '%c'"),
       
   337                         (TUint) aChar, (TUint) aChar, &charArrStr[j], aPoolIndexArr[i], aPtiKeys[aPoolIndexArr[i]] );
       
   338                 countArr[j]++;
       
   339                 }
       
   340             }
       
   341         }
       
   342 
       
   343     PRINT ( _L("CPcsKeyMap::CheckPotentialErrorConditions: ===================================================") );
       
   344     
       
   345 #ifdef __WINS__
       
   346     /*
       
   347     The reference 4x10 QWERTY mappings of 9.2 emulator have each number mapped to two keys.
       
   348     That kind of mappings can't be handled correctly, so panic in debug would basically be correct.
       
   349     However, assertions are commented out for now to be able to do some testing.
       
   350     
       
   351     // Check in debug mode if we have wrong situations
       
   352     __ASSERT_DEBUG( (countArr[TKeyMappingData::EKeyMapSingleCharArr]  <= 1), Panic(EPanicPreCond_MultipleSingleCharMatching) );
       
   353     __ASSERT_DEBUG( (countArr[TKeyMappingData::EKeyMapUILangArr]      <= 1), Panic(EPanicPreCond_MultipleUIPriorityMatching) );
       
   354     __ASSERT_DEBUG( (countArr[TKeyMappingData::EKeyMapEnglishLangArr] <= 1), Panic(EPanicPreCond_MultipleEnglishPriorityMatching) );
       
   355     __ASSERT_DEBUG( (countArr[TKeyMappingData::EKeyMapOthersLangArr]  <= 1), Panic(EPanicPreCond_MultipleOthersPriorityMatching) );
       
   356     */
       
   357 #endif // __WINS__
       
   358     }
       
   359 #endif // _DEBUG        
       
   360 
       
   361 // ----------------------------------------------------------------------------
       
   362 // CPcsKeyMap::KeyForCharacterMultiMatch
       
   363 // Considers possible that the same character can be in more pools.
       
   364 // This case was verified at least in the following verified cases:
       
   365 // - For some language version (i.e. Scandinavian with keys 'ä', 'å', 'ö'.
       
   366 // - For some special characters in ITU-T 12 keys keyboards.
       
   367 //   Example: '$' is under key '1' and '7', '£' is under key '1' and '5'.
       
   368 // In case the character is in more pools the selection strategy is the following:
       
   369 //   - 1st choice: if the keyboard is EPtiKeyboard12Key exclude the pool with '1'.
       
   370 //   - 2nd choice: choose the 1st pool that has for a language the char as single char.
       
   371 //   - 3rd choice: choose the 1st pool that has the char mapped for the UI language.
       
   372 //   - 4th choice: choose the 1st pool that has the char mapped for the English language.
       
   373 //   - 5th choice: choose the 1st pool that has the char mapped for the Other languages.
       
   374 // ----------------------------------------------------------------------------
       
   375 TPtiKey CPcsKeyMap::KeyForCharacterMultiMatch( const TChar& aChar, TKeyboardModes aKbMode ) const
       
   376     {    
       
   377     aKbMode = ResolveKeyboardMode( aKbMode, EPredictiveDefaultKeyboard ); 
       
   378 
       
   379     // Select key arrays to use according to keyboard mode
       
   380     const RArray<TPtiKey>* ptiKeyArray;
       
   381     const RPointerArray<TKeyMappingData>* keyMappingArray;
       
   382     TPtiKeyboardType kbType;
       
   383     GetPredictiveKeyboardData( aKbMode, ptiKeyArray, keyMappingArray, kbType );
       
   384     if ( !ptiKeyArray || !keyMappingArray || ptiKeyArray->Count() == 0 )
       
   385         {
       
   386         // No mappings available. This may be, for example, because aKbMode is non-predictive.
       
   387         // Return no mapping in that case to indicate that character should be treated in
       
   388         // non-predictive way.
       
   389         return EPtiKeyNone;
       
   390         }
       
   391     
       
   392     // Set an array of pool index matches (more matches are possible)
       
   393     RArray<TInt> poolIndexArr;
       
   394     for ( TInt i = 0; i < keyMappingArray->Count(); i++ )
       
   395         {
       
   396         if ( CharacterForKeyMappingExists(*(*keyMappingArray)[i], (TUint) aChar) )
       
   397             {
       
   398             poolIndexArr.Append(i);
       
   399 
       
   400             PRINT4 ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Char '%c' (0x%04X) found in pool %d with key '%c'"),
       
   401                     (TUint) aChar, (TUint) aChar, i, (*ptiKeyArray)[i] );
       
   402             }
       
   403         }
       
   404 
       
   405     /* Choose the pool index depending on the number of matches.
       
   406      * If there are 2 or more matches, then the choice of the pool index depends on
       
   407      * a serie of conditions.
       
   408      */
       
   409     TInt poolIndex = KErrNotFound;
       
   410 
       
   411     // Character not found in any pool
       
   412     if ( poolIndexArr.Count() == 0 )
       
   413         {
       
   414         PRINT2 ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Char '%c' (0x%04X) NOT found from any pool"),
       
   415                  (TUint) aChar, (TUint) aChar );
       
   416         }
       
   417 
       
   418     // Character found in one pool (normal case)
       
   419     else if ( poolIndexArr.Count() == 1 )
       
   420         {
       
   421         poolIndex = poolIndexArr[0];
       
   422 
       
   423         PRINT2 ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Chosen (for unique match) pool %d with key '%c'"),
       
   424                 poolIndex, (*ptiKeyArray)[poolIndex] );
       
   425         }
       
   426 
       
   427     /* Character found in more pools, this can happen in some known conditions:
       
   428      * - In some variants 'Ä' is in key 'A' and in key 'Ä'
       
   429      * - In ITUT keyboard '$' is in keys '1' and '7'. This happens for more chars.
       
   430      * - For different languages in N97 '/' is in different keys.
       
   431      */
       
   432     else // ( poolIndexArr.Count() > 1 )
       
   433         {
       
   434 
       
   435         /* If keybord is ITUT we exclude the key '1' from the posibility of being choosen,
       
   436          * infact some characters can be typed by key '1' and another key.
       
   437          * For example:
       
   438          *     '$' is under key '1' and '7',
       
   439          *     '£' is under key '1' and '5'.
       
   440          *
       
   441          * This is needed when the client passes updated chars to the engine.
       
   442          * i.e.: Existing contact are "!Mat" and "$Nathan",
       
   443          *       User types '7' and client passes '7' or 'p' matching only contact "$Nathan",
       
   444          *       In next query user types '2' and client passes '$2' or '$a' matching "!Mat" and "$Nathan".
       
   445          *       This is wrong, as "!Mat" should not be matched.
       
   446          * When the client will not pass updated chars to the engine, but the original (i.e.: "72" or "pa"),
       
   447          * this piece of code shall be removed.
       
   448          * With "client" it is referred to MCL contacts client.
       
   449          */
       
   450         if (EPtiKeyboard12Key == kbType)
       
   451             {
       
   452             for ( TInt i = 0; i < poolIndexArr.Count() ; i++ )
       
   453                 {
       
   454                 if ( EPtiKey1 == (*ptiKeyArray)[poolIndexArr[i]] )
       
   455                     {
       
   456                     poolIndexArr.Remove(i);
       
   457     
       
   458                     PRINT ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Key '1' excluded (for multi match - EPtiKeyboard12Key)") );
       
   459                     break;
       
   460                     }
       
   461                 }
       
   462             if ( poolIndexArr.Count() == 1 )
       
   463                 {
       
   464                 poolIndex = poolIndexArr[0];
       
   465 
       
   466                 PRINT2 ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Chosen (for unique match after removing key '1') pool %d with key '%c'"),
       
   467                         poolIndex, (*ptiKeyArray)[poolIndex] );
       
   468                 }
       
   469             }
       
   470 
       
   471 #ifdef _DEBUG
       
   472         CheckPotentialErrorConditions(poolIndexArr, aChar, *ptiKeyArray, *keyMappingArray);
       
   473 #endif // _DEBUG        
       
   474 
       
   475         // Search the char in the char arrays in priority order, the 1st match is taken
       
   476         for ( TInt j = TKeyMappingData::EKeyMapSingleCharArr; j <= TKeyMappingData::EKeyMapOthersLangArr; j++ )
       
   477             {
       
   478             if ( KErrNotFound == poolIndex )
       
   479                 {
       
   480                 TInt positionLeftMostOnKeys = KErrNotFound; 
       
   481 
       
   482                 for ( TInt i = 0; i < poolIndexArr.Count(); i++ )
       
   483                     {
       
   484                     TInt position = (*keyMappingArray)[poolIndexArr[i]]->iKeyMapCharArr[j].Find((TUint) aChar);
       
   485                     if ( KErrNotFound != position )
       
   486                         {
       
   487                         // Get the key that has the char in the leftmost index.
       
   488                         // We consider that the char can be mapped in more than one key (this is really
       
   489                         // the case for instance in some Scandinavian variants).
       
   490                         // With this guess there is more possibility that we choose the key where the
       
   491                         // char is physically printed on the keyboard key.
       
   492                         // In order for this guessing strategy to work, chars for TPtiTextCase EPtiCaseUpper
       
   493                         // have to be added to the char arrays before any other TPtiTextCase.
       
   494                         if ( TKeyMappingData::EKeyMapUILangArr == j )
       
   495                             {
       
   496                             if ( ( KErrNotFound == positionLeftMostOnKeys ) || ( position < positionLeftMostOnKeys ) )
       
   497                                 {
       
   498                                 poolIndex = poolIndexArr[i];
       
   499                                 positionLeftMostOnKeys = position;
       
   500                                 }
       
   501                             }
       
   502                         // Get the 1st key that has the char mapped to it
       
   503                         else
       
   504                             {
       
   505                             poolIndex = poolIndexArr[i];
       
   506                     
       
   507                             PRINT3 ( _L("CPcsKeyMap::KeyForCharacterMultiMatch: Chosen (for multi match - char arr: %d) pool %d with key '%c'"),
       
   508                                      j, poolIndex, (*ptiKeyArray)[poolIndex] );
       
   509                         
       
   510                             break;
       
   511                             }
       
   512                         }
       
   513                     }
       
   514                 }
       
   515             }
       
   516                     
       
   517         } // else -> ( poolIndexArr.Count() > 1 )
       
   518 
       
   519     // Set the key value from the pool index
       
   520     TPtiKey key = EPtiKeyNone;
       
   521     if ( KErrNotFound != poolIndex )
       
   522         {
       
   523         key = (*ptiKeyArray)[poolIndex];
       
   524         }
       
   525     
       
   526     poolIndexArr.Close();
       
   527     return key;
       
   528     }
       
   529 
       
   530 // ----------------------------------------------------------------------------
       
   531 // CPcsKeyMap::PoolIdForKey
       
   532 //
       
   533 // ----------------------------------------------------------------------------
       
   534 TInt CPcsKeyMap::PoolIdForKey(const TPtiKey aKey, TKeyboardModes aKbMode)
       
   535     {
       
   536     aKbMode = ResolveKeyboardMode( aKbMode, EPredictiveDefaultKeyboard ); 
       
   537 
       
   538     // From logical point of view, the Pool ID is an index of the key in
       
   539     // an array which is formed by concatenating QWERTY keys array in the end
       
   540     // of the ITU-T keys array.
       
   541     TInt poolId = KErrNotFound;
       
   542     if ( aKbMode == EPredictiveItuT && IsItutPredictiveAvailable() )
       
   543         {
       
   544         poolId = iItutKeys.Find(aKey);
       
   545         // IF the key is not found, then it should go to the special pool,
       
   546         // which is the pool of the dummy key in the ITU-T keys array
       
   547         if (KErrNotFound == poolId)
       
   548             {
       
   549             poolId = iItutKeys.Count() - 1;
       
   550             }
       
   551         }
       
   552     else if ( aKbMode == EPredictiveQwerty && IsQwertyPredictiveAvailable() )
       
   553         {
       
   554         poolId = iQwertyKeys.Find(aKey);
       
   555         // IF the key is not found, then it should go to the special pool,
       
   556         // which is the pool of the dummy key in the QWERTY keys array
       
   557         if (KErrNotFound == poolId)
       
   558             {
       
   559             poolId = iQwertyKeys.Count() - 1;
       
   560             }
       
   561         // Pools of QWERTY keys come after pools of ITU-T keys
       
   562         poolId += iItutKeys.Count();
       
   563         }
       
   564 
       
   565     // Pool ID must never exceed value 63, because CPcsCache class
       
   566     // stores these values as bitmask into 64 bit variable.
       
   567     __ASSERT_DEBUG( poolId < 64, Panic(EPanic_OverflowInPoolIndex) );
       
   568 
       
   569     return poolId;
       
   570     }
       
   571 
       
   572 // ----------------------------------------------------------------------------
       
   573 // CPcsKeyMap::PoolIdForCharacter
       
   574 //
       
   575 // ----------------------------------------------------------------------------
       
   576 TInt CPcsKeyMap::PoolIdForCharacter(const TChar& aChar, TKeyboardModes aKbMode)
       
   577     {
       
   578     // Pools are formed according the predictive keyboard mapping(s).
       
   579     // When selecting pool for non-predictive mode, we use the pool of the
       
   580     // default keyboard. The non-predictive matches should be a sub set of the
       
   581     // predictive matches of the default keyboard, although strictly speaking,
       
   582     // there is no guarantee for this.
       
   583     aKbMode = ResolveKeyboardMode( aKbMode, ENonPredictive ); 
       
   584 
       
   585     TPtiKey key = KeyForCharacterMultiMatch( aChar, aKbMode );
       
   586 
       
   587     TInt poolId = PoolIdForKey(key, aKbMode);
       
   588 
       
   589     return poolId;
       
   590     }
       
   591 
       
   592 // ----------------------------------------------------------------------------
       
   593 // CPcsKeyMap::PoolCount
       
   594 //
       
   595 // ----------------------------------------------------------------------------
       
   596 TInt CPcsKeyMap::PoolCount()
       
   597     {
       
   598     return iItutKeyMaps.Count() + iQwertyKeyMaps.Count();
       
   599     }
       
   600 
       
   601 // ----------------------------------------------------------------------------
       
   602 // CPcsKeyMap::SetSpaceAndZeroOnSameKey
       
   603 // 
       
   604 // ----------------------------------------------------------------------------
       
   605 void CPcsKeyMap::SetSpaceAndZeroOnSameKey()
       
   606     {
       
   607     static const TInt KSpace = 0x20; // ASCII for " "
       
   608     static const TInt KZero  = 0x30; // ASCII for "0"
       
   609 
       
   610     TChar charSpace(KSpace);
       
   611     TChar charZero(KZero);
       
   612 
       
   613     TPtiKey keySpace;
       
   614     TPtiKey keyZero;
       
   615 	
       
   616     // ITU-T mode
       
   617     keySpace = KeyForCharacterMultiMatch(charSpace, EPredictiveItuT);
       
   618     keyZero = KeyForCharacterMultiMatch(charZero, EPredictiveItuT);
       
   619     iSpaceAndZeroOnSameKeyOnItut = (keySpace == keyZero && keyZero != EPtiKeyNone);
       
   620     PRINT1 ( _L("CPcsKeyMap::iSpaceAndZeroOnSameKeyOnItut = %d"), iSpaceAndZeroOnSameKeyOnItut );
       
   621     
       
   622     // QWERTY mode
       
   623     keySpace = KeyForCharacterMultiMatch(charSpace, EPredictiveQwerty);
       
   624     keyZero = KeyForCharacterMultiMatch(charZero, EPredictiveQwerty);
       
   625     iSpaceAndZeroOnSameKeyOnQwerty = (keySpace == keyZero && keyZero != EPtiKeyNone);
       
   626     PRINT1 ( _L("CPcsKeyMap::iSpaceAndZeroOnSameKeyOnQwerty = %d"), iSpaceAndZeroOnSameKeyOnQwerty );
       
   627     }
       
   628 
       
   629 // ----------------------------------------------------------------------------
       
   630 // CPcsKeyMap::GetSpaceAndZeroOnSameKey
       
   631 // 
       
   632 // ----------------------------------------------------------------------------
       
   633 TBool CPcsKeyMap::GetSpaceAndZeroOnSameKey( TKeyboardModes aKbMode )
       
   634     {
       
   635     TBool result = EFalse;
       
   636 
       
   637     aKbMode = ResolveKeyboardMode( aKbMode, EPredictiveDefaultKeyboard );
       
   638 
       
   639     if ( aKbMode == EPredictiveItuT )
       
   640         {
       
   641         result = iSpaceAndZeroOnSameKeyOnItut;
       
   642         }
       
   643     else if ( aKbMode == EPredictiveQwerty )
       
   644         {
       
   645         result = iSpaceAndZeroOnSameKeyOnQwerty;
       
   646         }
       
   647 
       
   648     return result;
       
   649     }
       
   650 
       
   651 // ----------------------------------------------------------------------------
       
   652 // CPcsKeyMap::GetPhysicalKeyboardTypesL
       
   653 // Initialise the keyboard type variables
       
   654 // ----------------------------------------------------------------------------
       
   655 void CPcsKeyMap::GetPhysicalKeyboardTypesL( TPtiKeyboardType& aItutKbType,
       
   656                                             TPtiKeyboardType& aQwertyKbType )
       
   657     {
       
   658     TInt physicalKeyboard = 0;
       
   659     CRepository* aknFepRepository = CRepository::NewL( KCRUidAknFep );
       
   660     aknFepRepository->Get( KAknFepPhysicalKeyboards, physicalKeyboard );
       
   661     delete aknFepRepository;
       
   662 
       
   663     PRINT1 ( _L("CPcsKeyMap::GetPhysicalKeyboardTypesL: Physical keyboard support flag = 0x%02X"), physicalKeyboard );
       
   664 
       
   665     // Constants follow the definition of KAknFepPhysicalKeyboards
       
   666     const TInt KPtiKeyboard12Key = 0x01;
       
   667     const TInt KPtiKeyboardQwerty4x12 = 0x02;
       
   668     const TInt KPtiKeyboardQwerty4x10 = 0x04;
       
   669     const TInt KPtiKeyboardQwerty3x11 = 0x08;
       
   670     const TInt KPtiKeyboardHalfQwerty = 0x10;
       
   671     const TInt KPtiKeyboardCustomQwerty = 0x20; 
       
   672 
       
   673     // Get ITU-T mode first.
       
   674     // Use always 12-key mode since all the supported devices should have at least
       
   675     // virtual ITU-T available.
       
   676     // It will be set to EPtiKeyboardNone if getting the key list will fail.
       
   677     if ( physicalKeyboard & KPtiKeyboard12Key )
       
   678         {
       
   679         aItutKbType = EPtiKeyboard12Key;
       
   680         }
       
   681     else
       
   682         {
       
   683         aItutKbType = EPtiKeyboardNone;
       
   684         }
       
   685     
       
   686     // Then get QWERTY mode. On real-life devices there should never
       
   687     // be more than one QWERTY keyboard available but on emulator there can be several.
       
   688     // Use the first one found in the following precedence
       
   689     // It will be set to EPtiKeyboardNone if getting the key list will fail.
       
   690     if ( physicalKeyboard & KPtiKeyboardQwerty3x11 )
       
   691         {
       
   692         aQwertyKbType = EPtiKeyboardQwerty3x11;
       
   693         }
       
   694     else if ( physicalKeyboard & KPtiKeyboardQwerty4x10 )
       
   695         {
       
   696         aQwertyKbType = EPtiKeyboardQwerty4x10;
       
   697         }
       
   698     else if ( physicalKeyboard & KPtiKeyboardQwerty4x12 )
       
   699         {
       
   700         aQwertyKbType = EPtiKeyboardQwerty4x12;
       
   701         }
       
   702     else if ( physicalKeyboard & KPtiKeyboardCustomQwerty )
       
   703         {
       
   704         aQwertyKbType = EPtiKeyboardCustomQwerty;
       
   705         }
       
   706     else if ( physicalKeyboard & KPtiKeyboardHalfQwerty )
       
   707         {
       
   708         aQwertyKbType = EPtiKeyboardHalfQwerty;
       
   709         }
       
   710     else
       
   711         {
       
   712         aQwertyKbType = EPtiKeyboardNone;
       
   713         }
       
   714         
       
   715     PRINT1 ( _L("CPcsKeyMap::GetPhysicalKeyboardTypesL: Physical ITU-T Keyboard = %d"), aItutKbType );
       
   716     PRINT1 ( _L("CPcsKeyMap::GetPhysicalKeyboardTypesL: Physical QWERTY Keyboard = %d"), aQwertyKbType );
       
   717     }
       
   718 
       
   719 // ----------------------------------------------------------------------------
       
   720 // CPcsKeyMap::AppendEntryWithFakeKeyToKeyList
       
   721 // Add pool with unused id for for key
       
   722 // ----------------------------------------------------------------------------
       
   723 void CPcsKeyMap::AppendEntryWithFakeKeyToKeyList( RArray<TPtiKey>& aKeyArray )
       
   724     {
       
   725     TUint keyUInt = (TUint) EPtiKeyNone + 1;
       
   726 
       
   727     while ( KErrNotFound != aKeyArray.Find( (TPtiKey) keyUInt) )
       
   728         {
       
   729         keyUInt++;
       
   730         }
       
   731 
       
   732     TPtiKey key = (TPtiKey) keyUInt;
       
   733     aKeyArray.Append( key );
       
   734 
       
   735     // This should always be the last one in the array
       
   736     PRINT2 ( _L("CPcsKeyMap::AppendEntryWithFakeKeyToKeyList: Added additional last pool %d with key id #%d"),
       
   737             aKeyArray.Count()-1, key );
       
   738     }
       
   739 
       
   740 // ----------------------------------------------------------------------------
       
   741 // CPcsKeyMap::CreateKeyMapFromKeyBindingTable
       
   742 //
       
   743 // ----------------------------------------------------------------------------
       
   744 void CPcsKeyMap::CreateKeyListFromKeyBindingTable( RArray<TPtiKey>& aKeyArray, 
       
   745         TPtiKeyboardType aKbType, CPtiEngine* aPtiEngine )
       
   746     {
       
   747     PRINT ( _L("Enter CPcsKeyMap::CreateKeyListFromKeyBindingTable") );
       
   748 
       
   749     PRINT1 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Creating KeyList for TPtiKeyboardType=%d"),
       
   750              aKbType  );
       
   751 
       
   752     // Get the user language
       
   753     TLanguage keyMapLanguage = iUILanguage;
       
   754     PRINT1 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Current User Language is %d"),
       
   755             keyMapLanguage  );
       
   756 
       
   757     // If the user language is not supported, then we use ELangEnglish as default
       
   758     if (!IsLanguageSupported((TInt) keyMapLanguage))
       
   759         {
       
   760         PRINT2 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Language %d is not supported, defaulting to %d"),
       
   761                 keyMapLanguage, ELangEnglish );
       
   762 
       
   763         keyMapLanguage = ELangEnglish;
       
   764         }
       
   765 
       
   766     CPtiCoreLanguage* currLanguage = static_cast<CPtiCoreLanguage*>(aPtiEngine->GetLanguage( keyMapLanguage ));
       
   767 
       
   768     // If we fail to get the language, we try again trying with ELangEnglish
       
   769     if ( (!currLanguage) && (ELangEnglish != keyMapLanguage) )
       
   770         {
       
   771         PRINT1 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Failed to get Current Language, trying with %d"),
       
   772                  ELangEnglish );
       
   773 
       
   774         currLanguage = static_cast<CPtiCoreLanguage*>(aPtiEngine->GetLanguage( ELangEnglish ));
       
   775         }
       
   776 
       
   777     if (currLanguage)
       
   778         {
       
   779         TInt langCode = currLanguage->LanguageCode();
       
   780         TRAP_IGNORE( aPtiEngine->ActivateLanguageL( langCode ) );
       
   781         const CPtiKeyMapData* keyMapData = currLanguage->RawKeyMapData();
       
   782         const TPtiKeyBinding* table = NULL;
       
   783         TInt numItems = 0;
       
   784         if ( keyMapData )
       
   785             {
       
   786             table = keyMapData->KeyBindingTable(aKbType, numItems);
       
   787             }
       
   788         else
       
   789             {
       
   790             PRINT1( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: #### Failed to get RawKeyMapData for language %d ####"), langCode );
       
   791             }
       
   792         
       
   793         PRINT1 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Num of Items in KeyBindingTable is %d"), numItems );
       
   794 
       
   795         // Get from the key table the keys for constructing the pools
       
   796         if (table)
       
   797             {
       
   798             for (TInt i = 0; i < numItems; i++)
       
   799                 {
       
   800                 TPtiKey key = (TPtiKey) table[i].iScanCode;
       
   801                 // Get all keys with same EPtiCaseLower or EPtiCaseUpper case
       
   802                 // Only for one of the casing to avoid repetitions
       
   803                 if ( (EPtiKeyNone != key) && (EPtiCaseLower == table[i].iCase) )
       
   804                     {
       
   805                     PRINT3 ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: Adding pool %d with key '%c' (0x%02X)"),
       
   806                             aKeyArray.Count(), key, key );
       
   807                     aKeyArray.Append( key );
       
   808                     }
       
   809                 }
       
   810             // Add a fake key at the end if the KeyList is not empty
       
   811             if (aKeyArray.Count() > 0)
       
   812                 {
       
   813                 AppendEntryWithFakeKeyToKeyList(aKeyArray);
       
   814                 }
       
   815             }
       
   816         else
       
   817             {
       
   818             PRINT ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: ##### Failed to create Key List (KeyBindingTable) #####") );
       
   819             }
       
   820         }
       
   821     else
       
   822         {
       
   823         PRINT ( _L("CPcsKeyMap::CreateKeyListFromKeyBindingTable: ##### Failed to create Key List (Language) #####") );
       
   824         }
       
   825 
       
   826     PRINT ( _L("End CPcsKeyMap::CreateKeyListFromKeyBindingTable") );
       
   827 }
       
   828 
       
   829 // ----------------------------------------------------------------------------
       
   830 // CPcsKeyMap::IsLanguageSupported
       
   831 // Returns ETrue if this language is supported
       
   832 // ----------------------------------------------------------------------------
       
   833 TBool CPcsKeyMap::IsLanguageSupported(TInt aLang)
       
   834     {
       
   835     TBool supported = 
       
   836 #ifdef __WINS__
       
   837             // Only few languages for emulator 
       
   838             ( ELangEnglish == aLang || 
       
   839               ELangRussian == aLang || 
       
   840               ELangHebrew == aLang || 
       
   841               ELangFinnish == aLang ) &&
       
   842 #endif // __WINS__
       
   843             ( KErrNotFound == iLanguageNotSupported.Find((TLanguage)aLang) );
       
   844                 
       
   845     return supported;
       
   846     }
       
   847 
       
   848 // ----------------------------------------------------------------------------
       
   849 // CPcsKeyMap::CreateKeyMappingL
       
   850 //
       
   851 // ----------------------------------------------------------------------------
       
   852 void CPcsKeyMap::CreateKeyMappingL( TKeyboardModes aKbMode )
       
   853     {
       
   854     PRINT ( _L("Enter CPcsKeyMap::CreateKeyMappingL") );
       
   855 
       
   856     __ASSERT_DEBUG( (aKbMode==EPredictiveItuT || aKbMode==EPredictiveQwerty),
       
   857                     Panic(EPanic_InvalidKeyboardType) );
       
   858 
       
   859     // Select the arrays we are operating on
       
   860     RArray<TPtiKey>* ptiKeysArray;
       
   861     RPointerArray<TKeyMappingData>* keyMappingArray;
       
   862     TPtiKeyboardType kbType;
       
   863     GetPredictiveKeyboardData( aKbMode, ptiKeysArray, keyMappingArray, kbType );
       
   864     if ( kbType == EPtiKeyboardNone )
       
   865         {
       
   866         PRINT1( _L("CPcsKeyMap::CreateKeyMappingL: ##### No Keyboard available for mode %d => skipping #####"), aKbMode );
       
   867         return;
       
   868         }
       
   869     
       
   870     // Instantiate the engine
       
   871     CPtiEngine* ptiEngine = CPtiEngine::NewL(ETrue);
       
   872     CleanupStack::PushL( ptiEngine );
       
   873 
       
   874     ptiEngine->SetKeyboardType( kbType );
       
   875 
       
   876     CreateKeyListFromKeyBindingTable( *ptiKeysArray, kbType, ptiEngine );
       
   877 
       
   878     if ( ptiKeysArray->Count() > 0 )
       
   879         {
       
   880         // Now add the keymap arrays to hold the keymap data
       
   881         for (TInt i = 0; i < ptiKeysArray->Count(); i++)
       
   882             {
       
   883             TKeyMappingData *keyData = new(ELeave) TKeyMappingData;
       
   884             keyMappingArray->Append(keyData);
       
   885             }
       
   886     
       
   887         // Get the available Languages on the phone
       
   888         RArray<TInt> languagesOnThisPhone;
       
   889         CleanupClosePushL( languagesOnThisPhone );
       
   890         ptiEngine->GetAvailableLanguagesL(languagesOnThisPhone);
       
   891         PRINT2 ( _L("CPcsKeyMap::CreateKeyMappingL: Languages on this phone %d, maximum is set to %d"),
       
   892                  languagesOnThisPhone.Count(), KMaxNbrOfLangKeymapping );
       
   893         
       
   894         // Remove the non-supported languages
       
   895         for (TInt i = 0; i < languagesOnThisPhone.Count(); /* do not increment i */)
       
   896             {
       
   897             if ( IsLanguageSupported(languagesOnThisPhone[i]) )
       
   898                 {
       
   899                 i++;
       
   900                 }
       
   901             else
       
   902                 {
       
   903                 PRINT1 ( _L("CPcsKeyMap::CreateKeyMappingL: Removing not supported Language %d"),
       
   904                          languagesOnThisPhone[i] );
       
   905                 languagesOnThisPhone.Remove(i);
       
   906                 }
       
   907             }
       
   908     
       
   909         // Set current UI language as 1st language and English as 2nd language,
       
   910         // if present in AvailableLanguages
       
   911         TInt langIndex;
       
   912         if ( KErrNotFound != (langIndex = languagesOnThisPhone.Find(ELangEnglish)) )
       
   913             {
       
   914             languagesOnThisPhone.Remove(langIndex);
       
   915             languagesOnThisPhone.Insert(ELangEnglish, 0);
       
   916             }
       
   917         if ( KErrNotFound != (langIndex = languagesOnThisPhone.Find(iUILanguage)) )
       
   918             {
       
   919             languagesOnThisPhone.Remove(langIndex);
       
   920             languagesOnThisPhone.Insert(iUILanguage, 0);
       
   921             }
       
   922     
       
   923         // Set max number of languages for Key Map
       
   924         TInt count = languagesOnThisPhone.Count();
       
   925         if (count > KMaxNbrOfLangKeymapping)
       
   926             {
       
   927             PRINT2 ( _L("CPcsKeyMap::CreateKeyMappingL: Supported Languages on this phone %d, limiting to %d"),
       
   928                      count, KMaxNbrOfLangKeymapping );
       
   929             count = KMaxNbrOfLangKeymapping;
       
   930             }
       
   931     
       
   932         // Add Key Map for the languages
       
   933         for (TInt i = 0; i < count; i++)
       
   934             {
       
   935             TLanguage languageToUse = (TLanguage) languagesOnThisPhone[i];
       
   936     
       
   937             PRINT1 ( _L("CPcsKeyMap::CreateKeyMappingL: Constructing Key Map for Language %d"), languageToUse );
       
   938             TRAPD( leaveCode, AddKeyMappingForLanguageL(ptiEngine, languageToUse, kbType, *ptiKeysArray, *keyMappingArray) );
       
   939             if ( leaveCode )
       
   940                 {
       
   941                 PRINT2 ( _L("CPcsKeyMap::CreateKeyMappingL: ##### Adding mappings for language %d failed, leave code = %d #####"),
       
   942                          languageToUse, leaveCode );
       
   943                 }
       
   944     
       
   945             PRINT ( _L("CPcsKeyMap::CreateKeyMappingL: ===================================================") );
       
   946             }
       
   947     
       
   948         CleanupStack::PopAndDestroy( &languagesOnThisPhone );
       
   949         }
       
   950 
       
   951     CleanupStack::PopAndDestroy( ptiEngine );
       
   952 
       
   953     PRINT ( _L("End CPcsKeyMap::CreateKeyMappingL") );
       
   954     }
       
   955 
       
   956 // ----------------------------------------------------------------------------
       
   957 // CPcsKeyMap::AddKeyMappingForActiveLanguageL
       
   958 //
       
   959 // ----------------------------------------------------------------------------
       
   960 void CPcsKeyMap::AddKeyMappingForLanguageL(
       
   961         CPtiEngine* aPtiEngine, 
       
   962         TLanguage aLanguage,
       
   963         TPtiKeyboardType aKbType,
       
   964         const RArray<TPtiKey>& aPtiKeys,
       
   965         RPointerArray<TKeyMappingData>& aResultMapping )
       
   966 {
       
   967     PRINT ( _L("Enter CPcsKeyMap::AddKeyMappingForLanguageL") );
       
   968 
       
   969     TInt err = aPtiEngine->ActivateLanguageL( aLanguage );
       
   970     if ( err )
       
   971         {
       
   972         PRINT2 ( _L("##### CPcsKeyMap::AddKeyMappingForLanguageL failed to activate language %d, error=%d) #####"),
       
   973                 aLanguage, err );
       
   974         User::Leave( err );
       
   975         }
       
   976 
       
   977     // Make a language object based on the language
       
   978     CPtiCoreLanguage* language = static_cast<CPtiCoreLanguage*>(aPtiEngine->GetLanguage( aLanguage ));
       
   979 
       
   980     if (language)
       
   981         {
       
   982         for (TInt i = 0; i < aResultMapping.Count() - 1; i++)
       
   983             {
       
   984             TPtiKey key = aPtiKeys[i];
       
   985 
       
   986             PRINT ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: ===================================================") );
       
   987             PRINT4 ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: Adding chars for Key '%c' (0x%02X) for Keyboard Type %d and Language %d"),
       
   988                      key, key, aKbType, aLanguage );
       
   989 
       
   990             // Get the pointer to the language class (UI, English, Others)
       
   991             RArray<TUint>* keyMapLang;
       
   992             if (aLanguage == iUILanguage)
       
   993                 {
       
   994                 keyMapLang = &(aResultMapping[i]->iKeyMapCharArr[TKeyMappingData::EKeyMapUILangArr]);
       
   995                 PRINT1 ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: Language %d is the UI language"), aLanguage );
       
   996                 }
       
   997             else if (aLanguage == ELangEnglish)
       
   998                 {
       
   999                 // If (iUILanguage == ELangEnglish) ok to be in previous if case
       
  1000                 keyMapLang = &(aResultMapping[i]->iKeyMapCharArr[TKeyMappingData::EKeyMapEnglishLangArr]);
       
  1001                 PRINT1 ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: Language %d is English language"), aLanguage );
       
  1002                 }
       
  1003             else
       
  1004                 {
       
  1005                 keyMapLang = &(aResultMapping[i]->iKeyMapCharArr[TKeyMappingData::EKeyMapOthersLangArr]);
       
  1006                 PRINT1 ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: Language %d is in the Other languages"), aLanguage );
       
  1007                 }
       
  1008             
       
  1009             PRINT ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: ---------------------------------------------------") );
       
  1010 
       
  1011             TBool isSingleCharForKey = ETrue;
       
  1012             TUint singleChar = 0;
       
  1013 
       
  1014             // EPtiCaseUpper must be the 1st TPtiTextCase for iUILanguage
       
  1015             AddCharactersToKey( *language, aKbType, key, EPtiCaseUpper, *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1016             AddCharactersToKey( *language, aKbType, key, EPtiCaseLower, *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1017 
       
  1018             // 1. No other TPtiTextCase values for ITUT keyboard
       
  1019             // 2. No language variants handling for ITUT keyboard
       
  1020             if ( EPtiKeyboard12Key != aKbType )
       
  1021                 {
       
  1022                 AddCharactersToKey( *language, aKbType, key, EPtiCaseFnLower,  *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1023                 AddCharactersToKey( *language, aKbType, key, EPtiCaseFnUpper,  *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1024                 AddCharactersToKey( *language, aKbType, key, EPtiCaseChrLower, *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1025                 AddCharactersToKey( *language, aKbType, key, EPtiCaseChrUpper, *aResultMapping[i], *keyMapLang, isSingleCharForKey, singleChar );
       
  1026 
       
  1027                 // Support for key guessing given the char in some phone language variants
       
  1028                 if ( (isSingleCharForKey) && (0 != singleChar) )
       
  1029                     {
       
  1030                     aResultMapping[i]->iKeyMapCharArr[TKeyMappingData::EKeyMapSingleCharArr].Append(singleChar); // singleChar is in LowerCase
       
  1031                     aResultMapping[i]->iKeyMapCharArr[TKeyMappingData::EKeyMapSingleCharArr].Append(User::UpperCase(singleChar));
       
  1032 
       
  1033                     PRINT ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: ---------------------------------------------------") );
       
  1034                     PRINT5 ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: For Language %d and key '%c' of pool %d single char is '%c' (0x%04X)"),
       
  1035                             aLanguage, key, i, singleChar, singleChar );
       
  1036                     }
       
  1037                 }
       
  1038             }
       
  1039         PRINT ( _L("CPcsKeyMap::AddKeyMappingForLanguageL: ===================================================") );
       
  1040         }
       
  1041 
       
  1042     PRINT ( _L("End CPcsKeyMap::AddKeyMappingForLanguageL") );
       
  1043 }
       
  1044 
       
  1045 // ----------------------------------------------------------------------------
       
  1046 // CPcsKeyMap::GetCharactersForKey
       
  1047 //
       
  1048 // ----------------------------------------------------------------------------
       
  1049 void CPcsKeyMap::GetCharactersForKey(CPtiCoreLanguage& aPtiLanguage,
       
  1050                                      TPtiKeyboardType aKbType,
       
  1051                                      TPtiKey aKey,
       
  1052                                      TPtiTextCase aTextCase,
       
  1053                                      TDes& aResult)
       
  1054     {
       
  1055     const CPtiKeyMapData* keyMapData = aPtiLanguage.RawKeyMapData();
       
  1056     if  ( keyMapData )
       
  1057         {
       
  1058         TPtrC dataPtr = keyMapData->DataForKey( aKbType, aKey, aTextCase );
       
  1059         // truncate results if supplied buffer is not large enough
       
  1060         aResult = dataPtr.Left( aResult.MaxLength() );
       
  1061         }
       
  1062     }
       
  1063 
       
  1064 // ----------------------------------------------------------------------------
       
  1065 // CPcsKeyMap::AddDataForKeyL
       
  1066 //
       
  1067 // ----------------------------------------------------------------------------
       
  1068 void CPcsKeyMap::AddCharactersToKey(CPtiCoreLanguage& aPtiLanguage,
       
  1069                                     TPtiKeyboardType aKbType,
       
  1070                                     TPtiKey aKey,
       
  1071                                     TPtiTextCase aTextCase,
       
  1072                                     TKeyMappingData& aKeyDataList,
       
  1073                                     RArray<TUint>& aKeyMapLang,
       
  1074                                     TBool& aIsSingleCharForKey,
       
  1075                                     TUint& aSingleChar)
       
  1076     {
       
  1077     PRINT ( _L("Enter CPcsKeyMap::AddCharactersToKey") );
       
  1078 
       
  1079     TBuf<255> result;
       
  1080     GetCharactersForKey(aPtiLanguage, aKbType, aKey, aTextCase, result);
       
  1081 
       
  1082     PRINT3 ( _L("CPcsKeyMap::AddCharactersToKey: Get mapping chars for Key '%c' (0x%02X) and TextCase %d"),
       
  1083              aKey, aKey, aTextCase );
       
  1084     PRINT1 ( _L("CPcsKeyMap::AddCharactersToKey: Got chars: \"%S\""), &result );
       
  1085 
       
  1086     for ( TInt i = 0; i < result.Length(); i++ )
       
  1087         {
       
  1088         TText character = result[i];
       
  1089         if ( !CharacterForKeyMappingExists(aKeyDataList, character ) )
       
  1090             {
       
  1091             PRINT2 ( _L("CPcsKeyMap::AddCharactersToKey: ----- Appending char to list: '%c' (0x%04X)"), character, character );
       
  1092             aKeyMapLang.Append(character);
       
  1093             }
       
  1094         else
       
  1095             {
       
  1096             PRINT2 ( _L("CPcsKeyMap::AddCharactersToKey: ***** NOT Appending char to list: '%c' (0x%04X)"), character, character );
       
  1097             }
       
  1098 
       
  1099         // No language variants handling for ITUT keyboard
       
  1100         if ( EPtiKeyboard12Key != aKbType )
       
  1101             {
       
  1102             // Support for key guessing given the char in some phone language variants
       
  1103             if ( aIsSingleCharForKey )
       
  1104                 {
       
  1105                 if ( 0 == aSingleChar )
       
  1106                     {
       
  1107                     aSingleChar = User::LowerCase(character);
       
  1108                     }
       
  1109                 else
       
  1110                     {
       
  1111                     TInt newChar = User::LowerCase(character);
       
  1112                     if (newChar != aSingleChar)
       
  1113                         {
       
  1114                         aSingleChar = 0;
       
  1115                         aIsSingleCharForKey = EFalse;
       
  1116                         }
       
  1117                     }
       
  1118                 }
       
  1119             }
       
  1120         }
       
  1121 
       
  1122     PRINT ( _L("CPcsKeyMap::AddCharactersToKey: ---------------------------------------------------") );
       
  1123 
       
  1124     PRINT ( _L("End CPcsKeyMap::AddCharactersToKey") );
       
  1125     }
       
  1126 
       
  1127 // ----------------------------------------------------------------------------
       
  1128 // CPcsKeyMap::GetPredictiveKeyboardData
       
  1129 //
       
  1130 // ----------------------------------------------------------------------------
       
  1131 void CPcsKeyMap::GetPredictiveKeyboardData( TKeyboardModes aKbMode, 
       
  1132                                             RArray<TPtiKey>*& aPtiKeys, 
       
  1133                                             RPointerArray<TKeyMappingData>*& aKeyMappings, 
       
  1134                                             TPtiKeyboardType& aKbType )
       
  1135     {
       
  1136     // Get the data from constant version of this function
       
  1137     const RArray<TPtiKey>* constKeys;
       
  1138     const RPointerArray<TKeyMappingData>* constMappings;
       
  1139     GetPredictiveKeyboardData( aKbMode, constKeys, constMappings, aKbType );
       
  1140     
       
  1141     // Convert pointers to non-const
       
  1142     aPtiKeys = const_cast< RArray<TPtiKey>* >( constKeys );
       
  1143     aKeyMappings = const_cast< RPointerArray<TKeyMappingData>* >( constMappings );
       
  1144     }
       
  1145 
       
  1146 // ----------------------------------------------------------------------------
       
  1147 // CPcsKeyMap::GetPredictiveKeyboardData
       
  1148 //
       
  1149 // ----------------------------------------------------------------------------
       
  1150 void CPcsKeyMap::GetPredictiveKeyboardData( TKeyboardModes aKbMode, 
       
  1151                                             const RArray<TPtiKey>*& aPtiKeys, 
       
  1152                                             const RPointerArray<TKeyMappingData>*& aKeyMappings, 
       
  1153                                             TPtiKeyboardType& aKbType ) const
       
  1154     {
       
  1155     PRINT1 ( _L("CPcsKeyMap::GetPredictiveKeyboardData: aKbMode=%d "), aKbMode );
       
  1156     
       
  1157     // EPredictiveItuT or EPredictiveQwerty mode to ENonPredictive mode if keyboard is not mapped
       
  1158     if ( aKbMode == EPredictiveItuT && !IsItutPredictiveAvailable() )
       
  1159         {
       
  1160         aKbMode = ENonPredictive;
       
  1161         }
       
  1162     if ( aKbMode == EPredictiveQwerty && !IsQwertyPredictiveAvailable() )
       
  1163         {
       
  1164         aKbMode = ENonPredictive;
       
  1165         }
       
  1166 
       
  1167     // Get Predictive Keyboard Data
       
  1168     switch (aKbMode)
       
  1169         {
       
  1170         case EPredictiveItuT:
       
  1171             aPtiKeys = &iItutKeys;
       
  1172             aKeyMappings = &iItutKeyMaps;
       
  1173             aKbType = iItutKeyboardType;
       
  1174             break;
       
  1175 
       
  1176         case EPredictiveQwerty:
       
  1177             aPtiKeys = &iQwertyKeys;
       
  1178             aKeyMappings = &iQwertyKeyMaps;
       
  1179             aKbType = iQwertyKeyboardType;
       
  1180             break;
       
  1181 
       
  1182         case ENonPredictive:
       
  1183             aPtiKeys = NULL;
       
  1184             aKeyMappings = NULL;
       
  1185             aKbType = EPtiKeyboardNone;
       
  1186             break;
       
  1187 
       
  1188         // EPredictiveDefaultKeyboard must have been resolved previously
       
  1189         // to EPredictiveItuT or EPredictiveQwerty mode
       
  1190         case EPredictiveDefaultKeyboard: 
       
  1191         default:
       
  1192             aPtiKeys = NULL;
       
  1193             aKeyMappings = NULL;
       
  1194             aKbType = EPtiKeyboardNone;
       
  1195             __ASSERT_DEBUG( EFalse, Panic( EPanic_InvalidKeyboardType ) );
       
  1196             break;
       
  1197         }
       
  1198     }
       
  1199 
       
  1200 // End of file