--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Helper.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1016 @@
+/*
+* Copyright (c) 2007 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: Predictive Contact Search Algorithm 1 helper class
+*
+*/
+
+// INCLUDES
+#include <FindUtil.h>
+#include "FindUtilChineseECE.h"
+#include "CPcsAlgorithm2.h"
+#include "CPcsAlgorithm2Helper.h"
+#include "CPcsAlgorithm2Utils.h"
+#include "CPcsDebug.h"
+#include "CPcsCache.h"
+#include "CPcsKeyMap.h"
+#include "CPsData.h"
+#include "CWords.h"
+#include "CPsQuery.h"
+#include "CPsQueryItem.h"
+#include "CPsDataPluginInterface.h"
+#include "CPcsPoolElement.h"
+
+// Compare functions
+TBool Compare1(const TDesC& aFirst, const TDesC& aSecond)
+ {
+ return aFirst == aSecond;
+ }
+
+TBool Compare2(const TDesC& aFirst, const TDesC& aSecond)
+ {
+ return CPcsAlgorithm2Utils::MyCompareC(aFirst, aSecond);
+ }
+
+// ============================== MEMBER FUNCTIONS ============================
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::NewL
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+CPcsAlgorithm2Helper* CPcsAlgorithm2Helper::NewL(CPcsAlgorithm2* aAlgorithm)
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::NewL") );
+
+ CPcsAlgorithm2Helper* self = new (ELeave) CPcsAlgorithm2Helper();
+ CleanupStack::PushL(self);
+ self->ConstructL(aAlgorithm);
+ CleanupStack::Pop(self);
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::NewL") );
+
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::CPcsAlgorithm2Helper
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+CPcsAlgorithm2Helper::CPcsAlgorithm2Helper()
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::CPcsAlgorithm2") );
+ PRINT ( _L("End CPcsAlgorithm2Helper::CPcsAlgorithm2") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::ConstructL
+// Two Phase Construction
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::ConstructL(CPcsAlgorithm2* aAlgorithm)
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::ConstructL") );
+
+ iAlgorithm = aAlgorithm;
+ keyMap = iAlgorithm->GetKeyMap();
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::ConstructL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::CPcsAlgorithm2Helper
+// Destructor
+// ----------------------------------------------------------------------------
+CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper()
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper") );
+ iSearchResultsArr.ResetAndDestroy();
+ PRINT ( _L("End CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::SearchMixedL
+// Search function for input with both ITU-T and QWERTY mode
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::SearchMixedL(const CPsSettings& aSettings,
+ CPsQuery& aPsQuery, TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup,
+ RPointerArray<CPsData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
+ {
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchMixedL") );
+
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMixedL") );
+
+ // Create filtering helper for the required sort type
+ TSortType sortType = aSettings.GetSortType();
+ CPcsAlgorithm2FilterHelper* filterHelper =
+ CPcsAlgorithm2FilterHelper::NewL(sortType);
+
+ // Convert the search condition to numeric key string
+ TBuf<KPsQueryMaxLen> numericKeyStr;
+ TPtrC queryPtr = aPsQuery.QueryAsStringLC();
+ keyMap->GetNumericKeyString(queryPtr, numericKeyStr);
+ PRINT2 ( _L("Numeric Key String for %S = %S"), &queryPtr, &numericKeyStr );
+
+ // Reset the result set array for new search
+ iSearchResultsArr.ResetAndDestroy();
+
+ // Get the data stores
+ RPointerArray<TDesC> aDataStores;
+ aSettings.SearchUrisL(aDataStores);
+
+ // Get the required display fields from the client
+ RArray<TInt> requiredDataFields;
+ aSettings.DisplayFieldsL(requiredDataFields);
+
+ // Search based on first key str
+ TInt numValue = keyMap->PoolIdForCharacter(numericKeyStr[0]);
+
+ // Perform search for each required data store
+ RPointerArray<CPcsPoolElement> elements;
+
+ for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
+ {
+
+ RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
+ iSearchResultsArr.Append(temp);
+
+ // Get the contents for this data store
+ TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
+ if (arrayIndex < 0)
+ {
+ continue;
+ }
+ CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
+ cache->GetContactsForKeyL(numValue, elements);
+
+ // Perform filtering
+ FilterResultsMixedL(filterHelper, elements, aPsQuery,
+ isSearchInGroup, aContactsInGroup);
+
+ // If alphabetical sorting, get the results for this datastore
+ if (sortType == EAlphabetical)
+ {
+ filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
+ }
+
+ elements.Reset();
+ }
+
+ aDataStores.ResetAndDestroy();
+ requiredDataFields.Reset();
+
+ // If alphabetical sorting, merge the result sets of all datastores
+ if (sortType == EAlphabetical)
+ {
+ // Form the complete searchResults array
+ CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
+ searchResults);
+ }
+ else
+ {
+ // Results are already sorted pattern based
+ filterHelper->GetResults(searchResults);
+ }
+
+ // Get the sorted match sequence list
+ filterHelper->GetPatternsL(searchSeqs);
+
+ PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
+
+ // Cleanup
+ for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
+ {
+ iSearchResultsArr[i]->Reset();
+ delete iSearchResultsArr[i];
+ iSearchResultsArr[i] = NULL;
+ }
+
+ iSearchResultsArr.Reset();
+
+ CleanupStack::PopAndDestroy(); // query
+ delete filterHelper;
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::SearchMixedL") );
+
+ __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchMixedL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::SearchITUL
+// Search function for ITU-T style
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::SearchITUL(const CPsSettings& aSettings,
+ CPsQuery& aPsQuery, TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup,
+ RPointerArray<CPsData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
+ {
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchITUL") );
+
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchITUL") );
+
+ // Create filtering helper for the required sort type
+ TSortType sortType = aSettings.GetSortType();
+ CPcsAlgorithm2FilterHelper* filterHelper =
+ CPcsAlgorithm2FilterHelper::NewL(sortType);
+
+ // Convert the search condition to numeric key string
+ TBuf<KPsQueryMaxLen> numericKeyStr;
+ TPtrC queryPtr = aPsQuery.QueryAsStringLC();
+ keyMap->GetNumericKeyString(queryPtr, numericKeyStr);
+ PRINT2 ( _L("Numeric Key String for %S = %S"), &queryPtr, &numericKeyStr );
+ TInt numValue = keyMap->PoolIdForCharacter(numericKeyStr[0]);
+
+ // Reset the result set array for new search
+ iSearchResultsArr.ResetAndDestroy();
+
+ // Get the data stores
+ RPointerArray<TDesC> aDataStores;
+ aSettings.SearchUrisL(aDataStores);
+
+ // Get the required display fields from the client
+ RArray<TInt> requiredDataFields;
+ aSettings.DisplayFieldsL(requiredDataFields);
+
+ // Perform search for each required data store
+ RPointerArray<CPcsPoolElement> elements;
+
+ for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
+ {
+ RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
+ iSearchResultsArr.Append(temp);
+
+ // Get the contents for this data store
+ TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
+ if (arrayIndex < 0)
+ {
+ continue;
+ }
+ CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
+ cache->GetContactsForKeyL(numValue, elements);
+
+ // Perform filtering
+ FilterResultsL(filterHelper, elements, numericKeyStr,
+ isSearchInGroup, aContactsInGroup);
+
+ // If alphabetical sorting, get the results for this datastore
+ if (sortType == EAlphabetical)
+ {
+ filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
+ }
+
+ elements.Reset();
+ }
+
+ aDataStores.ResetAndDestroy();
+ requiredDataFields.Reset();
+
+ // If alphabetical sorting, merge the result sets of all datastores
+ if (sortType == EAlphabetical)
+ {
+ // Merge the result sets of individual datastores alphabetically
+ CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
+ searchResults);
+ }
+ else
+ {
+ // Results are already sorted pattern based
+ filterHelper->GetResults(searchResults);
+ }
+
+ // Get the sorted match sequence list
+ filterHelper->GetPatternsL(searchSeqs);
+
+ PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
+
+ // Cleanup
+ for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
+ {
+ iSearchResultsArr[i]->Reset();
+ delete iSearchResultsArr[i];
+ iSearchResultsArr[i] = NULL;
+ }
+ iSearchResultsArr.Reset();
+
+ CleanupStack::PopAndDestroy(); // query
+ delete filterHelper;
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::SearchITUL") );
+ __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchITUL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::SearchQWERTYL
+// Search function for QWERTY style
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::SearchQWERTYL(const CPsSettings& aSettings,
+ CPsQuery& aPsQuery, TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup,
+ RPointerArray<CPsData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
+ {
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchQWERTYL") );
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchQWERTYL") );
+
+ // te filtering helper for the required sort type
+ TSortType sortType = aSettings.GetSortType();
+ CPcsAlgorithm2FilterHelper* filterHelper =
+ CPcsAlgorithm2FilterHelper::NewL(sortType);
+
+ // Convert the search condition to numeric key string
+ TBuf<KPsQueryMaxLen> numericKeyStr;
+ TPtrC queryPtr = aPsQuery.QueryAsStringLC();
+
+ TChar queryChar;
+
+ // Handle Chinese word search case: extract the first char of one of its spelling
+ // which will be used as search string
+ if (iAlgorithm->FindUtilECE()->IsChineseWord(queryPtr))
+ {
+ RPointerArray<HBufC> spellList;
+ if (iAlgorithm->FindUtilECE()->T9ChineseTranslationL(queryPtr[0], spellList))
+ {
+ queryChar = *(spellList[0]->Ptr());
+ }
+ else
+ {
+ queryChar = queryPtr[0];
+ }
+ spellList.ResetAndDestroy();
+ }
+ else
+ {
+ queryChar = queryPtr[0];
+ }
+
+ TInt numValue = keyMap->PoolIdForCharacter(queryChar);
+ // Reset the result set array for new search
+ iSearchResultsArr.ResetAndDestroy();
+
+ // Get the data stores
+ RPointerArray<TDesC> aDataStores;
+ aSettings.SearchUrisL(aDataStores);
+
+ // Get the required display fields from the client
+ RArray<TInt> requiredDataFields;
+ aSettings.DisplayFieldsL(requiredDataFields);
+
+ // Perform search for each of the required data stores
+ RPointerArray<CPcsPoolElement> elements;
+
+ for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
+ {
+
+ RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
+ iSearchResultsArr.Append(temp);
+
+ // Get the contents for this data store
+ TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
+ if (arrayIndex < 0)
+ {
+ continue;
+ }
+ CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
+ cache->GetContactsForKeyL(numValue, elements);
+
+ // Perform filtering
+ FilterResultsQwertyL(filterHelper, elements, queryPtr,
+ isSearchInGroup, aContactsInGroup);
+
+ // If alphabetical sorting, get the results for this datastore
+ if (sortType == EAlphabetical)
+ {
+ filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
+ }
+
+ elements.Reset();
+ }
+ aDataStores.ResetAndDestroy();
+ requiredDataFields.Reset();
+
+ // If alphabetical sorting, merge the result sets of all datastores
+ if (sortType == EAlphabetical)
+ {
+ // Form the complete searchResults array
+ CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
+ searchResults);
+ }
+ else
+ {
+ // Results are already sorted pattern based
+ filterHelper->GetResults(searchResults);
+ }
+
+ // Get the sorted match sequence list
+ filterHelper->GetPatternsL(searchSeqs);
+
+ PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
+
+ // Cleanup
+ for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
+ {
+ iSearchResultsArr[i]->Reset();
+ delete iSearchResultsArr[i];
+ iSearchResultsArr[i] = NULL;
+ }
+ iSearchResultsArr.Reset();
+
+ CleanupStack::PopAndDestroy(); // query
+ delete filterHelper;
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::SearchQWERTYL") );
+ __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchQWERTYL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::SearchMatchSeqL
+// Funciton to search matching sequences in the input text
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::SearchMatchSeqL(HBufC* /*aQuery*/, TDesC& aData,
+ RPointerArray<TDesC>& /*aMatchSet*/,
+ CPsQuery& /*aPsQuery*/,
+ RArray<TPsMatchLocation>& aMatchLocation)
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMatchSeqL") );
+
+ // Convert the data into words
+ TLex lex(aData);
+
+ // First word
+ TPtrC token = lex.NextToken();
+
+ TInt beg = lex.Offset() - token.Length(); // start index of match sequence
+
+ // Search thru multiple words
+ while (token.Length() != 0)
+ {
+ TPsMatchLocation tempLocation;
+
+ // check for directionality of the text
+ TBool found(EFalse);
+ TBidiText::TDirectionality dir = TBidiText::TextDirectionality(token, &found);
+
+ tempLocation.index = beg;
+ tempLocation.length = 0;
+ tempLocation.direction = dir;
+
+ // Add the match location to the data structure array
+ aMatchLocation.Append(tempLocation);
+
+ // Next word
+ token.Set(lex.NextToken());
+ beg = lex.Offset() - token.Length(); // start index of next word
+ }
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::SearchMatchSeqL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2::FilterResultsL
+// Subset search function
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::FilterResultsL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
+ RPointerArray<CPcsPoolElement>& searchSet,
+ const TDesC& searchQuery,
+ TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup)
+ {
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::FilterResultsL") );
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::FilterResultsL") );
+
+ // Convert the search condition to numeric key string
+ TBuf<KPsQueryMaxLen> tmpSearchQuery;
+ keyMap->GetNumericKeyString(searchQuery, tmpSearchQuery);
+
+ //Holds the first char of first name of a contact
+ TBuf<10> firstChar;
+
+ PRINT2 ( _L("Numeric Key String for %S = %S"), &searchQuery, &tmpSearchQuery );
+
+ // Parse thru each search set elements and filter the results
+ for (int index = 0; index < searchSet.Count(); index++)
+ {
+ CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
+ CPsData* psData = poolElement->GetPsData();
+ psData->ClearDataMatches();
+ RPointerArray<TDesC> tempMatchSeq;
+
+ // Search thru multiple words
+ TBuf<KBufferMaxLen> token;
+ TBuf<KBufferMaxLen> firstName;
+ TBuf<KBufferMaxLen> lastName;
+ lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
+ firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
+
+ CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
+ TBool matched = 0;
+
+ // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
+ // before the first name, otherwise intitial letter searching will not function
+ if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
+ {
+ token.Append(lastName);
+ if (firstName.Length())
+ {
+ firstChar.Zero();
+ firstChar.Append(firstName[0]);
+ if (!pFindUtilEce->IsChineseWord(firstChar) )
+ {
+ token.Append(KSpace);
+ }
+ token.Append(firstName);
+ }
+
+ if (token.Length() != 0)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(token, tmpSearchQuery, ECustomConverter, iAlgorithm);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+ else
+ {
+ // If contact name only has western word, then should send
+ // "first name","last name" and "last name + first name" to FindUtil to do the search
+ const TInt lastnameLen = lastName.Length();
+ const TInt firstnameLen = firstName.Length();
+ if(lastnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(lastName, tmpSearchQuery, ECustomConverter, iAlgorithm);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ }
+ }
+
+ if(!matched && firstnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(firstName, tmpSearchQuery, ECustomConverter, iAlgorithm);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+
+ token.Append(lastName);
+ token.Append(firstName);
+ if (!matched && lastnameLen && firstnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(token, tmpSearchQuery, ECustomConverter, iAlgorithm);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+
+ if (matched)
+ {
+ // Extract matched character sequence, don't need to be accurate for Chinese variant
+ const TInt len = 1;
+ HBufC* seq = HBufC::NewLC(len);
+ *seq = token.Mid(0, len);
+ seq->Des().UpperCase();
+
+ TIdentityRelation<TDesC> rule(Compare1);
+ if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
+ {
+ tempMatchSeq.Append(seq);
+ CleanupStack::Pop();
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy();
+ }
+
+
+ // Add the result
+ if (isSearchInGroup)
+ {
+ if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+ else
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+
+ // Cleanup the match sequence array as
+ // they are stored in pattern details structure
+ tempMatchSeq.ResetAndDestroy();
+ }
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsL") );
+ __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::FilterResultsL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::FilterResultsQwertyL
+// Subset search function
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::FilterResultsQwertyL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
+ RPointerArray<CPcsPoolElement>& searchSet,
+ const TDesC& searchQuery,TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup)
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2::FilterResultsQwertyL") );
+
+ TBuf<50> tmpSearchQuery = searchQuery;
+ tmpSearchQuery.LowerCase();
+
+ //Holds the first char of first name of a contact
+ TBuf<10> firstChar;
+
+ // Parse thru each search set elements and filter the results
+ for (int index = 0; index < searchSet.Count(); index++)
+ {
+ CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
+ CPsData* psData = poolElement->GetPsData();
+ psData->ClearDataMatches();
+ RPointerArray<TDesC> tempMatchSeq;
+
+ // Parse thru each data and filter the results
+ TBuf<KBufferMaxLen> token;
+ TBuf<KBufferMaxLen> firstName;
+ TBuf<KBufferMaxLen> lastName;
+ lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
+ firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
+
+ CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
+ TBool matched = 0;
+
+ // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
+ // before the first name, otherwise intitial letter searching will not function
+ if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
+ {
+ token.Append(lastName);
+ if (firstName.Length())
+ {
+ firstChar.Zero();
+ firstChar.Append(firstName[0]);
+ if (!pFindUtilEce->IsChineseWord(firstChar) )
+ {
+ token.Append(KSpace);
+ }
+ token.Append(firstName);
+ }
+
+ if (token.Length() != 0)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(token, tmpSearchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+ else
+ {
+ // If contact name only has western word, then should send
+ // "first name","last name" and "last name + first name" to FindUtil to do the search
+ const TInt lastnameLen = lastName.Length();
+ const TInt firstnameLen = firstName.Length();
+ if(lastnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(lastName, tmpSearchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ }
+ }
+
+ if(!matched && firstnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(firstName, tmpSearchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+
+ token.Append(lastName);
+ token.Append(firstName);
+ if (!matched && lastnameLen && firstnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(token, tmpSearchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+
+ if (matched)
+ {
+ // Extract matched character sequence, don't need to be accurate for Chinese variant
+ const TInt len = 1;
+ HBufC* seq = HBufC::NewLC(len);
+ *seq = token.Mid(0, len);
+ seq->Des().UpperCase();
+
+ TIdentityRelation<TDesC> rule(Compare1);
+ if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
+ {
+ tempMatchSeq.Append(seq);
+ CleanupStack::Pop();
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy();
+ }
+
+ // Add the result
+ if (isSearchInGroup)
+ {
+ if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+ else
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+
+ // Cleanup the match sequence array as
+ // they are stored in pattern details structure
+ tempMatchSeq.ResetAndDestroy();
+ }
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsQwertyL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::FilterResultsMixedL
+// Subset search function
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::FilterResultsMixedL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
+ RPointerArray<CPcsPoolElement>& searchSet,
+ CPsQuery& searchQuery, TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup)
+ {
+ PRINT ( _L("Enter CPcsAlgorithm2::FilterResultsMixedL") );
+
+ // Convert the search query to alpha numeric string
+ TBuf<50> tmpSearchQuery;
+ ExtractQueryL(searchQuery, tmpSearchQuery);
+ tmpSearchQuery.LowerCase();
+ TBuf<10> firstChar;
+
+ // Parse thru each search set elements and filter the results
+ for (int index = 0; index < searchSet.Count(); index++)
+ {
+ CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
+ CPsData* psData = poolElement->GetPsData();
+ psData->ClearDataMatches();
+ RPointerArray<TDesC> tempMatchSeq;
+
+ // Parse thru each data and filter the results
+ TBuf<255> token;
+ TBuf<KBufferMaxLen> firstName;
+ TBuf<KBufferMaxLen> lastName;
+ lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
+ firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
+
+ CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
+ TBool matched = 0;
+
+ // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
+ // before the first name, otherwise intitial letter searching will not function
+ if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
+ {
+ token.Append(lastName);
+ if (firstName.Length())
+ {
+ firstChar.Zero();
+ firstChar.Append(firstName[0]);
+ if (!pFindUtilEce->IsChineseWord(firstChar) )
+ {
+ token.Append(KSpace);
+ }
+ token.Append(firstName);
+ }
+
+ if (token.Length() != 0)
+ {
+ matched = pFindUtilEce->MatchRefineL(token, searchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+ else
+ {
+ // If contact name only has western word, then should send
+ // "first name","last name" and "last name + first name" to FindUtil to do the search
+ const TInt lastnameLen = lastName.Length();
+ const TInt firstnameLen = firstName.Length();
+ if(lastnameLen)
+ {
+ matched = pFindUtilEce->MatchRefineL(lastName, searchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ }
+ }
+
+ if(!matched && firstnameLen)
+ {
+ matched = pFindUtilEce->MatchRefineL(firstName, searchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+
+ token.Append(lastName);
+ token.Append(firstName);
+ if (!matched && lastnameLen && firstnameLen)
+ {
+ matched = pFindUtilEce->MatchRefineL(token, searchQuery);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+
+ if (matched)
+ {
+ // Extract matched character sequence, don't need to be accurate for Chinese variant
+ const TInt len = 1;
+
+ HBufC* seq = HBufC::NewLC(len);
+ *seq = token.Mid(0, len);
+ seq->Des().UpperCase();
+
+ TIdentityRelation<TDesC> rule(Compare1);
+ if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
+ {
+ tempMatchSeq.Append(seq);
+ CleanupStack::Pop();
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy();
+ }
+
+ // Add the result
+ if (isSearchInGroup)
+ {
+ if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+ else
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+
+ // Cleanup the match sequence array as
+ // they are stored in pattern details structure
+ tempMatchSeq.ResetAndDestroy();
+ }
+
+ PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsMixedL") );
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::SortSearchSeqsL()
+//
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::SortSearchSeqsL(RPointerArray<TDesC>& aSearchSeqs)
+ {
+ // Sort the search seqs
+ TLinearOrder<TDesC> rule(Compare2);
+ aSearchSeqs.Sort(rule);
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::ExtractQueryL()
+// Required for mixed mode search.
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
+ {
+ for (int i = 0; i < aQuery.Count(); i++)
+ {
+ if (aQuery.GetItemAtL(i).Mode() == EItut)
+ {
+ TBuf<KPsQueryMaxLen> outBuf;
+ keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
+ aOutput.Append(outBuf[i]);
+ CleanupStack::PopAndDestroy();
+ }
+ else
+ {
+ aOutput.Append(aQuery.GetItemAtL(i).Character());
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::ExtractQueryL()
+// Required for mixed mode search.
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
+ {
+ TInt len = -1;
+
+ if (aInput.Length() > aQuery.Count())
+ {
+ len = aQuery.Count();
+ }
+ else
+ {
+ len = aInput.Length();
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ if (aQuery.GetItemAtL(i).Mode() == EItut)
+ {
+ TBuf<KPsQueryMaxLen> outBuf;
+ keyMap->GetNumericKeyString(aInput, outBuf);
+ aOutput.Append(outBuf[i]);
+ }
+ else
+ {
+ aOutput.Append(aInput[i]);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::FilterDataFieldsL()
+// Constructs a bit pattern using the required/supported data fields
+// For example, 6, 4 and 27 are supported fields <-- 00000111
+// 6 and 4 are required fields <-- 00000011
+// Bit pattern returned is 00000011.
+// ----------------------------------------------------------------------------
+TUint8 CPcsAlgorithm2Helper::FilterDataFieldsL(RArray<TInt>& aRequiredDataFields,
+ RArray<TInt>& aSupportedDataFields)
+ {
+ TUint8 filteredMatch = 0x0;
+
+ for (int i = 0; i < aSupportedDataFields.Count(); i++)
+ {
+ for (int j = 0; j < aRequiredDataFields.Count(); j++)
+ {
+ if (aSupportedDataFields[i] == aRequiredDataFields[j])
+ {
+ TReal val;
+ Math::Pow(val, 2, i);
+
+ filteredMatch |= (TUint8) val;
+ }
+ }
+ }
+
+ return filteredMatch;
+ }
+
+// End of file
+
+