--- a/phonebookengines/contactsmodel/cntplsql/src/cpcskeymap.cpp Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpcskeymap.cpp Wed Jun 23 18:02:44 2010 +0300
@@ -16,98 +16,27 @@
// INCLUDE FILES
#include "cpcskeymap.h"
+#include <QChar>
+#include <QString>
#if defined(USE_ORBIT_KEYMAP)
-
-// If defined, only the currently used language's keymap is used
-//#define USE_ONLY_DEFAULT_LANG_KEYMAP
-
-
-#include <QLocale>
-#include <hbinputlanguage.h>
#include <hbinputkeymap.h>
#include <hbinputkeymapfactory.h>
#endif // #if defined(USE_ORBIT_KEYMAP)
-
-#if defined(_DEBUG)
-#include <e32debug.h> // RDebug
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
-#define PRINT(x) RDebug::Print(x)
-#define PRINT1(x,y) RDebug::Print(x,y)
-#define PRINT2(x,y,z) RDebug::Print(x,y,z)
-#define PRINT3(w,x,y,z) RDebug::Print(w,x,y,z)
-#else // #if defined(_DEBUG)
-#define PRINT(x)
-#define PRINT1(x,y)
-#define PRINT2(x,y,z)
-#define PRINT3(w,x,y,z)
-#endif // #if defined(_DEBUG)
-
-
-#define KSpaceChar ' '
-
-#if defined(USE_ORBIT_KEYMAP)
-#define KSeparatorChar ' '
-#endif // #if defined(USE_ORBIT_KEYMAP)
+const QChar KSpaceChar = ' ';
// Separator character stored in predictive search table columns
-_LIT(KSeparator, " ");
-
-#if defined(USE_ORBIT_KEYMAP)
-// How many keys have mappings in ITU-T keypad (keys 0..9, * and # have mappings)
-const TInt KAmountOfKeys = 12;
-
-// The first key of the keyboard has value zero ('1' in the 12-key virtual keypad)
-enum TKeyId
- {
- EKey1 = 0,
- EKey2,
- EKey3,
- EKey4,
- EKey5,
- EKey6,
- EKey7,
- EKey8,
- EKey9,
- EKey0,
- EKeyStar,
- EKeyHash,
- ELastKey = EKeyHash
- };
-
-const QChar KStar = '*';
-const QChar KPlus = '+';
-const QChar KHash = '#';
-#endif // #if defined(USE_ORBIT_KEYMAP)
-
-// * key is mapped to this
-const TChar KMappedCharForStar = 'a';
-// # key is mapped to this
-const TChar KMappedCharForHash = 'b';
-// Unmapped (unknown) characters are replaced with this
-const TChar KPadChar = 'f';
+const QChar KSeparatorChar = ' ';
// ============================== MEMBER FUNCTIONS ============================
// ----------------------------------------------------------------------------
-// CPcsKeyMap::NewL
-// ----------------------------------------------------------------------------
-CPcsKeyMap* CPcsKeyMap::NewL()
- {
- PRINT(_L("Enter CPcsKeyMap::NewL"));
-
- CPcsKeyMap* self = new (ELeave) CPcsKeyMap();
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
-
- PRINT(_L("End CPcsKeyMap::NewL"));
- return self;
- }
-
-// ----------------------------------------------------------------------------
// CPcsKeyMap::~CPcsKeyMap
// ----------------------------------------------------------------------------
CPcsKeyMap::~CPcsKeyMap()
@@ -117,40 +46,93 @@
}
// ----------------------------------------------------------------------------
-// CPcsKeyMap::GetNumericKeyStringL
-// If aPlainConversion is EFalse, supports sub-string searches and space is
-// converted to a separator character (not zero).
+// CPcsKeyMap::GetMappedStringL
// ----------------------------------------------------------------------------
-HBufC* CPcsKeyMap::GetNumericKeyStringL(const TDesC& aSource,
- TBool aPlainConversion) const
+HBufC* CPcsKeyMap::GetMappedStringL(const TDesC& aSource) const
{
- PRINT1(_L("Enter CPcsKeyMap::GetNumericKeyStringL input '%S'"), &aSource);
+ PRINT1(_L("Enter CPcsKeyMap::GetMappedStringL input '%S'"), &aSource);
+
+ QString source((QChar*)aSource.Ptr(), aSource.Length());
+ QString result;
+ TInt err(KErrNone);
+ QT_TRYCATCH_ERROR(err, result = GetMappedString(source));
+ User::LeaveIfError(err);
+
+ HBufC* destination = HBufC::NewL(result.length());
+ destination->Des().Copy(result.utf16());
+
+ PRINT1(_L("End CPcsKeyMap::GetMappedStringL result '%S'"), destination);
+ return destination;
+ }
- TInt length = aSource.Length();
- HBufC* destination = HBufC::NewL(length);
- TPtr ptr = destination->Des();
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::GetMappedString
+// ----------------------------------------------------------------------------
+QString CPcsKeyMap::GetMappedString(QString aSource) const
+ {
+#if defined(WRITE_PRED_SEARCH_LOGS)
+ const int KLogLength = 30;
+ TBuf<KLogLength> log(aSource.left(KLogLength).utf16());
+ PRINT1(_L("Enter CPcsKeyMap::GetMappedString input '%S'"), &log);
+#endif
- for (TInt i = 0; i < aSource.Length(); ++i)
+ QString destination;
+ TBool skipHashStar = DetermineSpecialCharBehaviour(aSource);
+ TInt length = aSource.length();
+
+ for (int i = 0; i < length; ++i)
{
- if (!aPlainConversion && aSource[i] == KSpaceChar)
+ if (aSource[i] == KSpaceChar)
{
- ptr.Append(KSeparator);
+ destination.append(KSeparatorChar);
}
else
- {
+ {
+ QChar ch(0);
#if defined(USE_ORBIT_KEYMAP)
- ptr.Append(KeyForCharacter(aSource[i]));
+ ch = MappedKeyForChar(aSource[i]);
#else
- TChar a = aSource[i];
- TChar b = a.GetUpperCase();
- ptr.Append(GetNumericValueForChar(b));
+ ch = UseHardcodedKeyMap(aSource[i]);
+#endif
+ if (!ShouldSkipChar(ch, skipHashStar))
+ {
+ destination.append(ch);
+ }
+ }
+ }
+#if defined(WRITE_PRED_SEARCH_LOGS)
+ log = destination.left(KLogLength).utf16();
+ PRINT1(_L("End CPcsKeyMap::GetMappedString result '%S'"), &log);
#endif
- }
- }
+ return destination;
+ }
- PRINT1(_L("End CPcsKeyMap::GetNumericKeyStringL result '%S'"), destination);
- return destination;
- }
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::GetNumericLimitsL
+// In order to speed up the execution, caller should convert search pattern
+// with a one call to CPcsKeyMap::GetMappedStringL() and then pass the tokens
+// to CPcsKeyMap::GetNumericLimitsL().
+// So it is expected that aString contains only certain characters.
+// ----------------------------------------------------------------------------
+TInt CPcsKeyMap::GetNumericLimits(QString aString,
+ QString& aLowerLimit,
+ QString& aUpperLimit) const
+ {
+ PRINT(_L("CPcsKeyMap::GetNumericLimits"));
+ if (aString.length() > iMaxKeysStoredInDb)
+ {
+ QString truncated = aString.left(iMaxKeysStoredInDb);
+ aString = truncated;
+ }
+
+ TInt err = ComputeValue(aString, EFalse, aLowerLimit);
+ if (err == KErrNone)
+ {
+ err = ComputeValue(aString, ETrue, aUpperLimit);
+ }
+ PRINT1(_L("End CPcsKeyMap::GetNumericLimits ret=%d"), err);
+ return err;
+ }
#if defined(USE_ORBIT_KEYMAP)
// ----------------------------------------------------------------------------
@@ -162,79 +144,146 @@
}
// ----------------------------------------------------------------------------
-// CPcsKeyMap::CPcsKeyMap
-// Fill QList with empty strings
+// CPcsKeyMap::SetHardcodedCharacters
+// Default implementation selects only the current default language.
+// ----------------------------------------------------------------------------
+QList<HbInputLanguage> CPcsKeyMap::SelectLanguages()
+ {
+ QList<HbInputLanguage> languages;
+ HbInputLanguage inputLanguage(QLocale::system().language());
+ languages << inputLanguage;
+ return languages;
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::SetHardcodedCharacters
+// Default implementation does nothing
// ----------------------------------------------------------------------------
-CPcsKeyMap::CPcsKeyMap() :
- iKeyMapping()
+void CPcsKeyMap::SetHardcodedCharacters()
+ {
+ }
+#endif // #if defined(USE_ORBIT_KEYMAP)
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::DetermineSpecialCharBehaviour
+// Default implementation
+// ----------------------------------------------------------------------------
+TBool CPcsKeyMap::DetermineSpecialCharBehaviour(QString /*aSource*/) const
{
+ return EFalse;
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::ShouldSkipChar
+// Default implementation
+// ----------------------------------------------------------------------------
+TBool CPcsKeyMap::ShouldSkipChar(QChar /*aChar*/, TBool /*aSkipHashStar*/) const
+ {
+ return EFalse;
}
// ----------------------------------------------------------------------------
// CPcsKeyMap::ConstructL
// ----------------------------------------------------------------------------
+#if defined(USE_ORBIT_KEYMAP)
+void CPcsKeyMap::ConstructL(HbKeyboardType aKeyboardType)
+#else
void CPcsKeyMap::ConstructL()
+#endif
{
+ PRINT(_L("Enter CPcsKeyMap::ConstructL"));
+
+#if defined(USE_ORBIT_KEYMAP)
TInt err(KErrNone);
- QT_TRYCATCH_ERROR(err, ContructKeyboardMappings());
- if (err != KErrNone)
+ QT_TRYCATCH_ERROR(err,
+ {
+ InitKeyMappings();
+ SetHardcodedCharacters();
+ ConstructLanguageMappings(aKeyboardType);
+ });
+ if (err != KErrNone)
{
- PRINT1(_L("ContructKeyboardMappings threw exception, err=%d"), err);
+ PRINT1(_L("CPcsKeyMap::ConstructL exception, err=%d"), err);
User::Leave(err);
}
+#endif
+
+ PRINT(_L("End CPcsKeyMap::ConstructL"));
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::CPcsKeyMap
+// ----------------------------------------------------------------------------
+#if defined(USE_ORBIT_KEYMAP)
+CPcsKeyMap::CPcsKeyMap(TInt aAmountOfKeys,
+ QChar aPadChar,
+ TInt aMaxKeysStoredInDb) :
+ iKeyMapping(),
+ iAmountOfKeys(aAmountOfKeys),
+ iPadChar(aPadChar),
+ iMaxKeysStoredInDb(aMaxKeysStoredInDb)
+ {
+ }
+#else // #if defined(USE_ORBIT_KEYMAP)
+CPcsKeyMap::CPcsKeyMap(TInt /*aAmountOfKeys*/,
+ QChar /*aPadChar*/,
+ TInt aMaxKeysStoredInDb) :
+ iMaxKeysStoredInDb(aMaxKeysStoredInDb)
+ {
+ }
+#endif // #if defined(USE_ORBIT_KEYMAP)
+
+#if defined(USE_ORBIT_KEYMAP)
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::InitKeyMappings
+// Put string for each key into iKeyMapping.
+// ----------------------------------------------------------------------------
+void CPcsKeyMap::InitKeyMappings()
+ {
+ PRINT(_L("Enter CPcsKeyMap::InitKeyMappings"));
+
+ for (TInt i = 0; i < iAmountOfKeys; ++i)
+ {
+ iKeyMapping << QString("");
+ }
}
// ----------------------------------------------------------------------------
-// CPcsKeyMap::ContructKeyboardMappings
-// Fetch keymap for every language/country pair present.
-// Even though most languages map *, + and # to 1-key, they are here mapped to
-// the distinct *-key or #-key of the 12-key ITU-T keypad.
+// CPcsKeyMap::ConstructLanguageMappings
+// Fetch keymap for selected languages.
// ----------------------------------------------------------------------------
-void CPcsKeyMap::ContructKeyboardMappings()
+void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType)
{
- PRINT(_L("Enter CPcsKeyMap::ContructKeyboardMappings"));
+ PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings"));
- for (TInt i = 0; i < KAmountOfKeys; ++i)
- {
- iKeyMapping << QString("");
- }
-
- iKeyMapping[EKeyStar].append(KStar);
- iKeyMapping[EKeyStar].append(KPlus);
- iKeyMapping[EKeyHash].append(KHash);
- iHardcodedChars.append(KStar);
- iHardcodedChars.append(KPlus);
- iHardcodedChars.append(KHash);
-
-#if defined(_DEBUG)
+#if defined(WRITE_PRED_SEARCH_LOGS)
TInt count(0);
#endif
- QList<HbInputLanguage> languages;
-#if defined(USE_ONLY_DEFAULT_LANG_KEYMAP)
- HbInputLanguage inputLanguage(QLocale::system().language());
- languages << inputLanguage;
-#else
- languages = AvailableLanguages();
-#endif
+
+ QList<HbInputLanguage> languages = SelectLanguages();
+ PRINT1(_L("build keymap from %d language(s)"), languages.count());
+
TInt languageCount = languages.size();
for (TInt lang = 0; lang < languageCount; ++lang)
{
PRINT2(_L("(%d) handle language %d"), lang, languages[lang].language());
if (IsLanguageSupported(languages[lang].language()))
{
-/* PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
+ PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
languages[lang].language(),
- languages[lang].variant()); */
+ languages[lang].variant());
const HbKeymap* keymap =
HbKeymapFactory::instance()->keymap(languages[lang].language(),
languages[lang].variant());
if (keymap)
{
- for (TInt key = EKey1; key <= ELastKey; ++key)
+ for (TInt key = 0; key < iAmountOfKeys; ++key)
{
-// PRINT1(_L("handle key(enum value %d)"), key); // test
- const HbMappedKey* mappedKey = keymap->keyForIndex(HbKeyboardVirtual12Key, key);
- // mappedKey can be NULL, as most languages don't have mapping for EKeyStar, EKeyHash
+ PRINT1(_L("handle key(enum value %d)"), key); // test
+ const HbMappedKey* mappedKey = keymap->keyForIndex(aKeyboardType, key);
+ // 12-key: Most languages don't have mapping for EKeyStar, EKeyHash.
+ // QWERTY: Different languages have different amount of keys,
+ // so mappedKey can be NULL.
if (mappedKey)
{
const QString lowerCase = mappedKey->characters(HbModifierNone); // "abc2.."
@@ -248,13 +297,24 @@
if (!iKeyMapping[key].contains(ch) &&
!iHardcodedChars.contains(ch))
{
-/* PRINT3(_L("CPcsKeyMap: map key(%d) <-> char='%c'(0x%x)"),
- KeyIdToNumber(key),
- ch.toAscii(),
- ch.toAscii()); */
-#if defined(_DEBUG)
+#if defined(WRITE_PRED_SEARCH_LOGS)
+ char ascChar = ch.toAscii();
+ TChar logChar(ArrayIndexToMappedChar(key).unicode());
+
+ if (ascChar == 0) // ch can't be represented in ASCII
+ {
+ PRINT2(_L("CPcsKeyMap: map key(%c) <-> char=0x%x"),
+ logChar, ch);
+ }
+ else
+ {
+ PRINT3(_L("CPcsKeyMap: map key(%c) <-> char='%c'(0x%x)"),
+ logChar,
+ ascChar,
+ ascChar);
+ }
++count;
-#endif
+#endif // #if defined(WRITE_PRED_SEARCH_LOGS)
iKeyMapping[key] += ch;
}
}
@@ -268,47 +328,12 @@
}
}
-#if defined(_DEBUG)
- PRINT1(_L("End CPcsKeyMap::ContructKeyboardMappings keymap has %d chars"), count);
+#if defined(WRITE_PRED_SEARCH_LOGS)
+ PRINT1(_L("End CPcsKeyMap::ConstructLanguageMappings keymap has %d chars"), count);
#endif
}
// ----------------------------------------------------------------------------
-// CPcsKeyMap::AvailableLanguages
-// Put default language at the beginning of the language list, so that
-// ContructKeyboardMappingsL handles it first.
-// ----------------------------------------------------------------------------
-QList<HbInputLanguage> CPcsKeyMap::AvailableLanguages() const
- {
- PRINT(_L("Enter CPcsKeyMap::AvailableLanguages"));
-
- QList<HbInputLanguage> languages = HbKeymapFactory::availableLanguages();
-
-#if 1 // This code would make sure the default language is at the beginning of
- // list of available languages. But since there is resource leak, the code
- // is currently commented out until the leak is fixed.
- QLocale::Language currentLanguage = QLocale::system().language();
- if (!IsLanguageSupported(currentLanguage))
- {
- PRINT(_L("current lang not supported, use english")); //test
- currentLanguage = QLocale::English;
- }
- HbInputLanguage defaultLanguage(currentLanguage);
- if (languages.contains(defaultLanguage))
- {
- PRINT(_L("remove default lang")); //test
- languages.removeOne(defaultLanguage);
- }
- PRINT(_L("insert default lang as first lang")); //test
- languages.prepend(defaultLanguage); // THIS LEAKS RESOURCES!
-#endif
-
- PRINT1(_L("End CPcsKeyMap::AvailableLanguages found %d languages"),
- languages.count());
- return languages;
- }
-
-// ----------------------------------------------------------------------------
// CPcsKeyMap::IsLanguageSupported
// ----------------------------------------------------------------------------
TBool CPcsKeyMap::IsLanguageSupported(QLocale::Language aLanguage) const
@@ -317,170 +342,26 @@
}
// ----------------------------------------------------------------------------
-// CPcsKeyMap::KeyForCharacter
+// CPcsKeyMap::MappedKeyForChar
// Loop all QStrings of iKeyMapping to find one containing the character.
-// If the character is not mapped, use the character itself.
+// If the character is not mapped, use pad character.
// ----------------------------------------------------------------------------
-TChar CPcsKeyMap::KeyForCharacter(const TChar& aChar) const
+const QChar CPcsKeyMap::MappedKeyForChar(const QChar aChar) const
{
- TUint charValue(aChar);
- QChar ch(charValue);
- for (TInt index = 0; index < KAmountOfKeys; ++index)
+ for (TInt index = 0; index < iAmountOfKeys; ++index)
{
- if (iKeyMapping[index].contains(ch))
+ if (iKeyMapping[index].contains(aChar))
{
- return ArrayIndexToNumberChar(index);
+ return ArrayIndexToMappedChar(index);
}
}
- PRINT2(_L("CPcsKeyMap::KeyForCharacter no mapping for char '%c' (0x%x)"),
- (TUint)aChar, (TUint)aChar);
- return KPadChar;
- }
-
-#if defined(_DEBUG)
-// ----------------------------------------------------------------------------
-// CPcsKeyMap::KeyIdToNumber
-// Map Orbit API's key id to the number that the key results when pressed.
-// ----------------------------------------------------------------------------
-TInt CPcsKeyMap::KeyIdToNumber(TInt aKeyId) const
- {
- switch (aKeyId)
- {
- case EKey1:
- case EKey2:
- case EKey3:
- case EKey4:
- case EKey5:
- case EKey6:
- case EKey7:
- case EKey8:
- case EKey9:
- case EKeyStar:
- case EKeyHash:
- return aKeyId + 1;
- case EKey0:
- return 0;
- default:
- PRINT1(_L("CPcsKeyMap::KeyIdToNumber invalid index %d"), aKeyId);
- User::Panic(_L("CPcsKeyMap::KeyIdToNumber"), KErrArgument);
- return 0;
- }
- }
+#if _DEBUG
+ TUint ch = aChar.unicode();
+ PRINT2(_L("CPcsKeyMap::MappedKeyForChar no mapping for char '%c' (0x%x)"),
+ ch, ch);
#endif
-
-// ----------------------------------------------------------------------------
-// CPcsKeyMap::ArrayIndexToNumberChar
-// Map index of iKeyMapping list, to the number char that the mapping is for.
-// ----------------------------------------------------------------------------
-TChar CPcsKeyMap::ArrayIndexToNumberChar(TInt aArrayIndex) const
- {
- __ASSERT_DEBUG(aArrayIndex < KAmountOfKeys,
- User::Panic(_L("CPcsKeyMap::ArrayIndexToNumberChar"),
- KErrOverflow));
- switch (aArrayIndex)
- {
- case EKey0:
- return '0';
- case EKeyStar:
- return KMappedCharForStar;
- case EKeyHash:
- return KMappedCharForHash;
- default:
- return aArrayIndex + '1';
- }
- }
-#else // #if defined(USE_ORBIT_KEYMAP)
-CPcsKeyMap::CPcsKeyMap()
- {
- }
-
-void CPcsKeyMap::ConstructL()
- {
- }
-
-TChar CPcsKeyMap::GetNumericValueForChar(TChar input) const
- {
- TChar ret = '0';
- switch (input)
- {
- case 'A':
- case 'B':
- case 'C':
- ret = '2';
- break;
-
- case 'D':
- case 'E':
- case 'F':
- ret = '3';
- break;
-
- case 'G':
- case 'H':
- case 'I':
- ret = '4';
- break;
-
- case 'J':
- case 'K':
- case 'L':
- ret = '5';
- break;
-
- case 'M':
- case 'N':
- case 'O':
- ret = '6';
- break;
-
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- ret = '7';
- break;
-
- case 'T':
- case 'U':
- case 'V':
- ret = '8';
- break;
-
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- ret = '9';
- break;
-
- case '*':
- case '+':
- ret = KMappedCharForStar;
- break;
-
- case '#':
- ret = KMappedCharForHash;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case ' ':
- ret = input; // Numbers and space
- break;
-
- default: // Other (unknown) chars
- ret = KPadChar;
- }
- return ret;
+ return iPadChar;
}
#endif // #if defined(USE_ORBIT_KEYMAP)