plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /*
       
     2 * Copyright (c) 2010 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 */
       
    16 
       
    17 // INCLUDE FILES
       
    18 #include "cpcskeymap.h"
       
    19 #include <QChar>
       
    20 #include <QString>
       
    21 
       
    22 #if defined(USE_ORBIT_KEYMAP)
       
    23 #include <hbinputkeymap.h>
       
    24 #include <hbinputkeymapfactory.h>
       
    25 #endif // #if defined(USE_ORBIT_KEYMAP)
       
    26 
       
    27 // This macro suppresses log writes
       
    28 //#define NO_PRED_SEARCH_LOGS
       
    29 #include "predictivesearchlog.h"
       
    30 
       
    31 const QChar KSpaceChar = ' ';
       
    32 
       
    33 // Separator character stored in predictive search table columns
       
    34 const QChar KSeparatorChar = ' ';
       
    35 
       
    36 
       
    37 // ============================== MEMBER FUNCTIONS ============================
       
    38 
       
    39 // ----------------------------------------------------------------------------
       
    40 // CPcsKeyMap::~CPcsKeyMap
       
    41 // ----------------------------------------------------------------------------
       
    42 CPcsKeyMap::~CPcsKeyMap()
       
    43     {
       
    44     PRINT(_L("Enter CPcsKeyMap::~CPcsKeyMap"));    
       
    45     PRINT(_L("End CPcsKeyMap::~CPcsKeyMap"));
       
    46     }
       
    47 
       
    48 // ----------------------------------------------------------------------------
       
    49 // CPcsKeyMap::GetMappedStringL
       
    50 // ----------------------------------------------------------------------------
       
    51 HBufC* CPcsKeyMap::GetMappedStringL(const TDesC& aSource) const
       
    52     {
       
    53     PRINT1(_L("Enter CPcsKeyMap::GetMappedStringL input '%S'"), &aSource);
       
    54 
       
    55 	QString source((QChar*)aSource.Ptr(), aSource.Length());
       
    56 	QString result;
       
    57 	TInt err(KErrNone);
       
    58 	QT_TRYCATCH_ERROR(err, result = GetMappedString(source));
       
    59 	User::LeaveIfError(err);
       
    60 
       
    61     HBufC* destination = HBufC::NewL(result.length());
       
    62 	destination->Des().Copy(result.utf16());
       
    63 
       
    64     PRINT1(_L("End CPcsKeyMap::GetMappedStringL result '%S'"), destination);
       
    65     return destination;
       
    66     }
       
    67 
       
    68 // ----------------------------------------------------------------------------
       
    69 // CPcsKeyMap::GetMappedString
       
    70 // ----------------------------------------------------------------------------
       
    71 QString CPcsKeyMap::GetMappedString(QString aSource) const
       
    72 	{
       
    73 #if defined(WRITE_PRED_SEARCH_LOGS)
       
    74 	const int KLogLength = 30;
       
    75 	TBuf<KLogLength> log(aSource.left(KLogLength).utf16());
       
    76 	PRINT1(_L("Enter CPcsKeyMap::GetMappedString input '%S'"), &log);
       
    77 #endif
       
    78 
       
    79 	QString destination;
       
    80 	TBool skipHashStar = DetermineSpecialCharBehaviour(aSource);
       
    81 	TInt length = aSource.length();
       
    82 
       
    83     for (int i = 0; i < length; ++i)
       
    84         {
       
    85         if (aSource[i] == KSpaceChar)
       
    86             {
       
    87             destination.append(KSeparatorChar);
       
    88             }
       
    89         else
       
    90 			{
       
    91 			QChar ch(0);
       
    92 #if defined(USE_ORBIT_KEYMAP)
       
    93             ch = MappedKeyForChar(aSource[i]);
       
    94 #else
       
    95             ch = UseHardcodedKeyMap(aSource[i]);            
       
    96 #endif
       
    97 			if (!ShouldSkipChar(ch, skipHashStar))
       
    98 				{
       
    99 				destination.append(ch);
       
   100 				}
       
   101 			}
       
   102 		}
       
   103 #if defined(WRITE_PRED_SEARCH_LOGS)
       
   104 	log = destination.left(KLogLength).utf16();
       
   105 	PRINT1(_L("End CPcsKeyMap::GetMappedString result '%S'"), &log);
       
   106 #endif
       
   107     return destination;
       
   108 	}
       
   109 
       
   110 // ----------------------------------------------------------------------------
       
   111 // CPcsKeyMap::GetNumericLimitsL
       
   112 // In order to speed up the execution, caller should convert search pattern
       
   113 // with a one call to CPcsKeyMap::GetMappedStringL() and then pass the tokens
       
   114 // to CPcsKeyMap::GetNumericLimitsL().
       
   115 // So it is expected that aString contains only certain characters.
       
   116 // ----------------------------------------------------------------------------
       
   117 TInt CPcsKeyMap::GetNumericLimits(QString aString,
       
   118 								  QString& aLowerLimit,
       
   119 								  QString& aUpperLimit) const
       
   120 	{
       
   121 	PRINT(_L("CPcsKeyMap::GetNumericLimits"));
       
   122 	if (aString.length() > iMaxKeysStoredInDb)
       
   123 		{
       
   124 		QString truncated = aString.left(iMaxKeysStoredInDb);
       
   125 		aString = truncated;
       
   126 		}
       
   127 
       
   128 	TInt err = ComputeValue(aString, EFalse, aLowerLimit);
       
   129 	if (err == KErrNone)
       
   130 		{
       
   131 		err = ComputeValue(aString, ETrue, aUpperLimit);
       
   132 		}
       
   133 	PRINT1(_L("End CPcsKeyMap::GetNumericLimits ret=%d"), err);
       
   134 	return err;
       
   135 	}
       
   136 
       
   137 #if defined(USE_ORBIT_KEYMAP)
       
   138 // ----------------------------------------------------------------------------
       
   139 // CPcsKeyMap::Separator
       
   140 // ----------------------------------------------------------------------------
       
   141 QChar CPcsKeyMap::Separator() const
       
   142     {
       
   143     return KSeparatorChar;
       
   144     }
       
   145 
       
   146 // ----------------------------------------------------------------------------
       
   147 // CPcsKeyMap::SetHardcodedCharacters
       
   148 // Default implementation selects only the current default language.
       
   149 // ----------------------------------------------------------------------------
       
   150 QList<HbInputLanguage> CPcsKeyMap::SelectLanguages()
       
   151 	{
       
   152 	QList<HbInputLanguage> languages;
       
   153 	HbInputLanguage inputLanguage(QLocale::system().language()); 
       
   154 	languages << inputLanguage;
       
   155 	return languages;
       
   156 	}
       
   157 
       
   158 // ----------------------------------------------------------------------------
       
   159 // CPcsKeyMap::SetHardcodedCharacters
       
   160 // Default implementation does nothing
       
   161 // ----------------------------------------------------------------------------
       
   162 void CPcsKeyMap::SetHardcodedCharacters()
       
   163 	{
       
   164 	}
       
   165 #endif // #if defined(USE_ORBIT_KEYMAP)
       
   166 
       
   167 // ----------------------------------------------------------------------------
       
   168 // CPcsKeyMap::DetermineSpecialCharBehaviour
       
   169 // Default implementation
       
   170 // ----------------------------------------------------------------------------
       
   171 TBool CPcsKeyMap::DetermineSpecialCharBehaviour(QString /*aSource*/) const
       
   172 	{
       
   173 	return EFalse;
       
   174 	}
       
   175 
       
   176 // ----------------------------------------------------------------------------
       
   177 // CPcsKeyMap::ShouldSkipChar
       
   178 // Default implementation
       
   179 // ----------------------------------------------------------------------------
       
   180 TBool CPcsKeyMap::ShouldSkipChar(QChar /*aChar*/, TBool /*aSkipHashStar*/) const
       
   181 	{
       
   182 	return EFalse;
       
   183 	}
       
   184 
       
   185 // ----------------------------------------------------------------------------
       
   186 // CPcsKeyMap::ConstructL
       
   187 // ----------------------------------------------------------------------------
       
   188 #if defined(USE_ORBIT_KEYMAP)
       
   189 void CPcsKeyMap::ConstructL(HbKeyboardType aKeyboardType)
       
   190 #else
       
   191 void CPcsKeyMap::ConstructL()
       
   192 #endif
       
   193 	{
       
   194 	PRINT(_L("Enter CPcsKeyMap::ConstructL"));
       
   195 
       
   196 #if defined(USE_ORBIT_KEYMAP)
       
   197 	TInt err(KErrNone);
       
   198 	QT_TRYCATCH_ERROR(err,
       
   199 		{
       
   200 		InitKeyMappings();
       
   201 		SetHardcodedCharacters();
       
   202 		ConstructLanguageMappings(aKeyboardType);
       
   203 		});
       
   204 	if (err != KErrNone)
       
   205         {
       
   206         PRINT1(_L("CPcsKeyMap::ConstructL exception, err=%d"), err);
       
   207         User::Leave(err);
       
   208         }
       
   209 #endif
       
   210 
       
   211 	PRINT(_L("End CPcsKeyMap::ConstructL"));
       
   212 	}
       
   213 
       
   214 // ----------------------------------------------------------------------------
       
   215 // CPcsKeyMap::CPcsKeyMap
       
   216 // ----------------------------------------------------------------------------
       
   217 #if defined(USE_ORBIT_KEYMAP)
       
   218 CPcsKeyMap::CPcsKeyMap(TInt aAmountOfKeys,
       
   219 					   QChar aPadChar,
       
   220 					   TInt aMaxKeysStoredInDb) :
       
   221 	iKeyMapping(),
       
   222 	iAmountOfKeys(aAmountOfKeys),
       
   223 	iPadChar(aPadChar),
       
   224 	iMaxKeysStoredInDb(aMaxKeysStoredInDb)
       
   225 	{
       
   226 	}
       
   227 #else // #if defined(USE_ORBIT_KEYMAP)
       
   228 CPcsKeyMap::CPcsKeyMap(TInt /*aAmountOfKeys*/,
       
   229 					   QChar /*aPadChar*/,
       
   230 					   TInt aMaxKeysStoredInDb) :
       
   231 	iMaxKeysStoredInDb(aMaxKeysStoredInDb)
       
   232 	{
       
   233 	}
       
   234 #endif // #if defined(USE_ORBIT_KEYMAP)
       
   235 
       
   236 #if defined(USE_ORBIT_KEYMAP)
       
   237 // ----------------------------------------------------------------------------
       
   238 // CPcsKeyMap::InitKeyMappings
       
   239 // Put string for each key into iKeyMapping.
       
   240 // ----------------------------------------------------------------------------
       
   241 void CPcsKeyMap::InitKeyMappings()
       
   242 	{
       
   243     PRINT(_L("Enter CPcsKeyMap::InitKeyMappings"));
       
   244 
       
   245 	for (TInt i = 0; i < iAmountOfKeys; ++i)
       
   246         {
       
   247         iKeyMapping << QString("");
       
   248         }
       
   249 	}
       
   250 
       
   251 // ----------------------------------------------------------------------------
       
   252 // CPcsKeyMap::ConstructLanguageMappings
       
   253 // Fetch keymap for selected languages.
       
   254 // ----------------------------------------------------------------------------
       
   255 void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType) 
       
   256 	{
       
   257     PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings"));
       
   258 
       
   259 #if defined(WRITE_PRED_SEARCH_LOGS)
       
   260     TInt count(0);
       
   261 #endif
       
   262 
       
   263 	QList<HbInputLanguage> languages = SelectLanguages();
       
   264     PRINT1(_L("build keymap from %d language(s)"), languages.count());
       
   265 
       
   266 	TInt languageCount = languages.size();
       
   267 	for (TInt lang = 0; lang < languageCount; ++lang)
       
   268 		{
       
   269         PRINT2(_L("(%d) handle language %d"), lang, languages[lang].language());
       
   270 		if (IsLanguageSupported(languages[lang].language()))
       
   271 			{
       
   272 			PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
       
   273 				   languages[lang].language(),
       
   274 				   languages[lang].variant());
       
   275 			const HbKeymap* keymap =
       
   276 				HbKeymapFactory::instance()->keymap(languages[lang].language(),
       
   277                                                     languages[lang].variant());
       
   278 			if (keymap)
       
   279 			    {
       
   280 				for (TInt key = 0; key < iAmountOfKeys; ++key)
       
   281                     {
       
   282                     PRINT1(_L("handle key(enum value %d)"), key); // test
       
   283                     const HbMappedKey* mappedKey = keymap->keyForIndex(aKeyboardType, key);
       
   284 					// 12-key: Most languages don't have mapping for EKeyStar, EKeyHash.
       
   285 					// QWERTY: Different languages have different amount of keys,
       
   286 					// so mappedKey can be NULL.
       
   287                     if (mappedKey)
       
   288                         {
       
   289 						const QString lowerCase = mappedKey->characters(HbModifierNone); // "abc2.."
       
   290 						const QString upperCase = mappedKey->characters(HbModifierShiftPressed); // "ABC2.."
       
   291 						const QString charsForKey = lowerCase + upperCase; 
       
   292 	    
       
   293 						// Filter out duplicate characters
       
   294 						for (TInt i = charsForKey.length() - 1; i >= 0 ; --i) 
       
   295 							{
       
   296 							QChar ch = charsForKey[i];
       
   297 							if (!iKeyMapping[key].contains(ch) &&
       
   298 								!iHardcodedChars.contains(ch))
       
   299 								{
       
   300 #if defined(WRITE_PRED_SEARCH_LOGS)
       
   301 								char ascChar = ch.toAscii();
       
   302 								TChar logChar(ArrayIndexToMappedChar(key).unicode());
       
   303 	
       
   304 								if (ascChar == 0) // ch can't be represented in ASCII
       
   305 									{
       
   306 									PRINT2(_L("CPcsKeyMap: map key(%c) <-> char=0x%x"),
       
   307 									       logChar, ch);
       
   308 									}
       
   309 								else
       
   310 									{
       
   311 									PRINT3(_L("CPcsKeyMap: map key(%c) <-> char='%c'(0x%x)"),
       
   312 										   logChar,
       
   313 										   ascChar,
       
   314 										   ascChar);
       
   315 									}
       
   316 								++count;
       
   317 #endif // #if defined(WRITE_PRED_SEARCH_LOGS)
       
   318 								iKeyMapping[key] += ch;
       
   319 								}
       
   320 							}
       
   321 						}
       
   322                     }
       
   323 			    }
       
   324 			else
       
   325                 {
       
   326                 PRINT(_L("CPcsKeyMap::ContructKeyboardMapping keymap not found"));
       
   327                 }
       
   328 			}
       
   329 		}
       
   330 
       
   331 #if defined(WRITE_PRED_SEARCH_LOGS)
       
   332     PRINT1(_L("End CPcsKeyMap::ConstructLanguageMappings keymap has %d chars"), count);
       
   333 #endif
       
   334 	}
       
   335 
       
   336 // ----------------------------------------------------------------------------
       
   337 // CPcsKeyMap::IsLanguageSupported
       
   338 // ----------------------------------------------------------------------------
       
   339 TBool CPcsKeyMap::IsLanguageSupported(QLocale::Language aLanguage) const
       
   340 	{
       
   341 	return (aLanguage != QLocale::Japanese && aLanguage != QLocale::Chinese);
       
   342 	}
       
   343 
       
   344 // ----------------------------------------------------------------------------
       
   345 // CPcsKeyMap::MappedKeyForChar
       
   346 // Loop all QStrings of iKeyMapping to find one containing the character.
       
   347 // If the character is not mapped, use pad character.
       
   348 // ----------------------------------------------------------------------------
       
   349 const QChar CPcsKeyMap::MappedKeyForChar(const QChar aChar) const
       
   350 	{
       
   351     for (TInt index = 0; index < iAmountOfKeys; ++index) 
       
   352         {
       
   353         if (iKeyMapping[index].contains(aChar))
       
   354             {
       
   355 			return ArrayIndexToMappedChar(index);
       
   356             }
       
   357         }
       
   358 
       
   359 #if _DEBUG
       
   360 	TUint ch = aChar.unicode();
       
   361 	PRINT2(_L("CPcsKeyMap::MappedKeyForChar no mapping for char '%c' (0x%x)"),
       
   362 		   ch, ch);
       
   363 #endif
       
   364 	return iPadChar;
       
   365     }
       
   366 #endif // #if defined(USE_ORBIT_KEYMAP)
       
   367 
       
   368 // End of file