diff -r 000000000000 -r 876b1a06bc25 plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp Wed Aug 25 15:49:42 2010 +0300 @@ -0,0 +1,368 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Retrieves the character map for each of the numeric keys. +*/ + +// INCLUDE FILES +#include "cpcskeymap.h" +#include +#include + +#if defined(USE_ORBIT_KEYMAP) +#include +#include +#endif // #if defined(USE_ORBIT_KEYMAP) + +// This macro suppresses log writes +//#define NO_PRED_SEARCH_LOGS +#include "predictivesearchlog.h" + +const QChar KSpaceChar = ' '; + +// Separator character stored in predictive search table columns +const QChar KSeparatorChar = ' '; + + +// ============================== MEMBER FUNCTIONS ============================ + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::~CPcsKeyMap +// ---------------------------------------------------------------------------- +CPcsKeyMap::~CPcsKeyMap() + { + PRINT(_L("Enter CPcsKeyMap::~CPcsKeyMap")); + PRINT(_L("End CPcsKeyMap::~CPcsKeyMap")); + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::GetMappedStringL +// ---------------------------------------------------------------------------- +HBufC* CPcsKeyMap::GetMappedStringL(const TDesC& aSource) const + { + 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; + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::GetMappedString +// ---------------------------------------------------------------------------- +QString CPcsKeyMap::GetMappedString(QString aSource) const + { +#if defined(WRITE_PRED_SEARCH_LOGS) + const int KLogLength = 30; + TBuf log(aSource.left(KLogLength).utf16()); + PRINT1(_L("Enter CPcsKeyMap::GetMappedString input '%S'"), &log); +#endif + + QString destination; + TBool skipHashStar = DetermineSpecialCharBehaviour(aSource); + TInt length = aSource.length(); + + for (int i = 0; i < length; ++i) + { + if (aSource[i] == KSpaceChar) + { + destination.append(KSeparatorChar); + } + else + { + QChar ch(0); +#if defined(USE_ORBIT_KEYMAP) + ch = MappedKeyForChar(aSource[i]); +#else + 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; + } + +// ---------------------------------------------------------------------------- +// 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) +// ---------------------------------------------------------------------------- +// CPcsKeyMap::Separator +// ---------------------------------------------------------------------------- +QChar CPcsKeyMap::Separator() const + { + return KSeparatorChar; + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::SetHardcodedCharacters +// Default implementation selects only the current default language. +// ---------------------------------------------------------------------------- +QList CPcsKeyMap::SelectLanguages() + { + QList languages; + HbInputLanguage inputLanguage(QLocale::system().language()); + languages << inputLanguage; + return languages; + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::SetHardcodedCharacters +// Default implementation does nothing +// ---------------------------------------------------------------------------- +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, + { + InitKeyMappings(); + SetHardcodedCharacters(); + ConstructLanguageMappings(aKeyboardType); + }); + if (err != KErrNone) + { + 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::ConstructLanguageMappings +// Fetch keymap for selected languages. +// ---------------------------------------------------------------------------- +void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType) + { + PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings")); + +#if defined(WRITE_PRED_SEARCH_LOGS) + TInt count(0); +#endif + + QList 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"), + languages[lang].language(), + languages[lang].variant()); + const HbKeymap* keymap = + HbKeymapFactory::instance()->keymap(languages[lang].language(), + languages[lang].variant()); + if (keymap) + { + for (TInt key = 0; key < iAmountOfKeys; ++key) + { + 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.." + const QString upperCase = mappedKey->characters(HbModifierShiftPressed); // "ABC2.." + const QString charsForKey = lowerCase + upperCase; + + // Filter out duplicate characters + for (TInt i = charsForKey.length() - 1; i >= 0 ; --i) + { + QChar ch = charsForKey[i]; + if (!iKeyMapping[key].contains(ch) && + !iHardcodedChars.contains(ch)) + { +#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 // #if defined(WRITE_PRED_SEARCH_LOGS) + iKeyMapping[key] += ch; + } + } + } + } + } + else + { + PRINT(_L("CPcsKeyMap::ContructKeyboardMapping keymap not found")); + } + } + } + +#if defined(WRITE_PRED_SEARCH_LOGS) + PRINT1(_L("End CPcsKeyMap::ConstructLanguageMappings keymap has %d chars"), count); +#endif + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::IsLanguageSupported +// ---------------------------------------------------------------------------- +TBool CPcsKeyMap::IsLanguageSupported(QLocale::Language aLanguage) const + { + return (aLanguage != QLocale::Japanese && aLanguage != QLocale::Chinese); + } + +// ---------------------------------------------------------------------------- +// CPcsKeyMap::MappedKeyForChar +// Loop all QStrings of iKeyMapping to find one containing the character. +// If the character is not mapped, use pad character. +// ---------------------------------------------------------------------------- +const QChar CPcsKeyMap::MappedKeyForChar(const QChar aChar) const + { + for (TInt index = 0; index < iAmountOfKeys; ++index) + { + if (iKeyMapping[index].contains(aChar)) + { + return ArrayIndexToMappedChar(index); + } + } + +#if _DEBUG + TUint ch = aChar.unicode(); + PRINT2(_L("CPcsKeyMap::MappedKeyForChar no mapping for char '%c' (0x%x)"), + ch, ch); +#endif + return iPadChar; + } +#endif // #if defined(USE_ORBIT_KEYMAP) + +// End of file