--- a/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Helper.cpp Wed Sep 15 11:56:55 2010 +0300
+++ b/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Helper.cpp Wed Oct 13 14:15:33 2010 +0300
@@ -16,7 +16,7 @@
*/
// INCLUDES
-#include <PbkGlobalSettingFactory.h>
+#include <FindUtil.h>
#include "FindUtilChineseECE.h"
#include "CPcsAlgorithm2.h"
#include "CPcsAlgorithm2Helper.h"
@@ -25,11 +25,22 @@
#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 ============================
@@ -59,7 +70,6 @@
{
PRINT ( _L("Enter CPcsAlgorithm2Helper::CPcsAlgorithm2") );
PRINT ( _L("End CPcsAlgorithm2Helper::CPcsAlgorithm2") );
- iMaxCount = 0;
}
// ----------------------------------------------------------------------------
@@ -71,18 +81,13 @@
PRINT ( _L("Enter CPcsAlgorithm2Helper::ConstructL") );
iAlgorithm = aAlgorithm;
- iKeyMap = iAlgorithm->GetKeyMap();
+ keyMap = iAlgorithm->GetKeyMap();
- iPbkSettings = PbkGlobalSettingFactory::CreatePersistentSettingL();
- iPbkSettings->ConnectL( MPbkGlobalSetting::EGeneralSettingCategory );
- iPbkSettings->RegisterObserverL( this );
- UpdateNameOrderL();
-
PRINT ( _L("End CPcsAlgorithm2Helper::ConstructL") );
}
// ----------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper
+// CPcsAlgorithm2Helper::CPcsAlgorithm2Helper
// Destructor
// ----------------------------------------------------------------------------
CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper()
@@ -93,323 +98,798 @@
}
// ----------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::SearchSingleL
+// CPcsAlgorithm2Helper::SearchMixedL
// Search function for input with both ITU-T and QWERTY mode
// ----------------------------------------------------------------------------
-void CPcsAlgorithm2Helper::SearchSingleL(const CPsSettings& aSettings,
- CPsQuery& aPsQuery,
- TBool aIsSearchInGroup,
- const RArray<TInt>& aContactsInGroup,
- RPointerArray<CPsData>& aSearchResults,
- RPointerArray<CPsPattern>& aSearchSeqs)
+void CPcsAlgorithm2Helper::SearchMixedL(const CPsSettings& aSettings,
+ CPsQuery& aPsQuery, TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup,
+ RPointerArray<CPsData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
{
- PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchSingleL") );
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchMixedL") );
- //__LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchSingleL") );
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMixedL") );
- iMaxCount = aSettings.MaxResults();
-
// Create filtering helper for the required sort type
TSortType sortType = aSettings.GetSortType();
CPcsAlgorithm2FilterHelper* filterHelper =
CPcsAlgorithm2FilterHelper::NewL(sortType);
- CleanupStack::PushL( filterHelper );
-
- // Search from cache based on first character
- const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0);
- TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
// Reset the result set array for new search
iSearchResultsArr.ResetAndDestroy();
// Get the data stores
- RPointerArray<TDesC> dataStores;
- CleanupResetAndDestroyPushL( dataStores );
- aSettings.SearchUrisL(dataStores);
+ RPointerArray<TDesC> aDataStores;
+ aSettings.SearchUrisL(aDataStores);
// Get the required display fields from the client
RArray<TInt> requiredDataFields;
- CleanupClosePushL( requiredDataFields );
aSettings.DisplayFieldsL(requiredDataFields);
+
+ // Search from cache based on first character
+ const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0);
+ TInt numValue = keyMap->PoolIdForCharacter( firstCharItem.Character() );
// Perform search for each required data store
RPointerArray<CPcsPoolElement> elements;
- CleanupClosePushL( elements );
- const TInt dataStoresCount = dataStores.Count();
- for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
+ for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
{
- RPointerArray<CPsData>* temp = new (ELeave) RPointerArray<CPsData> ();
- CleanupStack::PushL( temp );
- iSearchResultsArr.AppendL( temp );
- CleanupStack::Pop( temp );
+
+ RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
+ iSearchResultsArr.Append(temp);
// Get the contents for this data store
- TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
+ TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
if (arrayIndex < 0)
{
continue;
}
CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
- cache->GetContactsForKeyL(cachePoolId, elements);
-
- // Get the supported data fields for this data store
- RArray<TInt> supportedDataFields;
- CleanupClosePushL( supportedDataFields );
- cache->GetDataFields(supportedDataFields);
-
- // Get the filtered data fields for this data store
- TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL(requiredDataFields,
- supportedDataFields);
+ cache->GetContactsForKeyL(numValue, elements);
// Perform filtering
- FilterResultsSingleL(filterHelper,
- elements,
- aPsQuery,
- filteredDataMatch,
- aIsSearchInGroup,
- aContactsInGroup);
+ FilterResultsMixedL(filterHelper, elements, aPsQuery,
+ isSearchInGroup, aContactsInGroup);
- // If alphabetical sorting, get the results for this datastore
+ // If alphabetical sorting, get the results for this datastore
if (sortType == EAlphabetical)
{
filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
}
elements.Reset();
- CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
+ }
+
+ 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;
}
- CleanupStack::PopAndDestroy( &elements ); // Close
- CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
- CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy
+ 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 query to string
+ TPtrC queryPtr = aPsQuery.QueryAsStringLC();
+
+ // Search from cache based on first character
+ const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0);
+ TInt numValue = keyMap->PoolIdForCharacter( firstCharItem.Character() );
+
+ // 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, 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)
+ {
+ // 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 query to string
+ TPtrC queryPtr = aPsQuery.QueryAsStringLC();
+
+ // Search from cache based on first character
+ const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0);
+ TInt numValue = keyMap->PoolIdForCharacter( firstCharItem.Character() );
+
+ // 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,
- aSearchResults);
+ searchResults);
}
else
{
// Results are already sorted pattern based
- filterHelper->GetResults(aSearchResults);
+ filterHelper->GetResults(searchResults);
}
// Get the sorted match sequence list
- filterHelper->GetPatternsL(aSearchSeqs);
-
- PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() );
+ filterHelper->GetPatternsL(searchSeqs);
- // Cleanup
- const TInt searchResultsArrCount = iSearchResultsArr.Count();
- for (TInt i = 0; i < searchResultsArrCount; i++)
+ 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.ResetAndDestroy();
+ iSearchResultsArr.Reset();
- CleanupStack::PopAndDestroy( filterHelper );
+ CleanupStack::PopAndDestroy(); // query
+ delete filterHelper;
- //__LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchSingleL") );
-
- PRINT ( _L("End CPcsAlgorithm2Helper::SearchSingleL") );
+ PRINT ( _L("End CPcsAlgorithm2Helper::SearchQWERTYL") );
+ __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchQWERTYL") );
}
// ----------------------------------------------------------------------------
// CPcsAlgorithm2Helper::SearchMatchSeqL
-// Function to search matching sequences in the input text
+// Funciton to search matching sequences in the input text
// ----------------------------------------------------------------------------
-void CPcsAlgorithm2Helper::SearchMatchSeqL(CPsQuery& aPsQuery,
- const TDesC& aData,
- RPointerArray<TDesC>& aMatchSet,
- RArray<TPsMatchLocation>& aMatchLocation )
+void CPcsAlgorithm2Helper::SearchMatchSeqL(HBufC* /*aQuery*/, TDesC& aData,
+ RPointerArray<TDesC>& /*aMatchSet*/,
+ CPsQuery& /*aPsQuery*/,
+ RArray<TPsMatchLocation>& aMatchLocation)
{
PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMatchSeqL") );
- RArray<TInt> matchPos;
- CleanupClosePushL( matchPos );
- RArray<TInt> matchLen;
- CleanupClosePushL( matchLen );
- if ( iAlgorithm->FindUtilECE()->MatchRefineL( aData, aPsQuery, matchPos, matchLen, ETrue ) )
+ // 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)
{
- ASSERT( matchPos.Count() == matchLen.Count() );
- const TInt matchPosCount = matchPos.Count();
- for ( TInt i = 0 ; i < matchPosCount ; ++i )
- {
- TPsMatchLocation tempLocation;
-
- // check for directionality of the text
- TBool found(EFalse);
- TPtrC matchingPart = aData.Mid( matchPos[i], matchLen[i] );
- TBidiText::TDirectionality dir = TBidiText::TextDirectionality(matchingPart, &found);
-
- tempLocation.index = matchPos[i];
- tempLocation.length = matchLen[i];
- tempLocation.direction = dir;
-
- // Add the match location to the data structure array
- aMatchLocation.Append(tempLocation);
-
- // Add the matched sequence to set, not allowing duplicates
- CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSet, matchingPart );
- }
+ 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
}
- CleanupStack::PopAndDestroy( &matchLen );
- CleanupStack::PopAndDestroy( &matchPos );
PRINT ( _L("End CPcsAlgorithm2Helper::SearchMatchSeqL") );
}
// ----------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::FilterResultsSingleL
+// CPcsAlgorithm2::FilterResultsL
// Subset search function
// ----------------------------------------------------------------------------
-void CPcsAlgorithm2Helper::FilterResultsSingleL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
- RPointerArray<CPcsPoolElement>& aSearchSet,
- CPsQuery& aSearchQuery,
- TUint8 aFilteredDataMatch,
- TBool aIsSearchInGroup,
- const RArray<TInt>& aContactsInGroup)
+void CPcsAlgorithm2Helper::FilterResultsL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
+ RPointerArray<CPcsPoolElement>& searchSet,
+ const TDesC& searchQuery,
+ TBool isSearchInGroup,
+ RArray<TInt>& aContactsInGroup)
{
- PRINT ( _L("Enter CPcsAlgorithm2::FilterResultsSingleL") );
+ __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::FilterResultsL") );
+ PRINT ( _L("Enter CPcsAlgorithm2Helper::FilterResultsL") );
- TInt maxcount = 0;
- CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
+ // 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;
- // Assume that all the elements is aSearchSet are from the same database.
- // Get firstname index and lastname index for that database.
- // If both are found, then name fields are matched a bit differently compared
- // to rest of the fields.
- TInt fnIndex( KErrNotFound );
- TInt lnIndex( KErrNotFound );
- TBool fullNameSearch( EFalse );
- if ( aSearchSet.Count() )
+ 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++)
{
- TInt dbUriId = aSearchSet[0]->GetPsData()->UriId();
- CPcsCache* cache = iAlgorithm->GetCache( dbUriId );
- fnIndex = cache->GetFirstNameIndex();
- lnIndex = cache->GetLastNameIndex();
-
- // Ensure that firstname and lastname are among the fields to be searched
- TUint8 fnBitmask = 1 << fnIndex;
- TUint8 lnBitmask = 1 << lnIndex;
- if ( (aFilteredDataMatch & fnBitmask) &&
- (aFilteredDataMatch & lnBitmask) )
- {
- fullNameSearch = ETrue;
- // Remove firstname and lastname from the set of fields to search
- // so that they will not be searched twice.
- aFilteredDataMatch &= ~fnBitmask;
- aFilteredDataMatch &= ~lnBitmask;
- }
- }
-
- // Parse thru each search set elements and filter the results
- const TInt searchSetCount = aSearchSet.Count();
- for (TInt index = 0; index < searchSetCount; index++)
- {
- CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (aSearchSet[index]);
+ CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
CPsData* psData = poolElement->GetPsData();
psData->ClearDataMatches();
+ RPointerArray<TDesC> tempMatchSeq;
- // Skip the contact if we are doing a group search and contact doesn't belong to the group
- if ( aIsSearchInGroup &&
- aContactsInGroup.Find( psData->Id() ) == KErrNotFound )
+ // 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))
{
- continue;
- }
-
- // Buffer for matched character sequence. Currently, we don't return
- // accurate pattern but just first character from the matching point.
- // Current clients don't actually use this data for anything.
- TBuf<1> matchingData;
-
- TBool matched = EFalse;
+ 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);
- // Parse thru each data field and filter the results
- // -------------------------------------------------
-
- // Name fields are handled separately to enable searching with query like
- // "LastnameFirstname". Searching fullname by query string
- // only for the pool elements matching with the firstname or lastname
- if ( fullNameSearch && ( poolElement->IsDataMatch(fnIndex) ||
- poolElement->IsDataMatch(lnIndex) ))
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
+ }
+ }
+ else
{
- HBufC* fullName = CreateNameBufLC( *psData, fnIndex, lnIndex );
+ // 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);
- // FindUtil can take care of matching queries like "Firstname", "Lastname",
- // and "LastnameFirstname".
- matched = pFindUtilEce->MatchRefineL( *fullName, aSearchQuery );
- if (matched)
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
+ }
+ }
+
+ if(!matched && firstnameLen)
{
- matchingData = fullName->Left(1);
- psData->SetDataMatch( fnIndex );
- psData->SetDataMatch( lnIndex );
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(firstName, tmpSearchQuery, ECustomConverter, iAlgorithm);
+
+ if (matched)
+ {
+ psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
+ }
}
- CleanupStack::PopAndDestroy( fullName );
- }
+ token.Append(lastName);
+ token.Append(firstName);
+ if (!matched && lastnameLen && firstnameLen)
+ {
+ matched = iAlgorithm->FindUtil()->Interface()->
+ MatchRefineL(token, tmpSearchQuery, ECustomConverter, iAlgorithm);
- // Find from the rest of the fields if no match found so far.
- // Name fields are already removed from aFilteredDataMatch if we did separate full name search.
- const TInt dataElementCount = psData->DataElementCount();
- for ( TInt dataIndex = 0; dataIndex < dataElementCount && !matched ; dataIndex++ )
- {
- // Filter off data fields not required in search
- TUint8 bitIndex = 1 << dataIndex;
- TUint8 filter = bitIndex & aFilteredDataMatch;
- if ( filter == 0x0 )
- {
- // Move to next data
- continue;
- }
-
- if ( poolElement->IsDataMatch(dataIndex) )
- {
- TPtrC fieldData( *psData->Data(dataIndex) );
- matched = pFindUtilEce->MatchRefineL( fieldData, aSearchQuery );
if (matched)
{
- matchingData = fieldData.Left(1);
- psData->SetDataMatch( dataIndex );
+ 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();
- // Add to results if match is found
- if ( matched )
+ 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))
{
- RPointerArray<TDesC> tempMatchSeq;
- CleanupClosePushL( tempMatchSeq );
+ 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());
+ }
+ }
- // Wrap matched character sequence to array.
- matchingData.UpperCase();
- tempMatchSeq.AppendL(&matchingData);
+ 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
- aAlgorithmFilterHelper->AddL( psData, tempMatchSeq );
- maxcount++;
-
- // Cleanup the match sequence array as
- // they are stored in pattern details structure
- CleanupStack::PopAndDestroy( &tempMatchSeq ); // Close
-
- // TODO: Match seqs could be extracted from actual
- // match locations by using the other overload of
- // CFindUtilChineseECE::MatchRefineL().
- // Currently, match seq data is not used by clients.
+ if (isSearchInGroup)
+ {
+ if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
+ }
+ else
+ {
+ aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
+ }
}
-
- if ( iMaxCount != -1 && maxcount > iMaxCount )
- {
- return;
- }
+
+ // Cleanup the match sequence array as
+ // they are stored in pattern details structure
+ tempMatchSeq.ResetAndDestroy();
}
- PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsSingleL") );
+ 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") );
}
// ----------------------------------------------------------------------------
@@ -419,156 +899,93 @@
void CPcsAlgorithm2Helper::SortSearchSeqsL(RPointerArray<TDesC>& aSearchSeqs)
{
// Sort the search seqs
- TLinearOrder<TDesC> rule( CPcsAlgorithm2Utils::MyCompareC );
+ TLinearOrder<TDesC> rule(Compare2);
aSearchSeqs.Sort(rule);
}
-// ---------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::CreteNameBufLC
-// Update name order according to Phonebook setting
-// ---------------------------------------------------------------------------
-HBufC* CPcsAlgorithm2Helper::CreateNameBufLC( const CPsData& aContactData,
- TInt aFirstNameIndex, TInt aLastNameIndex ) const
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::ExtractQueryL()
+// Required for mixed mode search.
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
{
- const TDesC& firstName( *aContactData.Data(aFirstNameIndex) );
- const TDesC& lastName( *aContactData.Data(aLastNameIndex) );
- CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
- HBufC* fullName = NULL;
-
- if ( pFindUtilEce->IsChineseWordIncluded( lastName ) ||
- pFindUtilEce->IsChineseWordIncluded( firstName ) )
+ for (int i = 0; i < aQuery.Count(); i++)
{
- fullName = HBufC::NewLC( lastName.Length() + firstName.Length() + 1 );
- TPtr fullNamePtr = fullName->Des();
-
- // Form the full name according the Phonebook name order setting. Typically,
- // the order is always lastname-firstname in Chinese variants. However, at least
- // currently it is possible to change this from Contacts app if UI language has
- // been set to English.
- if ( iNameOrder == ELastnameFirstname )
+ if (aQuery.GetItemAtL(i).Mode() == EItut)
{
- fullNamePtr.Append( lastName );
- //Holds the first char of first name of a contact
- TBuf<10> firstChar;
- firstChar.Zero();
-
- if(firstName.Length())
- {
- firstChar.Append(firstName[0]);
- // There is no space between LastName and FirstName in Chinese Name
- // except that the firstChar of FirstName isn't Chinese character
- if ( !pFindUtilEce->IsChineseWordIncluded( firstChar ) )
- {
- fullNamePtr.Append( KSpace );
- }
- fullNamePtr.Append( firstName );
- }
+ TBuf<KPsQueryMaxLen> outBuf;
+ keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
+ aOutput.Append(outBuf[i]);
+ CleanupStack::PopAndDestroy();
}
else
{
- fullNamePtr.Append( firstName );
- //Holds the first char of last name of a contact
- TBuf<10> firstChar;
- firstChar.Zero();
-
- if(lastName.Length())
- {
- firstChar.Append(lastName[0]);
- // There is no space between LastName and FirstName in Chinese Name
- // except that the firstChar of Lastname isn't Chinese character
- if ( !pFindUtilEce->IsChineseWordIncluded( firstChar ) )
- {
- fullNamePtr.Append( KSpace );
- }
- fullNamePtr.Append( lastName );
- }
- }
- }
- else
- {
- fullName = HBufC::NewLC( lastName.Length() + firstName.Length() + 1 );
- TPtr fullNamePtr = fullName->Des();
-
- // Form the full name according the Phonebook name order setting. Typically,
- // the order is always lastname-firstname in Chinese variants. However, at least
- // currently it is possible to change this from Contacts app if UI language has
- // been set to English.
- if ( iNameOrder == ELastnameFirstname )
- {
- fullNamePtr.Append( lastName );
- fullNamePtr.Append( KSpace );
- fullNamePtr.Append( firstName );
- }
- else
- {
- fullNamePtr.Append( firstName );
- fullNamePtr.Append( KSpace );
- fullNamePtr.Append( lastName );
- }
- }
-
- return fullName;
- }
-
-// ---------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::UpdateNameOrderL
-// Update name order according to Phonebook setting
-// ---------------------------------------------------------------------------
-void CPcsAlgorithm2Helper::UpdateNameOrderL()
- {
- /*
- * Phonebook name ordering flag, integer value, possible values:
- * 0: name order Lastname Firstname
- * 1: name order Firstname Lastname
- * 2: name order undefined
- */
- TInt nameOrderSetting;
- iPbkSettings->Get( MPbkGlobalSetting::ENameOrdering, nameOrderSetting );
-
- switch ( nameOrderSetting )
- {
- case 0:
- {
- iNameOrder = ELastnameFirstname;
- break;
- }
- case 1:
- {
- iNameOrder = EFirstnameLastname;
- break;
- }
- case 2:
- default:
- {
- // Decide name order based on UI language: lastname-firstname
- // for Chinese, firstname-lastname for the rest of languages.
- TLanguage uiLang = User::Language();
- if ( uiLang == ELangPrcChinese ||
- uiLang == ELangHongKongChinese ||
- uiLang == ELangTaiwanChinese )
- {
- iNameOrder = ELastnameFirstname;
- }
- else
- {
- iNameOrder = EFirstnameLastname;
- }
+ aOutput.Append(aQuery.GetItemAtL(i).Character());
}
}
}
-// ---------------------------------------------------------------------------
-// CPcsAlgorithm2Helper::SettingChangedL
-// From MPbkGlobalSettingObserver
-// ---------------------------------------------------------------------------
-void CPcsAlgorithm2Helper::SettingChangedL( MPbkGlobalSetting::TPbkGlobalSetting aKey )
+// ----------------------------------------------------------------------------
+// CPcsAlgorithm2Helper::ExtractQueryL()
+// Required for mixed mode search.
+// ----------------------------------------------------------------------------
+void CPcsAlgorithm2Helper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
{
- if ( aKey == MPbkGlobalSetting::ENameOrdering )
+ TInt len = -1;
+
+ if (aInput.Length() > aQuery.Count())
+ {
+ len = aQuery.Count();
+ }
+ else
+ {
+ len = aInput.Length();
+ }
+
+ for (int i = 0; i < len; i++)
{
- UpdateNameOrderL();
+ 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