predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Helper.cpp
changeset 0 e686773b3f54
child 7 b3431bff8c19
--- /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
+
+