predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsAlgorithm1Helper.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Predictive Contact Search Algorithm 1 helper class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 
       
    21 #include "CPcsAlgorithm1.h"
       
    22 #include "CPcsAlgorithm1Helper.h"
       
    23 #include "CPcsAlgorithm1Utils.h"
       
    24 #include "CPcsDebug.h"
       
    25 #include "CPcsCache.h"
       
    26 #include "CPcsKeyMap.h"
       
    27 #include "CPsData.h"
       
    28 #include "CWords.h"
       
    29 #include "CPsQuery.h"
       
    30 #include "CPsQueryItem.h"
       
    31 #include "CPsDataPluginInterface.h"
       
    32 #include "CPcsPoolElement.h"
       
    33 
       
    34 // ============================== MEMBER FUNCTIONS ============================
       
    35 
       
    36 // ----------------------------------------------------------------------------
       
    37 // CPcsAlgorithm1Helper::NewL
       
    38 // Two Phase Construction
       
    39 // ----------------------------------------------------------------------------
       
    40 CPcsAlgorithm1Helper* CPcsAlgorithm1Helper::NewL(CPcsAlgorithm1* aAlgorithm)
       
    41 {
       
    42     PRINT ( _L("Enter CPcsAlgorithm1Helper::NewL") );
       
    43 
       
    44     CPcsAlgorithm1Helper* self = new ( ELeave ) CPcsAlgorithm1Helper();
       
    45     CleanupStack::PushL( self );
       
    46     self->ConstructL(aAlgorithm);
       
    47     CleanupStack::Pop( self );
       
    48 
       
    49     PRINT ( _L("End CPcsAlgorithm1Helper::NewL") );
       
    50 
       
    51     return self;
       
    52 }
       
    53 
       
    54 // ----------------------------------------------------------------------------
       
    55 // CPcsAlgorithm1Helper::CPcsAlgorithm1Helper
       
    56 // Two Phase Construction
       
    57 // ----------------------------------------------------------------------------
       
    58 CPcsAlgorithm1Helper::CPcsAlgorithm1Helper()
       
    59 {
       
    60     PRINT ( _L("Enter CPcsAlgorithm1Helper::CPcsAlgorithm1") );
       
    61     PRINT ( _L("End CPcsAlgorithm1Helper::CPcsAlgorithm1") );
       
    62 }
       
    63 
       
    64 // ----------------------------------------------------------------------------
       
    65 // CPcsAlgorithm1Helper::ConstructL
       
    66 // Two Phase Construction
       
    67 // ----------------------------------------------------------------------------
       
    68 void CPcsAlgorithm1Helper::ConstructL(CPcsAlgorithm1* aAlgorithm)
       
    69 {
       
    70     PRINT ( _L("Enter CPcsAlgorithm1Helper::ConstructL") );
       
    71 
       
    72     iAlgorithm = aAlgorithm;
       
    73     iKeyMap = iAlgorithm->GetKeyMap();
       
    74 
       
    75     PRINT ( _L("End CPcsAlgorithm1Helper::ConstructL") );
       
    76 }
       
    77 
       
    78 // ----------------------------------------------------------------------------
       
    79 // CPcsAlgorithm1Helper::CPcsAlgorithm1Helper
       
    80 // Destructor
       
    81 // ----------------------------------------------------------------------------
       
    82 CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper()
       
    83 {
       
    84     PRINT ( _L("Enter CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper") );
       
    85     iSearchResultsArr.ResetAndDestroy();
       
    86     PRINT ( _L("End CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper") );
       
    87 }
       
    88 
       
    89 // ----------------------------------------------------------------------------
       
    90 // CPcsAlgorithm1Helper::SearchSingleL
       
    91 // Search function for query in ITU-T mode, QWERTY mode, or Mixed (ITU-T and QWERTY) mode.
       
    92 // ----------------------------------------------------------------------------
       
    93 void  CPcsAlgorithm1Helper::SearchSingleL( const CPsSettings& aSettings,
       
    94                                            CPsQuery& aPsQuery,
       
    95                                            TBool aIsSearchInGroup,
       
    96                                            RArray<TInt>& aContactsInGroup,
       
    97                                            RPointerArray<CPsData>& aSearchResults,
       
    98                                            RPointerArray<CPsPattern>& aSearchSeqs )
       
    99 {
       
   100     PRINT ( _L("Enter CPcsAlgorithm1Helper::SearchSingleL") );
       
   101 
       
   102     __LATENCY_MARK ( _L("CPcsAlgorithm1Helper::SearchSingleL") );
       
   103 
       
   104     // Create filtering helper for the required sort type
       
   105     TSortType sortType = aSettings.GetSortType();
       
   106     CPcsAlgorithm1FilterHelper* filterHelper = CPcsAlgorithm1FilterHelper::NewL(sortType);
       
   107     CleanupStack::PushL( filterHelper );
       
   108     
       
   109     // Search from cache based on first character
       
   110     const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0);
       
   111     TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
       
   112 
       
   113     // Reset the result set array for new search
       
   114     iSearchResultsArr.ResetAndDestroy();
       
   115 
       
   116     // Get the data stores
       
   117     RPointerArray<TDesC> dataStores;
       
   118     CleanupResetAndDestroyPushL( dataStores );
       
   119     aSettings.SearchUrisL(dataStores);
       
   120 
       
   121     // Get the required display fields from the client
       
   122     RArray<TInt> requiredDataFields;
       
   123     CleanupClosePushL( requiredDataFields );
       
   124     aSettings.DisplayFieldsL(requiredDataFields);
       
   125 
       
   126     // Perform search for each required data store
       
   127     RPointerArray<CPcsPoolElement> elements;
       
   128     CleanupClosePushL( elements );
       
   129 
       
   130     for ( TInt dsIndex = 0; 
       
   131           dsIndex < dataStores.Count();
       
   132           dsIndex++ )
       
   133     {
       
   134         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
       
   135         CleanupStack::PushL( temp );
       
   136         iSearchResultsArr.AppendL( temp );
       
   137         CleanupStack::Pop( temp );
       
   138 
       
   139         // Get the contents for this data store
       
   140         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
       
   141         if ( arrayIndex < 0 ) continue;
       
   142         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
       
   143         cache->GetContactsForKeyL(cachePoolId, elements);
       
   144 
       
   145         // Get the supported data fields for this data store
       
   146         RArray<TInt> supportedDataFields;
       
   147         CleanupClosePushL( supportedDataFields );
       
   148         cache->GetDataFields(supportedDataFields);
       
   149 
       
   150         // Get the filtered data fields for this data store
       
   151         TUint8 filteredDataMatch = CPcsAlgorithm1Utils::FilterDataFieldsL(requiredDataFields,
       
   152                                                                           supportedDataFields);
       
   153 
       
   154         // Perform filtering
       
   155         FilterResultsSingleL(filterHelper,
       
   156                              elements,
       
   157                              aPsQuery,
       
   158                              filteredDataMatch,
       
   159                              aIsSearchInGroup,
       
   160                              aContactsInGroup);
       
   161 
       
   162         // If alphabetical sorting, get the results for this datastore
       
   163         if ( sortType == EAlphabetical )
       
   164         {
       
   165             filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
       
   166         }
       
   167 
       
   168         elements.Reset();
       
   169         CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
       
   170     }
       
   171 
       
   172     CleanupStack::PopAndDestroy( &elements );           // Close
       
   173     CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
       
   174     CleanupStack::PopAndDestroy( &dataStores );         // ResetAndDestroy
       
   175 
       
   176     // If alphabetical sorting, merge the result sets of all datastores
       
   177     if ( sortType == EAlphabetical )
       
   178     {
       
   179         // Merge the result sets of individual datastores alphabetically
       
   180         CPcsAlgorithm1Utils::FormCompleteSearchResultsL(iSearchResultsArr,
       
   181                                                         aSearchResults);
       
   182     }
       
   183     else
       
   184     {
       
   185         // Results are already sorted pattern based
       
   186         filterHelper->GetResults(aSearchResults);
       
   187     }
       
   188 
       
   189     // Get the sorted match sequence list
       
   190     filterHelper->GetPatternsL(aSearchSeqs);
       
   191 
       
   192     PRINT1 ( _L("CPcsAlgorithm1Helper::SearchSingleL: Number of search results = %d"), aSearchResults.Count() );
       
   193 
       
   194     // Cleanup
       
   195     for ( TInt i = 0; i < iSearchResultsArr.Count(); i++ )
       
   196     {
       
   197         iSearchResultsArr[i]->Reset();
       
   198     }
       
   199     iSearchResultsArr.ResetAndDestroy();
       
   200 
       
   201     CleanupStack::PopAndDestroy( filterHelper );
       
   202 
       
   203     __LATENCY_MARKEND ( _L("CPcsAlgorithm1Helper::SearchSingleL") );
       
   204 
       
   205     PRINT ( _L("End CPcsAlgorithm1Helper::SearchSingleL") );
       
   206 }
       
   207 
       
   208 // ----------------------------------------------------------------------------
       
   209 // CPcsAlgorithm1Helper::FilterResultsSingleL
       
   210 // Subset search function
       
   211 // ----------------------------------------------------------------------------
       
   212 void  CPcsAlgorithm1Helper::FilterResultsSingleL(CPcsAlgorithm1FilterHelper* aAlgorithmFilterHelper,
       
   213                                                  RPointerArray<CPcsPoolElement>& aSearchSet,
       
   214                                                  CPsQuery& aPsQuery,
       
   215                                                  TUint8 aFilteredDataMatch,
       
   216                                                  TBool aIsSearchInGroup,
       
   217                                                  RArray<TInt>& aContactsInGroup)
       
   218 {
       
   219     PRINT ( _L("Enter CPcsAlgorithm1Helper::FilterResultsSingleL") );
       
   220 
       
   221     __LATENCY_MARK ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL") );
       
   222 
       
   223     // Convert the search query to char-and-key string
       
   224     TBuf<KPsQueryMaxLen> queryAsDes;
       
   225     iKeyMap->GetMixedKeyStringForQueryL( aPsQuery, queryAsDes );
       
   226 
       
   227     PRINTQUERY ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL: "), aPsQuery );
       
   228 
       
   229     PRINT1 ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL: char-and-key string for the query is \"%S\""),
       
   230              &queryAsDes );      
       
   231 
       
   232     // Parse thru each search set elements and filter the results
       
   233     for ( TInt index = 0; index < aSearchSet.Count(); index++ )
       
   234     {
       
   235         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*>(aSearchSet[index]);
       
   236         CPsData* psData = poolElement->GetPsData();
       
   237         psData->ClearDataMatches();
       
   238         
       
   239         // Skip this contact if performing group search and this contact doesn't
       
   240         // belong to the group
       
   241         if ( aIsSearchInGroup && aContactsInGroup.Find(psData->Id()) == KErrNotFound )
       
   242             {
       
   243             continue;
       
   244             }
       
   245         
       
   246         RPointerArray<TDesC> tempMatchSeq;
       
   247         CleanupResetAndDestroyPushL( tempMatchSeq );
       
   248         TBool isAdded = EFalse;
       
   249 
       
   250         // Parse thru each data and filter the results
       
   251         for ( TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++ )
       
   252         {
       
   253             // Filter off data fields not required in search
       
   254             TUint8 bitIndex = 1 << dataIndex;
       
   255 
       
   256             TUint8 filter = bitIndex & aFilteredDataMatch;
       
   257             if ( filter == 0x0 )
       
   258             {
       
   259                 // Move to next data
       
   260                 continue;
       
   261             }
       
   262 
       
   263             if ( poolElement->IsDataMatch(dataIndex) )
       
   264             {
       
   265                 TLex lex( *psData->Data(dataIndex) );
       
   266 
       
   267                 // First word
       
   268                 TPtrC token = lex.NextToken();
       
   269 
       
   270                 // Search thru multiple words
       
   271                 while ( token.Length() != 0 )
       
   272                 {
       
   273                     // Convert the data to char-and-key string
       
   274                     TBuf<KPsQueryMaxLen> dataWithKeys;
       
   275                     iKeyMap->GetMixedKeyStringForDataL( aPsQuery, token, dataWithKeys );
       
   276 
       
   277                     if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(dataWithKeys, queryAsDes, aPsQuery) )
       
   278                     {
       
   279                         psData->SetDataMatch(dataIndex);
       
   280                         isAdded = ETrue;
       
   281 
       
   282                         // Extract matched character sequence
       
   283                         TInt len = queryAsDes.Length();
       
   284                         TPtrC seq = token.Left(len);
       
   285                         CPcsAlgorithm1Utils::AppendMatchToSeqL( tempMatchSeq, seq );
       
   286                     }
       
   287                     // Next word
       
   288                     token.Set(lex.NextToken());
       
   289                 }
       
   290             }
       
   291         }
       
   292 
       
   293         // Add the result
       
   294         if ( isAdded )
       
   295         {
       
   296             aAlgorithmFilterHelper->AddL(psData,tempMatchSeq);
       
   297         }
       
   298 
       
   299         // Cleanup the match sequence array as
       
   300         // they are stored in pattern details structure
       
   301         CleanupStack::PopAndDestroy( &tempMatchSeq ); // ResetAndDestroy
       
   302     }
       
   303 
       
   304     __LATENCY_MARKEND ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL") );
       
   305 
       
   306     PRINT ( _L("End CPcsAlgorithm1Helper::FilterResultsSingleL") );
       
   307 }
       
   308 
       
   309 // ----------------------------------------------------------------------------
       
   310 // CPcsAlgorithm1Helper::SearchMatchSeqL
       
   311 // Funciton to search matching sequences in the input text
       
   312 // ----------------------------------------------------------------------------
       
   313 void  CPcsAlgorithm1Helper::SearchMatchSeqL(CPsQuery& aPsQuery,
       
   314                                             const TDesC& aData,
       
   315                                             RPointerArray<TDesC>& aMatchSet,
       
   316                                             RArray<TPsMatchLocation>& aMatchLocation )
       
   317 {
       
   318     PRINT ( _L("Enter CPcsAlgorithm1Helper::SearchMatchSeqL") );
       
   319 
       
   320     HBufC* queryAsDes = HBufC::NewLC(aPsQuery.Count());
       
   321     TPtr queryAsDesPtr(queryAsDes->Des());
       
   322     iKeyMap->GetMixedKeyStringForQueryL( aPsQuery, queryAsDesPtr );
       
   323 
       
   324     // Convert the data into words
       
   325     TLex lex(aData);
       
   326 
       
   327     // First word
       
   328     TPtrC token = lex.NextToken();
       
   329 
       
   330     TInt beg = lex.Offset() - token.Length();  // start index of match sequence
       
   331 
       
   332     // Search thru multiple words
       
   333     while ( token.Length() != 0 )
       
   334     {
       
   335         HBufC* data = HBufC::NewLC(token.Length());
       
   336         TPtr dataPtr(data->Des());
       
   337         iKeyMap->GetMixedKeyStringForDataL( aPsQuery, token, dataPtr );
       
   338 
       
   339         if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(dataPtr, *queryAsDes, aPsQuery) )
       
   340         {
       
   341             TInt len = queryAsDes->Length();
       
   342 
       
   343             TPsMatchLocation tempLocation;
       
   344 
       
   345             // check for directionality of the text
       
   346             TBool found(EFalse);
       
   347             TBidiText::TDirectionality dir = TBidiText::TextDirectionality(token, &found);
       
   348 
       
   349             tempLocation.index = beg;
       
   350             tempLocation.length = len;
       
   351             tempLocation.direction = dir;
       
   352 
       
   353             // Add the match location to the data structure array
       
   354             aMatchLocation.Append(tempLocation);
       
   355 
       
   356             // Add the sequence to the match sequence
       
   357             TPtrC seq = token.Left(len);
       
   358             CPcsAlgorithm1Utils::AppendMatchToSeqL( aMatchSet, seq );
       
   359         }
       
   360 
       
   361         // Next word
       
   362         token.Set(lex.NextToken());
       
   363         beg = lex.Offset() - token.Length();  // start index of next word
       
   364         CleanupStack::PopAndDestroy(); //data
       
   365     }
       
   366 
       
   367     CleanupStack::PopAndDestroy( queryAsDes );
       
   368 
       
   369     PRINT ( _L("End CPcsAlgorithm1Helper::SearchMatchSeqL") );
       
   370 }
       
   371 
       
   372 // ----------------------------------------------------------------------------
       
   373 // CPcsAlgorithm1Helper::SortSearchSeqsL()
       
   374 //
       
   375 // ----------------------------------------------------------------------------
       
   376 void  CPcsAlgorithm1Helper::SortSearchSeqsL(RPointerArray<TDesC>& aSearchSeqs)
       
   377 {
       
   378     // Sort the search seqs
       
   379     TLinearOrder<TDesC> rule( CPcsAlgorithm1Utils::CompareCollate );
       
   380     aSearchSeqs.Sort(rule);
       
   381 }
       
   382 
       
   383 // End of file