predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
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 main class
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDES
       
    19 #include <VPbkEng.rsg>
       
    20 #include <PtiEngine.h>
       
    21 #include <centralrepository.h>
       
    22 #include <AknFepInternalCRKeys.h>
       
    23 
       
    24 #include "CPcsAlgorithm2.h"
       
    25 #include "CPcsAlgorithm2Helper.h"
       
    26 #include "CPcsAlgorithm2MultiSearchHelper.h"
       
    27 #include "CPcsAlgorithm2Utils.h"
       
    28 #include "CPcsDebug.h"
       
    29 #include "CPcsCache.h"
       
    30 #include "CPcsKeyMap.h"
       
    31 #include "CPsData.h"
       
    32 #include "CWords.h"
       
    33 #include "CPsQuery.h"
       
    34 #include "CPsDataPluginInterface.h"
       
    35 #include "CPcsDefs.h"
       
    36 #include "FindUtilChineseECE.h"
       
    37 
       
    38 
       
    39 // ============================== MEMBER FUNCTIONS ============================
       
    40 
       
    41 // ----------------------------------------------------------------------------
       
    42 // CPcsAlgorithm2::NewL
       
    43 // Two Phase Construction
       
    44 // ----------------------------------------------------------------------------
       
    45 CPcsAlgorithm2* CPcsAlgorithm2::NewL()
       
    46     {
       
    47     PRINT ( _L("Enter CPcsAlgorithm2::NewL") );
       
    48 
       
    49     CPcsAlgorithm2* self = new (ELeave) CPcsAlgorithm2();
       
    50     CleanupStack::PushL(self);
       
    51     self->ConstructL();
       
    52     CleanupStack::Pop(self);
       
    53 
       
    54     PRINT ( _L("End CPcsAlgorithm2::NewL") );
       
    55 
       
    56     return self;
       
    57     }
       
    58 
       
    59 // ----------------------------------------------------------------------------
       
    60 // CPcsAlgorithm2::CPcsAlgorithm2
       
    61 // Two Phase Construction
       
    62 // ----------------------------------------------------------------------------
       
    63 CPcsAlgorithm2::CPcsAlgorithm2()
       
    64     {
       
    65     PRINT ( _L("Enter CPcsAlgorithm2::CPcsAlgorithm2") );
       
    66     PRINT ( _L("End CPcsAlgorithm2::CPcsAlgorithm2") );
       
    67     }
       
    68 
       
    69 // ----------------------------------------------------------------------------
       
    70 // CPcsAlgorithm2::ConstructL
       
    71 // Two Phase Construction
       
    72 // ----------------------------------------------------------------------------
       
    73 void CPcsAlgorithm2::ConstructL()
       
    74     {
       
    75     PRINT ( _L("Enter CPcsAlgorithm2::ConstructL") );
       
    76 
       
    77     iCacheStatus = ECachingNotStarted; // Starting status
       
    78     iCacheError = KErrNone; // No error
       
    79     iCacheCount = 0; // No data
       
    80 
       
    81     iFindUtilECE = CFindUtilChineseECE::NewL(this);
       
    82     
       
    83     iPluginLauncher = CIdle::NewL( CActive::EPriorityStandard );
       
    84 
       
    85     // Define cache status property used to inform clients about the caching status.
       
    86     DefinePropertyL( EPsKeyCacheStatus );
       
    87     
       
    88     // Define cache error property used to inform client about the errors.
       
    89     DefinePropertyL( EPsKeyCacheError );
       
    90     
       
    91     // Define properties for notifying about cache updates
       
    92     DefinePropertyL( EPsKeyContactRemovedCounter );
       
    93     DefinePropertyL( EPsKeyContactModifiedCounter );
       
    94     DefinePropertyL( EPsKeyContactAddedCounter );
       
    95 
       
    96     // Initialize key map and pti engine
       
    97     TInt keyMapErr = KErrNone;
       
    98     TRAP( keyMapErr, iKeyMap = CPcsKeyMap::NewL( this ) );
       
    99     if (keyMapErr != KErrNone)
       
   100         {
       
   101         PRINT ( _L("**********************************************."));
       
   102         PRINT1 ( _L("CPcsAlgorithm2::ConstructL() KeyMap construction error. The keymap crashed with error code %d."), keyMapErr );
       
   103         PRINT ( _L("Please check the keypad/language for which keymap got crashed.") );
       
   104         PRINT ( _L("**********************************************."));
       
   105         User::Leave( keyMapErr ); // we can't go on without a key map; constructing cache needs it
       
   106         }
       
   107     
       
   108     // Initialize helpers
       
   109     iHelper = CPcsAlgorithm2Helper::NewL(this);
       
   110     iMultiSearchHelper = CPcsAlgorithm2MultiSearchHelper::NewL(this);
       
   111 
       
   112     if(!iPluginLauncher->IsActive())
       
   113         {
       
   114         iPluginLauncher->Start(TCallBack(CPcsAlgorithm2::DoLaunchPluginsL, this));
       
   115         }
       
   116 
       
   117     PRINT ( _L("End CPcsAlgorithm2::ConstructL") );
       
   118     }
       
   119 
       
   120 // ----------------------------------------------------------------------------
       
   121 // CPcsAlgorithm2::~CPcsAlgorithm2
       
   122 // Destructor
       
   123 // ----------------------------------------------------------------------------
       
   124 CPcsAlgorithm2::~CPcsAlgorithm2()
       
   125     {
       
   126     PRINT ( _L("Enter CPcsAlgorithm2::~CPcsAlgorithm2") );
       
   127 
       
   128     // Clear TLS
       
   129     Dll::SetTls(NULL);
       
   130 
       
   131     // Cleanup cache
       
   132     iPcsCache.ResetAndDestroy();
       
   133 
       
   134     // Cleanup adapters interface and key handling
       
   135     delete iKeyMap;
       
   136     delete iPsDataPluginInterface;
       
   137 
       
   138     // Cleanup helpers
       
   139     delete iHelper;
       
   140     delete iMultiSearchHelper;
       
   141 
       
   142     delete iFindUtilECE;
       
   143     
       
   144     delete iPluginLauncher;
       
   145 
       
   146     PRINT ( _L("End CPcsAlgorithm2::~CPcsAlgorithm2") );
       
   147     }
       
   148 
       
   149 // ----------------------------------------------------------------------------
       
   150 // CPcsAlgorithm2::DefinePropertyL
       
   151 // Define a P&S property with given key under the internal category 
       
   152 // UID of PCS. Leave if definition fails for any other reason than
       
   153 // key already existing. 
       
   154 // ----------------------------------------------------------------------------
       
   155 void CPcsAlgorithm2::DefinePropertyL( TPcsInternalKeyCacheStatus aPsKey )
       
   156     {
       
   157     TInt err = RProperty::Define( KPcsInternalUidCacheStatus, 
       
   158                                   aPsKey, 
       
   159                                   RProperty::EInt );
       
   160     if ( err != KErrAlreadyExists )
       
   161         {
       
   162         User::LeaveIfError(err);
       
   163         }
       
   164     }
       
   165 
       
   166 // ----------------------------------------------------------------------------
       
   167 // CPcsAlgorithm2::RemoveSpacesL
       
   168 // Remove leading and trailing spaces of search query
       
   169 // ----------------------------------------------------------------------------
       
   170 void  CPcsAlgorithm2::RemoveSpacesL(CPsQuery& aQuery)
       
   171     {
       
   172     PRINT ( _L("Enter CPcsAlgorithm2::RemoveSpacesL") );
       
   173 
       
   174     // Remove all leading " "
       
   175     while ( aQuery.Count() > 0 )
       
   176         {
       
   177         CPsQueryItem& item = aQuery.GetItemAtL(0); // First
       
   178         if ( !item.Character().IsSpace() )
       
   179             {
       
   180             break;
       
   181             }
       
   182         aQuery.Remove(0);
       
   183         }
       
   184 
       
   185     // Remove all trailing " "
       
   186     while ( aQuery.Count() > 0 )
       
   187         {
       
   188         CPsQueryItem& item = aQuery.GetItemAtL(aQuery.Count()-1); // Last
       
   189         if ( !item.Character().IsSpace() )
       
   190             {
       
   191             break;
       
   192             }
       
   193         aQuery.Remove(aQuery.Count()-1);
       
   194         }
       
   195     
       
   196     PRINT ( _L("End CPcsAlgorithm2::RemoveSpacesL") );
       
   197     }    
       
   198 
       
   199 // ----------------------------------------------------------------------------
       
   200 // CPcsAlgorithm2::ReplaceZeroWithSpaceL
       
   201 // Replace first occurance of '0' in a sequence of '0's in ITU-T with space
       
   202 // ----------------------------------------------------------------------------
       
   203 TBool CPcsAlgorithm2::ReplaceZeroWithSpaceL(CPsQuery& aQuery)
       
   204     {
       
   205     PRINT ( _L("Enter CPcsAlgorithm1::ReplaceZeroWithSpaceL") );
       
   206 
       
   207        //PRINTQUERY ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL (BEFORE): "), aQuery );
       
   208 
       
   209        TBool queryModified = EFalse;    
       
   210 
       
   211        /* In phones like E52 and E55, where the "0" and the " " characters are on
       
   212         * the same key, the "0"s have to be considered as possible separators.
       
   213         *
       
   214         * In phones like N97 and E72, where the "0" and the " " characters are on
       
   215         * different keys, the "0"s must not be considered as possible separators.
       
   216         */
       
   217 
       
   218        // Skip initial "0"s, they are not replaced into spaces
       
   219        TInt skipIndex = 0;
       
   220        while ( (skipIndex < aQuery.Count()) && 
       
   221                (aQuery.GetItemAtL(skipIndex).Character().GetNumericValue() == 0) )
       
   222        {
       
   223            skipIndex++;
       
   224        }
       
   225        
       
   226        // Replace remaining "0"s into spaces in case they are entered with a keyboard
       
   227        // that has "0" and " " on the same key.
       
   228        const TInt queryCount = aQuery.Count();
       
   229        for ( TInt index = skipIndex; index < queryCount; index++ )
       
   230        {
       
   231            CPsQueryItem& item = aQuery.GetItemAtL(index);
       
   232 
       
   233            if ( iKeyMap->GetSpaceAndZeroOnSameKey( item.Mode() ) &&
       
   234                 item.Character().GetNumericValue() == 0 )
       
   235            {
       
   236                item.SetCharacter(KSpace);
       
   237                queryModified = ETrue;
       
   238            }
       
   239        }
       
   240        
       
   241        //PRINTQUERY ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL (AFTER): "), aQuery );
       
   242 
       
   243        PRINT1 ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL: Query modified (0=not, 1=yes): %d"), queryModified );
       
   244 
       
   245        PRINT ( _L("End CPcsAlgorithm1::ReplaceZeroWithSpaceL") );
       
   246 
       
   247        return  queryModified;
       
   248     }
       
   249 
       
   250 // ----------------------------------------------------------------------------
       
   251 // CPcsAlgorithm2::PerformSearchL
       
   252 // Search function for cache
       
   253 // ----------------------------------------------------------------------------
       
   254 void CPcsAlgorithm2::PerformSearchL(const CPsSettings& aSettings, 
       
   255                                     CPsQuery& aQuery, 
       
   256                                     RPointerArray<CPsClientData>& aSearchResults,
       
   257                                     RPointerArray<CPsPattern>& aSearchSeqs)
       
   258     {
       
   259     PRINT ( _L("Enter CPcsAlgorithm2::PerformSearchL") );
       
   260 
       
   261     //__LATENCY_MARK ( _L("CPcsAlgorithm2::PerformSearchL") );
       
   262     
       
   263     // Check aSettings   
       
   264     RPointerArray<TDesC> searchUris;
       
   265     CleanupResetAndDestroyPushL( searchUris );
       
   266     aSettings.SearchUrisL(searchUris);
       
   267          
       
   268     if ( searchUris.Count() <= 0)
       
   269     {
       
   270         PRINT ( _L("searchUris.Count() <= 0, Leave from CPcsAlgorithm1::PerformSearchL") );
       
   271         User::Leave(KErrArgument); 
       
   272     }
       
   273     CleanupStack::PopAndDestroy( &searchUris ); // ResetAndDestroy
       
   274 
       
   275     // Local arrays to hold the search results 
       
   276     RPointerArray<CPsData> tempSearchResults;
       
   277     CleanupClosePushL( tempSearchResults );
       
   278     RPointerArray<CPsData> tempSearchResults1;
       
   279     CleanupClosePushL( tempSearchResults1 );
       
   280 
       
   281     // -------------------- Perform the basic search --------------------------
       
   282 
       
   283     RemoveSpacesL(aQuery);
       
   284     PRINTQUERY ( _L("CPcsAlgorithm2::PerformSearchL: 1st search query: "), aQuery );
       
   285     DoSearchL(aSettings, aQuery, tempSearchResults, aSearchSeqs);
       
   286 
       
   287     // ------------------------------------------------------------------------
       
   288 
       
   289     // ---- Perform new search after "0" replacement if query is not empty ----
       
   290     /* Examples:
       
   291      * - If the original search string is "Abc0" then we will search again with "Abc".
       
   292      * - If the original search string is "00" then we will not search again.
       
   293      */
       
   294     TBool queryModified = ReplaceZeroWithSpaceL(aQuery);
       
   295     RemoveSpacesL(aQuery);
       
   296     // Perform query again if query got modified. 
       
   297     if (queryModified)
       
   298         {
       
   299         PRINTQUERY ( _L("CPcsAlgorithm2::PerformSearchL: 2nd search query: "), aQuery );
       
   300         DoSearchL(aSettings, aQuery, tempSearchResults1, aSearchSeqs);
       
   301 
       
   302 
       
   303         // Sort rule        
       
   304         TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder);
       
   305 
       
   306         // Avoid duplicates and add new results
       
   307         TIdentityRelation<CPsData> identityRule(CPsData::CompareById);
       
   308         const TInt tempSearchResults1Count = tempSearchResults1.Count();
       
   309         if (aSettings.GetSortType() != EAlphabetical)
       
   310             {
       
   311             TInt insertPos = 0;
       
   312             for (TInt i = 0; i < tempSearchResults1Count; i++)
       
   313                 {
       
   314                 if (tempSearchResults.Find(tempSearchResults1[i],
       
   315                                            identityRule) == KErrNotFound)
       
   316                     {
       
   317                     tempSearchResults.Insert(tempSearchResults1[i], insertPos);
       
   318                     insertPos++;
       
   319                     }
       
   320                 }
       
   321             }
       
   322         else
       
   323             {
       
   324             for (TInt i = 0; i < tempSearchResults1Count; i++)
       
   325                 {
       
   326                 if (tempSearchResults.Find(tempSearchResults1[i],
       
   327                                            identityRule) == KErrNotFound)
       
   328                     {
       
   329                     tempSearchResults.InsertInOrderAllowRepeats(tempSearchResults1[i], 
       
   330                                                                 rule);
       
   331                     }
       
   332                 }
       
   333             }
       
   334         }
       
   335     // ------------------------------------------------------------------------
       
   336 
       
   337     // ---------------------- Write result objects to the stream --------------
       
   338     // Truncate the result set if required
       
   339     TInt maxNumToDisplay = aSettings.MaxResults();
       
   340     TInt resultSetCount = tempSearchResults.Count();
       
   341     TInt numToDisplay = 0;
       
   342     if ( maxNumToDisplay == -1 )
       
   343         {
       
   344         numToDisplay = resultSetCount;
       
   345         }
       
   346     else
       
   347         {
       
   348         numToDisplay = Min( maxNumToDisplay, resultSetCount );
       
   349         }
       
   350 
       
   351     // Copy desired number of results from tempSearchResults to the results stream
       
   352     for (TInt i = 0; i < numToDisplay; i++)
       
   353         {
       
   354         aSearchResults.Append(WriteClientDataL(*(tempSearchResults[i])));
       
   355         }
       
   356     // ------------------------------------------------------------------------
       
   357 
       
   358     // Cleanup local results array
       
   359     CleanupStack::PopAndDestroy( &tempSearchResults1 ); // Close, don't destroy
       
   360     CleanupStack::PopAndDestroy( &tempSearchResults );  // Close, don't destroy
       
   361 
       
   362     // __LATENCY_MARKEND ( _L("CPcsAlgorithm2::PerformSearchL") );
       
   363 
       
   364     PRINT ( _L("End CPcsAlgorithm2::PerformSearchL") );
       
   365     }
       
   366 
       
   367 // ----------------------------------------------------------------------------
       
   368 // CPcsAlgorithm2::SearchInputL
       
   369 // Search function for input string
       
   370 // ----------------------------------------------------------------------------
       
   371 void CPcsAlgorithm2::SearchInputL(CPsQuery& aQuery, 
       
   372                                   TDesC& aData,
       
   373                                   RPointerArray<TDesC>& aMatchSet,
       
   374                                   RArray<TPsMatchLocation>& aMatchLocation)
       
   375     {
       
   376     // __LATENCY_MARK ( _L("CPcsAlgorithm2::SearchInputL: ") );
       
   377     PRINT ( _L("Enter CPcsAlgorithm2::SearchInputL") );
       
   378 
       
   379     // Print input query for debug
       
   380     PRINTQUERY ( _L("CPcsAlgorithm2::SearchInputL: Search query: "), aQuery );
       
   381 
       
   382     // Print received search data
       
   383     PRINT1 ( _L("Search data received = %S"), &aData);
       
   384 
       
   385 
       
   386     // -------------------- Perform the basic search --------------------------
       
   387 
       
   388     RemoveSpacesL(aQuery);
       
   389     DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation);
       
   390 
       
   391     // ------------------------------------------------------------------------   
       
   392 
       
   393     // ---- Perform new search after "0" replacement if query is not empty ----
       
   394     /* Examples:
       
   395      * - If the original search string is "Abc0" then we will search again with "Abc".
       
   396      * - If the original search string is "00" then we will not search again.
       
   397      */
       
   398     TBool queryModified = ReplaceZeroWithSpaceL(aQuery);
       
   399     RemoveSpacesL(aQuery);
       
   400     // If query got modified and the search query still contains something
       
   401     // perform a multi search again
       
   402     if (queryModified && aQuery.Count() > 0 && aMatchSet.Count() == 0  && aMatchLocation.Count() == 0 )
       
   403         {
       
   404         DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation);
       
   405         }
       
   406     // ------------------------------------------------------------------------
       
   407 
       
   408     // --- Remove overlapping items from aMatchLocation ---
       
   409     TInt i = 0;
       
   410     TBool incrementFirstCursor;
       
   411     while ( i < aMatchLocation.Count() )
       
   412         {
       
   413         incrementFirstCursor = ETrue;
       
   414         TInt j = i+1;
       
   415         while ( j < aMatchLocation.Count() )
       
   416             {
       
   417             if ( CPcsAlgorithm2Utils::MatchesOverlap( aMatchLocation[j], aMatchLocation[i] ) )
       
   418                 {
       
   419                 // Remove match location item with smallest length if 2 items have same index
       
   420                 if ( aMatchLocation[j].length <= aMatchLocation[i].length )
       
   421                     {
       
   422                     aMatchLocation.Remove(j);
       
   423                     continue; // Do not increment j
       
   424                     }
       
   425                 else
       
   426                     {
       
   427                     aMatchLocation.Remove(i);
       
   428                     incrementFirstCursor = EFalse; // Do not increment i
       
   429                     break;
       
   430                     }
       
   431                 }
       
   432             j++;
       
   433             }
       
   434         if ( incrementFirstCursor )
       
   435             {
       
   436             i++;
       
   437             }
       
   438         }
       
   439 
       
   440     // --- Remove from aMatchSet items which no longer have corresponding item in aMatchLocation ---
       
   441     HBufC* dataUpper = HBufC::NewLC(aData.Length());
       
   442     dataUpper->Des().Copy(aData);
       
   443     dataUpper->Des().UpperCase(); // Get uppercase, as aMatchSet is in upper case
       
   444 
       
   445     TInt k = 0;
       
   446     while ( k < aMatchSet.Count() )
       
   447         {
       
   448         TBool keepMatch = EFalse;
       
   449         TInt startCursor = -1;
       
   450 
       
   451         TInt offsetCursor;
       
   452         while ( KErrNotFound != (offsetCursor = dataUpper->Mid(startCursor + 1).Find(*aMatchSet[k])) )
       
   453             {
       
   454             // startCursor = index of match item *aMatchSet[k] into search string aData
       
   455             startCursor = offsetCursor + startCursor + 1;
       
   456             const TInt matchLocationCount = aMatchLocation.Count();
       
   457             for ( TInt i = 0; i < matchLocationCount; i++ )
       
   458                 {
       
   459                 // If match item was found in the location list, then keep it
       
   460                 if ( (aMatchLocation[i].index == startCursor) &&
       
   461                      (aMatchLocation[i].length == aMatchSet[k]->Length()) )
       
   462                     {
       
   463                     keepMatch = ETrue;
       
   464                     break;
       
   465                     }
       
   466                 }
       
   467             }
       
   468 
       
   469         if ( keepMatch )
       
   470             {
       
   471             k++;
       
   472             }
       
   473         else
       
   474             {
       
   475             aMatchSet.Remove(k); // Do not increment k
       
   476             }
       
   477         }
       
   478     CleanupStack::PopAndDestroy( dataUpper );
       
   479     // --- Remove items End ---
       
   480 
       
   481     // Sort match set
       
   482     iHelper->SortSearchSeqsL(aMatchSet);
       
   483 
       
   484     PRINT ( _L("End CPcsAlgorithm2::SearchInputL") );
       
   485     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchInputL") );
       
   486     }
       
   487 
       
   488 // ----------------------------------------------------------------------------
       
   489 // CPcsAlgorithm2::SearchMatchStringL
       
   490 // Search function for input string, result also as string
       
   491 // ----------------------------------------------------------------------------
       
   492 void CPcsAlgorithm2::SearchMatchStringL( CPsQuery& /*aSearchQuery*/,
       
   493                                          TDesC& /*aSearchData*/,
       
   494                                          TDes& /*aMatch*/ )
       
   495     {
       
   496     PRINT ( _L("Enter CPcsAlgorithm2::SearchMatchStringL") );
       
   497 
       
   498     //__LATENCY_MARK ( _L("CPcsAlgorithm2::SearchMatchStringL") ); 
       
   499     
       
   500     // TODO: Implementation missing
       
   501     
       
   502     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchMatchStringL") );
       
   503 
       
   504     PRINT ( _L("End CPcsAlgorithm2::SearchMatchStringL") );
       
   505     }
       
   506 
       
   507 // ----------------------------------------------------------------------------
       
   508 // CPcsAlgorithm2::DoSearchL
       
   509 // Search function helper
       
   510 // ----------------------------------------------------------------------------
       
   511 void CPcsAlgorithm2::DoSearchL( const CPsSettings& aSettings, 
       
   512                                 CPsQuery& aQuery, 
       
   513                                 RPointerArray<CPsData>& aSearchResults,
       
   514                                 RPointerArray<CPsPattern>& aSearchSeqs )
       
   515     {
       
   516     PRINT ( _L("Enter CPcsAlgorithm2::DoSearchL") );
       
   517 
       
   518     //__LATENCY_MARK ( _L("CPcsAlgorithm2::DoSearchL") ); 
       
   519     
       
   520     // -(0)----------------- Check if group search is required ---------------    
       
   521     RArray<TInt> contactsInGroup;
       
   522     CleanupClosePushL( contactsInGroup );
       
   523     RArray<TInt> groupIdArray;
       
   524     CleanupClosePushL( groupIdArray );
       
   525 
       
   526     // Create a new settings instance
       
   527     CPsSettings* tempSettings = aSettings.CloneL();
       
   528     CleanupStack::PushL( tempSettings );
       
   529 
       
   530     TBool isGroupSearch = IsGroupSearchL(*tempSettings, groupIdArray);
       
   531 
       
   532     if (isGroupSearch)
       
   533         {
       
   534         // Replace groups URI with contacts DB URI in new search settings
       
   535         ReplaceGroupsUriL(*tempSettings);
       
   536 
       
   537         // List of contacts in this group	
       
   538         GetContactsInGroupL(groupIdArray[0], contactsInGroup);
       
   539         }
       
   540 
       
   541     // -----------------------------------------------------------------------
       
   542 
       
   543 
       
   544     // Extract query list. 
       
   545     RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery);
       
   546     CleanupResetAndDestroyPushL( queryList );
       
   547 
       
   548     // (1)-------------------- No query return all contacts -------------------
       
   549     if (queryList.Count() == 0)
       
   550         {
       
   551         GetAllContentsL(*tempSettings, aSearchResults);
       
   552 
       
   553         if (isGroupSearch)
       
   554             {
       
   555             FilterSearchResultsForGroupsL(contactsInGroup, aSearchResults);
       
   556             }
       
   557         }
       
   558     // ------------------------------------------------------------------------
       
   559 
       
   560     // (2)-------------------- Perform a single query search ------------------
       
   561     else if (queryList.Count() == 1)
       
   562         {
       
   563         CPsQuery* query = queryList[0];
       
   564 
       
   565         // Search results
       
   566         iHelper->SearchSingleL(*tempSettings, *query, isGroupSearch,
       
   567                                contactsInGroup, aSearchResults, aSearchSeqs);
       
   568         }
       
   569     // ------------------------------------------------------------------------
       
   570 
       
   571     // (3)-------------------- Perform a multi query search -------------------
       
   572     else // multiple query
       
   573         {
       
   574         PRINT ( _L("Query received is in multiple. Performing a multi search.") );
       
   575 
       
   576         // Search results
       
   577         iMultiSearchHelper->SearchMultiL(*tempSettings, queryList, isGroupSearch, 
       
   578                                          contactsInGroup, aSearchResults, aSearchSeqs);
       
   579         }
       
   580     // -------------------------------------------------------------------------	
       
   581 
       
   582     // Cleanup
       
   583     
       
   584     CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy
       
   585     CleanupStack::PopAndDestroy( tempSettings );
       
   586     CleanupStack::PopAndDestroy( &groupIdArray ); // Close
       
   587     CleanupStack::PopAndDestroy( &contactsInGroup ); // Close
       
   588 
       
   589 	//__LATENCY_MARKEND ( _L("CPcsAlgorithm2::DoSearchL") );
       
   590 
       
   591     PRINT ( _L("End CPcsAlgorithm2::DoSearchL") );
       
   592     }
       
   593 
       
   594 // ----------------------------------------------------------------------------
       
   595 // CPcsAlgorithm2::DoSearchInputL
       
   596 // Search function helper
       
   597 // ----------------------------------------------------------------------------
       
   598 void CPcsAlgorithm2::DoSearchInputL(CPsQuery& aQuery, 
       
   599                                     const TDesC& aData,
       
   600                                     RPointerArray<TDesC>& aMatchSet,
       
   601                                     RArray<TPsMatchLocation>& aMatchLocation)
       
   602     {
       
   603 
       
   604     //__LATENCY_MARK ( _L("CPcsAlgorithm2::SearchInputL: ") );
       
   605     PRINT ( _L("Enter CPcsAlgorithm2::DoSearchInputL") );
       
   606 
       
   607     // Check if any seperator is there in the query
       
   608     RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery);
       
   609     CleanupResetAndDestroyPushL( queryList );
       
   610 
       
   611     // No query    
       
   612     if (queryList.Count() == 0)
       
   613         {
       
   614         PRINT ( _L("Query received is empty") );
       
   615         CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy
       
   616         return;
       
   617         }
       
   618 
       
   619     // Single query
       
   620     if (queryList.Count() == 1)
       
   621         {
       
   622         iHelper->SearchMatchSeqL(aQuery, aData, aMatchSet, aMatchLocation);
       
   623         }
       
   624 
       
   625     if (queryList.Count() > 1) // multiple query
       
   626         {
       
   627         PRINT ( _L("Query received is in multiple. Performing a multi search.") );
       
   628 
       
   629         // Search results
       
   630         iMultiSearchHelper->SearchMatchSeqMultiL(queryList, 
       
   631                                                  aData, 
       
   632                                                  aMatchSet,
       
   633                                                  aMatchLocation);
       
   634         }
       
   635 
       
   636     // Delete all the query elements
       
   637     CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy
       
   638     PRINT ( _L("End CPcsAlgorithm2::DoSearchInputL") );
       
   639     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchInputL") );
       
   640 
       
   641     }
       
   642 
       
   643 // ----------------------------------------------------------------------------
       
   644 // CPcsAlgorithm2::AddData
       
   645 // Add a data element to the pool
       
   646 // ----------------------------------------------------------------------------    
       
   647 void CPcsAlgorithm2::AddData(TDesC& aDataStore, CPsData* aData)
       
   648     {
       
   649     TInt arrayIndex = GetCacheIndex(aDataStore);
       
   650 
       
   651     if (arrayIndex < 0)
       
   652         return;
       
   653 
       
   654     CPcsCache* cache = iPcsCache[arrayIndex];
       
   655 
       
   656     // Fill the data store index
       
   657     TInt dataStoreIndex = FindStoreUri(aDataStore);
       
   658     if (dataStoreIndex >= 0)
       
   659         {
       
   660         aData->SetUriId(dataStoreIndex);
       
   661         }
       
   662     else
       
   663         {
       
   664         PRINT(_L("CPcsAlgorithm2::AddDataL Unknown data store"));
       
   665         return;
       
   666         }
       
   667     TRAPD(err, cache->AddToCacheL(*aData));
       
   668 
       
   669     if (err != KErrNone)
       
   670         {
       
   671         SetCachingError(aDataStore, err);
       
   672         }
       
   673     }
       
   674 
       
   675 // ----------------------------------------------------------------------------
       
   676 // CPcsAlgorithm2::RemoveData
       
   677 // Remove a data element from the pool
       
   678 // ----------------------------------------------------------------------------
       
   679 void CPcsAlgorithm2::RemoveData(TDesC &aDataStore, TInt aItemId)
       
   680     {
       
   681     TInt arrayIndex = GetCacheIndex(aDataStore);
       
   682 
       
   683     if (arrayIndex < 0)
       
   684         return;
       
   685 
       
   686     CPcsCache* cache = iPcsCache[arrayIndex];
       
   687     TRAPD(err, cache->RemoveFromCacheL(aItemId));
       
   688 
       
   689     if (err != KErrNone)
       
   690         {
       
   691         SetCachingError(aDataStore, err);
       
   692         }
       
   693     }
       
   694 
       
   695 // ---------------------------------------------------------------------
       
   696 // CPcsAlgorithm2::RemoveAll
       
   697 // Remove all the contacts from a datastore
       
   698 // ---------------------------------------------------------------------
       
   699 void CPcsAlgorithm2::RemoveAll(TDesC& aDataStore)
       
   700     {
       
   701     TInt dataStoreIndex = GetCacheIndex(aDataStore);
       
   702 
       
   703     if (dataStoreIndex < 0)
       
   704         return;
       
   705 
       
   706     CPcsCache* cache = iPcsCache[dataStoreIndex];
       
   707     cache->RemoveAllFromCache();
       
   708     }
       
   709 
       
   710 // ----------------------------------------------------------------------------
       
   711 // CPcsAlgorithm2::GetCacheIndex
       
   712 // Return the cache index for a data store
       
   713 // ----------------------------------------------------------------------------
       
   714 TInt CPcsAlgorithm2::GetCacheIndex(const TDesC& aDataStore)
       
   715     {
       
   716     const TInt pcsCacheCount = iPcsCache.Count();
       
   717     for (int i = 0; i <pcsCacheCount; i++)
       
   718         {
       
   719         CPcsCache* cache = iPcsCache[i];
       
   720 
       
   721         if (cache->GetURI().CompareC(aDataStore) == 0)
       
   722             return i;
       
   723         }
       
   724 
       
   725     return -1;
       
   726     }
       
   727 
       
   728 // ----------------------------------------------------------------------------
       
   729 // CPcsAlgorithm2::AddDataStore
       
   730 // Adds a new store
       
   731 // ----------------------------------------------------------------------------
       
   732 void CPcsAlgorithm2::AddDataStore(TDesC& aDataStore)
       
   733     {
       
   734     // Check if the datastore cache already exists
       
   735     TInt index = GetCacheIndex(aDataStore);
       
   736     if (index != -1)
       
   737         {
       
   738         // Already exists
       
   739         return;
       
   740         }
       
   741 
       
   742     // Create a new cache    
       
   743     CPcsCache* cache = NULL;
       
   744     TRAPD(err, cache = CPcsCache::NewL( this, aDataStore, *iKeyMap, iCacheCount));
       
   745     if (err != KErrNone)
       
   746         {
       
   747         SetCachingError(aDataStore, err);
       
   748         return;
       
   749         }
       
   750 
       
   751     // Increment the cachecount
       
   752     iCacheCount++;
       
   753 
       
   754     RArray<TInt> dataFields;
       
   755     TRAP(err, iPsDataPluginInterface->GetSupportedDataFieldsL(cache->GetURI(), dataFields));
       
   756     if (err != KErrNone)
       
   757         {
       
   758         SetCachingError(aDataStore, err);
       
   759         return;
       
   760         }
       
   761     cache->SetDataFields(dataFields);
       
   762 
       
   763     // Check if sort order is persisted already    
       
   764     RArray<TInt> sortOrder;
       
   765     TRAP(err, ReadSortOrderFromCenRepL(*(cache->GetUri()), sortOrder));
       
   766     if (err != KErrNone)
       
   767         {
       
   768         SetCachingError(aDataStore, err);
       
   769         return;
       
   770         }
       
   771 
       
   772     if (sortOrder.Count() == 0)
       
   773         {
       
   774         cache->SetSortOrder(dataFields); // Initial sort order	
       
   775         }
       
   776     else
       
   777         {
       
   778         cache->SetSortOrder(sortOrder); // Persisted sort order
       
   779         }
       
   780 
       
   781     sortOrder.Close();
       
   782     dataFields.Close();
       
   783 
       
   784     iPcsCache.Append(cache);
       
   785 
       
   786     TRAP(err, iPsDataPluginInterface->RequestForDataL(aDataStore));
       
   787     if (err != KErrNone)
       
   788         {
       
   789         SetCachingError(aDataStore, err);
       
   790         UpdateCachingStatus(aDataStore, ECachingCompleteWithErrors);
       
   791         return;
       
   792         }
       
   793     }
       
   794 
       
   795 // ----------------------------------------------------------------------------
       
   796 // CPcsAlgorithm2::RemoveDataStore
       
   797 // Removes an existing data store
       
   798 // ----------------------------------------------------------------------------
       
   799 void CPcsAlgorithm2::RemoveDataStore(TDesC& aDataStore)
       
   800     {
       
   801 
       
   802     for (int i = 0; i < iPcsCache.Count(); i++)
       
   803         {
       
   804         CPcsCache* cache = iPcsCache[i];
       
   805 
       
   806         if (cache->GetURI().CompareC(aDataStore) == 0)
       
   807             {
       
   808             delete iPcsCache[i];
       
   809             iPcsCache.Remove(i);
       
   810             iCacheCount--; 
       
   811             }
       
   812         }
       
   813     }
       
   814 
       
   815 // ----------------------------------------------------------------------------
       
   816 // CPcsAlgorithm2::IsLanguageSupportedL
       
   817 // Returns ETrue if this language is supported
       
   818 // ----------------------------------------------------------------------------
       
   819 TBool CPcsAlgorithm2::IsLanguageSupportedL(TUint32 aLang)
       
   820     {
       
   821     return iKeyMap->IsLanguageSupportedL(aLang);
       
   822     }
       
   823 
       
   824 // ----------------------------------------------------------------------------
       
   825 // CPcsAlgorithm2::GetUriForIdL
       
   826 // Get the URI string for this internal id
       
   827 // ----------------------------------------------------------------------------
       
   828 const TDesC& CPcsAlgorithm2::GetUriForIdL(TUint8 aUriId)
       
   829     {
       
   830     TBool found = EFalse;
       
   831     TInt i = 0;
       
   832     const TInt pcsCacheCount = iPcsCache.Count();
       
   833     for (i = 0; i < pcsCacheCount; i++)
       
   834         {
       
   835         if (iPcsCache[i]->GetUriId() == aUriId)
       
   836             {
       
   837             found = ETrue;
       
   838             break;
       
   839             }
       
   840         }
       
   841 
       
   842     if (!found)
       
   843         {
       
   844         User::Leave(KErrNotFound);
       
   845         }
       
   846 
       
   847     return *(iPcsCache[i]->GetUri());
       
   848     }
       
   849 
       
   850 // ----------------------------------------------------------------------------
       
   851 // CPcsAlgorithm2::FindStoreUri
       
   852 // Checks if this store exists
       
   853 // ----------------------------------------------------------------------------
       
   854 TInt CPcsAlgorithm2::FindStoreUri(const TDesC& aDataStore)
       
   855     {
       
   856     const TInt pcsCacheCount = iPcsCache.Count();
       
   857     for ( TInt i = 0; i < pcsCacheCount; i++ )
       
   858         {
       
   859         if ( aDataStore.CompareC(*(iPcsCache[i]->GetUri())) == 0 )
       
   860             {
       
   861             return i;
       
   862             }
       
   863         }
       
   864 
       
   865     return KErrNotFound;
       
   866     }
       
   867 
       
   868 // ----------------------------------------------------------------------------
       
   869 // CPcsAlgorithm2::UpdateCachingStatus
       
   870 // Update caching status
       
   871 // ----------------------------------------------------------------------------
       
   872 void CPcsAlgorithm2::UpdateCachingStatus(TDesC& aDataStore, TInt aStatus)
       
   873 {
       
   874     PRINT ( _L("Enter CPcsAlgorithm2::UpdateCachingStatus") );
       
   875     PRINT2 ( _L("CPcsAlgorithm2::UpdateCachingStatus: Request received for URI=%S with status=%d"),
       
   876              &aDataStore, aStatus );
       
   877 
       
   878     // Handle data store update events
       
   879     if ( aStatus == ECacheUpdateContactRemoved ||
       
   880          aStatus == ECacheUpdateContactModified ||
       
   881          aStatus == ECacheUpdateContactAdded )
       
   882         {
       
   883         HandleCacheUpdated( static_cast<TCachingStatus>(aStatus) );
       
   884         return;
       
   885         }
       
   886 
       
   887     // If not a cache update event, then this event is related to the initial
       
   888     // cache construction.
       
   889 
       
   890     // Check if any error occurred and update the cache error
       
   891     if ( aStatus < 0 )
       
   892     {
       
   893         SetCachingError(aDataStore, aStatus);
       
   894     }
       
   895     else
       
   896     {
       
   897         TInt index = FindStoreUri(aDataStore);
       
   898         iPcsCache[index]->UpdateCacheStatus(aStatus);
       
   899     }
       
   900 
       
   901     TCachingStatus status = ECachingNotStarted;
       
   902     TUint countNotStarted = 0;
       
   903     TUint countInProgress = 0;
       
   904     TUint countCompleted = 0;
       
   905     TUint countCompletedWithErrors = 0;
       
   906     TInt cacheCount = iPcsCache.Count();
       
   907     for ( TInt i = 0; i < cacheCount; i++ )
       
   908     {
       
   909         PRINT3 ( _L("CPcsAlgorithm2::UpdateCachingStatus: URI[%d]=%S, cache status=%d"),
       
   910                  i, &iPcsCache[i]->GetURI(), iPcsCache[i]->GetCacheStatus() );
       
   911 
       
   912         switch ( iPcsCache[i]->GetCacheStatus() )
       
   913         {
       
   914             case ECachingNotStarted:         
       
   915             {
       
   916                 countNotStarted++;          
       
   917                 break;
       
   918             }
       
   919             case ECachingInProgress:         
       
   920             {
       
   921                 countInProgress++;         
       
   922                 break;
       
   923             }
       
   924             case ECachingComplete:           
       
   925             {
       
   926                 countCompleted++;           
       
   927                 break;
       
   928             }
       
   929             case ECachingCompleteWithErrors: 
       
   930             {
       
   931                 countCompletedWithErrors++; 
       
   932                 break;
       
   933             }
       
   934             default:                         
       
   935             { 
       
   936                 // Default completed state
       
   937                 countCompleted++;           
       
   938                 break;
       
   939             }
       
   940         }
       
   941     }
       
   942 
       
   943     // Calculate cumulative status according to single caches statuses
       
   944     if ( countCompleted > 0 && ( countCompleted + countNotStarted ) == cacheCount )
       
   945     {
       
   946         // If at least one caching is finished
       
   947         // set status to ECachingComplete or ECachingCompleteWithErrors
       
   948         // according to iCacheError
       
   949         status = ( iCacheError == KErrNone ) ? ECachingComplete : ECachingCompleteWithErrors;
       
   950     }
       
   951     else if ( countInProgress > 0 )
       
   952     {
       
   953         // Else if at least one caching is in progress,
       
   954         // set status to ECachingInProgress
       
   955         status = ECachingInProgress;
       
   956     }
       
   957     else if ( countCompletedWithErrors > 0 )
       
   958     {
       
   959         // Else if at least one caching is completed with errors, 
       
   960         //set status to ECachingCompleteWithErrors
       
   961         status = ECachingCompleteWithErrors;
       
   962     }
       
   963     else
       
   964     {
       
   965         // countNotStarted == cacheCount
       
   966         // status is set to default ECachingNotStarted
       
   967     }
       
   968 
       
   969     PRINT1 ( _L("CPcsAlgorithm2::UpdateCachingStatus: Cumulative caching status is %d"),
       
   970              status );
       
   971 
       
   972     // Check if status changed
       
   973     if ( status != iCacheStatus )
       
   974     {
       
   975         PRINT2 ( _L("CPcsAlgorithm2::UpdateCachingStatus: Cumulative caching changed: %d -> %d"),
       
   976                  iCacheStatus, status );
       
   977 
       
   978         iCacheStatus = status;
       
   979         RProperty::Set(KPcsInternalUidCacheStatus, EPsKeyCacheStatus, iCacheStatus );
       
   980     }
       
   981 
       
   982     PRINT( _L("End CPcsAlgorithm2::UpdateCachingStatus") );
       
   983 }
       
   984 
       
   985 
       
   986 // ----------------------------------------------------------------------------
       
   987 // CPcsAlgorithm2::SetCachingError
       
   988 // Updates cachinge error
       
   989 // ----------------------------------------------------------------------------
       
   990 void CPcsAlgorithm2::SetCachingError(const TDesC& aDataStore, TInt aError)
       
   991     {
       
   992     PRINT2 ( _L("SetCachingError::URI %S ERROR %d"), &aDataStore, aError );
       
   993 
       
   994     iCacheError = aError;
       
   995     RProperty::Set( KPcsInternalUidCacheStatus, EPsKeyCacheError, iCacheError );
       
   996     }
       
   997 
       
   998 // ----------------------------------------------------------------------------
       
   999 // CPcsAlgorithm2::GetAllContentsL
       
  1000 // Returns all the contents of a store
       
  1001 // ----------------------------------------------------------------------------
       
  1002 void CPcsAlgorithm2::GetAllContentsL(const CPsSettings& aSettings,
       
  1003                                      RPointerArray<CPsData>& aResults)
       
  1004     {
       
  1005     //__LATENCY_MARK ( _L("CPcsAlgorithm2::GetAllContentsL") );
       
  1006 
       
  1007     PRINT ( _L("Enter CPcsAlgorithm2::GetAllContentsL") );
       
  1008 
       
  1009     // To hold array of results from different data stores
       
  1010     typedef RPointerArray<CPsData> CPSDATA_R_PTR_ARRAY;
       
  1011     RPointerArray<CPSDATA_R_PTR_ARRAY> searchResultsArr;
       
  1012     CleanupResetAndDestroyPushL( searchResultsArr );
       
  1013     // TODO: Here's still a potential memory leak if a leave happens. The child
       
  1014     // arrays of searchResultsArr are not Reset in that case. The CPsData objects
       
  1015     // may leak as well. Handling this safely is somewhat complicated because some of
       
  1016     // the CPsData objects may already be transferred to ownership of aResults array
       
  1017     // at the time the leave happens, and those items must not be deleted.
       
  1018     
       
  1019     // Get the data stores
       
  1020     RPointerArray<TDesC> dataStores;
       
  1021     CleanupResetAndDestroyPushL( dataStores );
       
  1022     aSettings.SearchUrisL(dataStores);
       
  1023 
       
  1024     // Get all contacts for each data store
       
  1025     const TInt dataStoresCount = dataStores.Count(); 
       
  1026     for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
       
  1027         {
       
  1028         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
       
  1029         searchResultsArr.Append(temp);
       
  1030 
       
  1031         TInt arrayIndex = GetCacheIndex(*(dataStores[dsIndex]));
       
  1032         if (arrayIndex < 0)
       
  1033             {
       
  1034             continue;
       
  1035             }
       
  1036 
       
  1037         CPcsCache* cache = GetCache(arrayIndex);
       
  1038 
       
  1039         cache->GetAllContentsL(*(searchResultsArr[dsIndex]));
       
  1040         }
       
  1041 
       
  1042     CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy
       
  1043 
       
  1044     // Merge the results from different data stores
       
  1045     CPcsAlgorithm2Utils::FormCompleteSearchResultsL(searchResultsArr, aResults);
       
  1046 
       
  1047     // Cleanup the local arrays
       
  1048     const TInt seaerchResultsArrCount = searchResultsArr.Count(); 
       
  1049     for (TInt i = 0; i < seaerchResultsArrCount; i++)
       
  1050         {
       
  1051         searchResultsArr[i]->Reset();
       
  1052         }
       
  1053 
       
  1054     CleanupStack::PopAndDestroy( &searchResultsArr ); // ResetAndDestroy
       
  1055 
       
  1056     PRINT1 ( _L("Number of results = %d"), aResults.Count() );
       
  1057 
       
  1058     PRINT ( _L("End CPcsAlgorithm2::GetAllContentsL") );
       
  1059 
       
  1060     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::GetAllContentsL") );
       
  1061     }
       
  1062 
       
  1063 // ----------------------------------------------------------------------------
       
  1064 // CPcsAlgorithm2::IsGroupSearchL
       
  1065 // Checks if a group search is required
       
  1066 // ----------------------------------------------------------------------------
       
  1067 TBool CPcsAlgorithm2::IsGroupSearchL(CPsSettings& aSettings,
       
  1068                                      RArray<TInt>& aGroupIdArray)
       
  1069     {
       
  1070     PRINT ( _L("Enter CPcsAlgorithm2::IsGroupSearchL") );
       
  1071 
       
  1072     // Get the groupIds in the seach settings
       
  1073     aSettings.GetGroupIdsL(aGroupIdArray);
       
  1074 
       
  1075     // Get the current URIs defined in settings    
       
  1076     RPointerArray<TDesC> searchUris;
       
  1077     CleanupResetAndDestroyPushL( searchUris );
       
  1078     aSettings.SearchUrisL(searchUris);
       
  1079 
       
  1080     if (aGroupIdArray.Count() && (searchUris.Count() > aGroupIdArray.Count()))
       
  1081         {
       
  1082         // There is an error, either there are more than one groups
       
  1083         // or the settings contain a combination of group/non-group Uris
       
  1084         aGroupIdArray.Close();
       
  1085         User::Leave(KErrArgument);
       
  1086         }
       
  1087 
       
  1088     CleanupStack::PopAndDestroy( &searchUris ); // ResetAndDestroy
       
  1089 
       
  1090     PRINT ( _L("End CPcsAlgorithm2::IsGroupSearchL") );
       
  1091 
       
  1092     if (aGroupIdArray.Count() == 1)
       
  1093         return ETrue;
       
  1094 
       
  1095     return EFalse;
       
  1096     }
       
  1097 
       
  1098 // ----------------------------------------------------------------------------
       
  1099 // CPcsAlgorithm2::ReplaceGroupsUriL
       
  1100 // Replace groups uri to contacts uri
       
  1101 // ----------------------------------------------------------------------------
       
  1102 void CPcsAlgorithm2::ReplaceGroupsUriL(CPsSettings& aSettings)
       
  1103     {
       
  1104     RPointerArray<TDesC> uri;
       
  1105     CleanupResetAndDestroyPushL( uri );
       
  1106 
       
  1107     // Set contacts db uri
       
  1108     HBufC* cntdb = KVPbkDefaultCntDbURI().AllocLC();
       
  1109     uri.AppendL(cntdb);
       
  1110     CleanupStack::Pop( cntdb ); // ownership transferred
       
  1111     aSettings.SetSearchUrisL(uri);
       
  1112 
       
  1113     // Cleanup
       
  1114     CleanupStack::PopAndDestroy( &uri ); // ResetAndDestroy
       
  1115     }
       
  1116 
       
  1117 // ----------------------------------------------------------------------------
       
  1118 // CPcsAlgorithm2::FilterSearchResultsForGroupsL
       
  1119 // Filters the results that belong to a group
       
  1120 // ----------------------------------------------------------------------------
       
  1121 void CPcsAlgorithm2::FilterSearchResultsForGroupsL(RArray<TInt>& contactsInGroup, 
       
  1122                                                    RPointerArray<CPsData>& aSearchResults)
       
  1123     {
       
  1124     PRINT ( _L("Enter CPcsAlgorithm2::FilterSearchResultsForGroupsL") );
       
  1125 
       
  1126     // for each search result
       
  1127     // Note: aSearchResults.Count() is to be checked everytime,
       
  1128     //       since the elements are being removed dynamically.
       
  1129     for (TInt j = 0; j < aSearchResults.Count(); j++)
       
  1130         {
       
  1131         TBool includeResult = EFalse;
       
  1132 
       
  1133         if (contactsInGroup.Find(aSearchResults[j]->Id()) != KErrNotFound)
       
  1134             {
       
  1135             includeResult = ETrue;
       
  1136             }
       
  1137 
       
  1138         if (includeResult == EFalse)
       
  1139             {
       
  1140             aSearchResults.Remove(j);
       
  1141             j--; // j is decremented, since that object is removed
       
  1142             }
       
  1143         }
       
  1144 
       
  1145     PRINT ( _L("End CPcsAlgorithm2::FilterSearchResultsForGroupsL") );
       
  1146     }
       
  1147 
       
  1148 // ----------------------------------------------------------------------------
       
  1149 // CPcsAlgorithm2::GetContactsInGroupL
       
  1150 // Recover contacts that belong to a group
       
  1151 // ----------------------------------------------------------------------------
       
  1152 void CPcsAlgorithm2::GetContactsInGroupL(TInt aGroupId, RArray<TInt>& aGroupContactIds)
       
  1153     {
       
  1154     // Clear results array
       
  1155     aGroupContactIds.Reset();
       
  1156     
       
  1157     // Cache Index for group database
       
  1158     TInt cacheIndex = GetCacheIndex(KVPbkDefaultGrpDbURI);
       
  1159     
       
  1160     // Get the groups contact ids 
       
  1161     if (cacheIndex != -1)
       
  1162         {
       
  1163         RPointerArray<CPsData> groups;
       
  1164         CleanupClosePushL( groups );
       
  1165 
       
  1166         // Get all groups
       
  1167         iPcsCache[cacheIndex]->GetAllContentsL(groups);
       
  1168 
       
  1169         // Get all contacts in group
       
  1170         const TInt groupsCount = groups.Count(); 
       
  1171         for (TInt i = 0; i < groupsCount; i++)
       
  1172             {
       
  1173             if (groups[i]->Id() == aGroupId)
       
  1174                 {
       
  1175                 groups[i]->IntDataExt(aGroupContactIds); // All contacts in group
       
  1176                 break;
       
  1177                 }
       
  1178             }
       
  1179 
       
  1180         CleanupStack::PopAndDestroy( &groups ); // Close
       
  1181         }
       
  1182     }
       
  1183 
       
  1184 // ----------------------------------------------------------------------------
       
  1185 // CPcsAlgorithm2::GetDataOrderL
       
  1186 // 
       
  1187 // ----------------------------------------------------------------------------
       
  1188 void CPcsAlgorithm2::GetDataOrderL(TDesC& aURI, RArray<TInt>& aDataOrder)
       
  1189     {
       
  1190     PRINT ( _L("End CPcsAlgorithm2::GetDataOrderL") );
       
  1191 
       
  1192     TInt arrayIndex = -1;
       
  1193 
       
  1194     if (CPcsAlgorithm2Utils::IsGroupUri(aURI))
       
  1195         {
       
  1196         // If search in a group uri, use contacts db
       
  1197         arrayIndex = GetCacheIndex(KVPbkDefaultCntDbURI);
       
  1198         }
       
  1199     else
       
  1200         {
       
  1201         arrayIndex = GetCacheIndex(aURI);
       
  1202         }
       
  1203 
       
  1204     if (arrayIndex < 0)
       
  1205         {
       
  1206         return;
       
  1207         }
       
  1208 
       
  1209     CPcsCache* cache = iPcsCache[arrayIndex];
       
  1210 
       
  1211     aDataOrder.Reset();
       
  1212 
       
  1213     // Get the data fields for this cache
       
  1214     cache->GetDataFields(aDataOrder);
       
  1215 
       
  1216     PRINT ( _L("End CPcsAlgorithm2::GetDataOrderL") );
       
  1217     }
       
  1218 
       
  1219 // ----------------------------------------------------------------------------
       
  1220 // CPcsAlgorithm2::GetSortOrderL
       
  1221 // 
       
  1222 // ----------------------------------------------------------------------------
       
  1223 void CPcsAlgorithm2::GetSortOrderL(TDesC& aURI, RArray<TInt>& aDataOrder)
       
  1224     {
       
  1225     PRINT ( _L("End CPcsAlgorithm2::GetSortOrderL") );
       
  1226 
       
  1227     TInt arrayIndex = -1;
       
  1228 
       
  1229     if (CPcsAlgorithm2Utils::IsGroupUri(aURI))
       
  1230         {
       
  1231         // If search in a group uri, use contacts db
       
  1232         arrayIndex = GetCacheIndex(KVPbkDefaultCntDbURI);
       
  1233         }
       
  1234     else
       
  1235         {
       
  1236         arrayIndex = GetCacheIndex(aURI);
       
  1237         }
       
  1238 
       
  1239     if (arrayIndex < 0)
       
  1240         {
       
  1241         return;
       
  1242         }
       
  1243 
       
  1244     CPcsCache* cache = iPcsCache[arrayIndex];
       
  1245 
       
  1246     aDataOrder.Reset();
       
  1247 
       
  1248     // Get the data fields for this cache
       
  1249     cache->GetSortOrder(aDataOrder);
       
  1250 
       
  1251     PRINT ( _L("End CPcsAlgorithm2::GetSortOrderL") );
       
  1252     }
       
  1253 
       
  1254 // ----------------------------------------------------------------------------
       
  1255 // CPcsAlgorithm2::ChangeSortOrderL
       
  1256 // 
       
  1257 // ----------------------------------------------------------------------------
       
  1258 void CPcsAlgorithm2::ChangeSortOrderL(TDesC& aURI, RArray<TInt>& aSortOrder)
       
  1259     {
       
  1260     PRINT ( _L("Enter CPcsAlgorithm2::ChangeSortOrderL.") );
       
  1261 
       
  1262     PRINT ( _L("CPcsAlgorithm2::ChangeSortOrderL. Sort order change received.") );
       
  1263     PRINT1 ( _L("URI = %S"), &aURI );
       
  1264 
       
  1265     // If URI is search in a group URI return       
       
  1266     if (CPcsAlgorithm2Utils::IsGroupUri(aURI))
       
  1267         {
       
  1268         PRINT ( _L("CPcsAlgorithm2::ChangeSortOrderL. Sort order change not supported.") );
       
  1269         return;
       
  1270         }
       
  1271 
       
  1272     // Check if a cache exists
       
  1273     TInt arrayIndex = GetCacheIndex(aURI);
       
  1274     if (arrayIndex < 0)
       
  1275         {
       
  1276         PRINT ( _L("CPcsAlgorithm2::ChangeSortOrderL. Cache for URI doesn't exist.") );
       
  1277         return;
       
  1278         }
       
  1279 
       
  1280     // Cache instance for this URI
       
  1281     CPcsCache* cache = iPcsCache[arrayIndex];
       
  1282 
       
  1283     // Check if received sort order is same as before
       
  1284     RArray<TInt> mySortOrder;
       
  1285     cache->GetSortOrder(mySortOrder);
       
  1286 
       
  1287     if (aSortOrder.Count() == mySortOrder.Count())
       
  1288         {
       
  1289         TBool same = ETrue;
       
  1290         const TInt mySourtOrderCount = mySortOrder.Count(); 
       
  1291         for ( TInt i = 0; i < mySourtOrderCount ; i++ )
       
  1292             {
       
  1293             if (mySortOrder[i] != aSortOrder[i])
       
  1294                 {
       
  1295                 same = EFalse;
       
  1296                 break;
       
  1297                 }
       
  1298             }
       
  1299 
       
  1300         if (same)
       
  1301             {
       
  1302             PRINT ( _L("CPcsAlgorithm2::ChangeSortOrderL. Same sort order received. Ignoring ...") );
       
  1303             PRINT ( _L("End CPcsAlgorithm2::ChangeSortOrderL.") );
       
  1304             mySortOrder.Reset();
       
  1305             return;
       
  1306             }
       
  1307         }
       
  1308 
       
  1309     mySortOrder.Reset();
       
  1310 
       
  1311     PRINT ( _L("CPcsAlgorithm2::ChangeSortOrderL. New sort order received. Refreshing ...") );
       
  1312 
       
  1313     // Set the new sort order on the cache
       
  1314     cache->SetSortOrder(aSortOrder);
       
  1315 
       
  1316     // Persist the changes in sort order
       
  1317     WriteSortOrderToCenRepL(aURI, aSortOrder);
       
  1318 
       
  1319     // Request for data again
       
  1320     TInt err = KErrNone;
       
  1321     TRAP(err, cache->ResortdataInPoolsL());
       
  1322     if (err != KErrNone)
       
  1323         {
       
  1324         PRINT ( _L("CPcsAlgorithm1::ChangeSortOrderL() Set Caching Error ") );
       
  1325         SetCachingError(aURI, err);
       
  1326         UpdateCachingStatus(aURI, ECachingCompleteWithErrors);
       
  1327         return;
       
  1328         }
       
  1329 
       
  1330     PRINT ( _L("End CPcsAlgorithm2::ChangeSortOrderL.") );
       
  1331     }
       
  1332 
       
  1333 // ---------------------------------------------------------------------------------
       
  1334 // Read the persisted sort order from the central repository
       
  1335 // Persisted sort order is of form URI Field1 Field2 Field3 .. FieldN (space delimited)
       
  1336 // ---------------------------------------------------------------------------------
       
  1337 void CPcsAlgorithm2::ReadSortOrderFromCenRepL(const TDesC& aURI, RArray<TInt>& aSortOrder)
       
  1338     {
       
  1339     PRINT ( _L("Enter CPcsAlgorithm2::ReadSortOrderFromCenRepL.") );
       
  1340 
       
  1341     aSortOrder.Reset();
       
  1342 
       
  1343     CRepository *repository = CRepository::NewL(KCRUidPSSortOrder);
       
  1344 
       
  1345     // Read the sort order from cenrep
       
  1346     TBuf<KCRMaxLen> str;
       
  1347 
       
  1348     for ( TInt i(KCenrepFieldsStartKey); 
       
  1349           i < KCenrepFieldsStartKey + KCenrepNumberOfFieldsCount; 
       
  1350           i++ )
       
  1351         {
       
  1352         TInt err = repository->Get(i, str);
       
  1353 
       
  1354         if (KErrNone != err)
       
  1355             {
       
  1356             break;
       
  1357             }
       
  1358 
       
  1359         if (str != KNullDesC)
       
  1360             {
       
  1361             TLex lex(str);
       
  1362 
       
  1363             // Extract the URI
       
  1364             TPtrC token = lex.NextToken();
       
  1365 
       
  1366             if (aURI.Compare(token) == 0)
       
  1367                 {
       
  1368                 // Extract the sort order
       
  1369                 token.Set(lex.NextToken());
       
  1370 
       
  1371                 while (token.Length() != 0)
       
  1372                     {
       
  1373                     TLex lex1(token);
       
  1374 
       
  1375                     TInt intVal;
       
  1376                     TInt err = lex1.Val(intVal);
       
  1377 
       
  1378                     if (KErrNone == err)
       
  1379                         {
       
  1380                         aSortOrder.Append(intVal);
       
  1381                         }
       
  1382 
       
  1383                     // Next token
       
  1384                     token.Set(lex.NextToken());
       
  1385                     }
       
  1386 
       
  1387                 break;
       
  1388                 }
       
  1389             }
       
  1390 
       
  1391         }
       
  1392 
       
  1393     delete repository;
       
  1394 
       
  1395     PRINT ( _L("End CPcsAlgorithm2::ReadSortOrderFromCenRepL.") );
       
  1396     }
       
  1397 
       
  1398 // ---------------------------------------------------------------------------------
       
  1399 // Write the sort order into the central repository
       
  1400 // Persisted sort order is of form URI Field1 Field2 Field3 .. FieldN (space delimited)
       
  1401 // ---------------------------------------------------------------------------------
       
  1402 void CPcsAlgorithm2::WriteSortOrderToCenRepL(const TDesC& aURI, RArray<TInt>& aSortOrder)
       
  1403     {
       
  1404     PRINT ( _L("Enter CPcsAlgorithm2::WriteSortOrderToCenRepL.") );
       
  1405 
       
  1406     CRepository* repository = CRepository::NewLC(KCRUidPSSortOrder);
       
  1407 
       
  1408     // Check if there an entry for this URI in cenrep
       
  1409     TBuf<KCRMaxLen> str;
       
  1410     TInt keyIndex = -1;
       
  1411 
       
  1412     for ( TInt i(KCenrepFieldsStartKey); 
       
  1413           i < KCenrepFieldsStartKey + KCenrepNumberOfFieldsCount; 
       
  1414           i++ )
       
  1415         {
       
  1416         TInt err = repository->Get(i, str);
       
  1417 
       
  1418         if (KErrNone != err)
       
  1419             {
       
  1420             PRINT ( _L("CPcsAlgorithm2::WriteSortOrderToCenRepL. cenrep error.") );
       
  1421             return;
       
  1422             }
       
  1423 
       
  1424         if (str != KNullDesC)
       
  1425             {
       
  1426             TLex lex(str);
       
  1427 
       
  1428             // Extract the URI
       
  1429             TPtrC token = lex.NextToken();
       
  1430 
       
  1431             if (aURI.Compare(token) == 0)
       
  1432                 {
       
  1433                 keyIndex = i; // i has the key index for this URI
       
  1434                 break;
       
  1435                 }
       
  1436             }
       
  1437         }
       
  1438 
       
  1439     // No entry for this URI in cenrep
       
  1440     // Find the next free location in cenrep
       
  1441     if (keyIndex == -1)
       
  1442         {
       
  1443         // Find the next free key index
       
  1444         for ( TInt i(KCenrepFieldsStartKey); 
       
  1445               i < KCenrepFieldsStartKey + KCenrepNumberOfFieldsCount; 
       
  1446               i++ )
       
  1447             {
       
  1448             TInt err = repository->Get(i, str);
       
  1449 
       
  1450             if (KErrNone != err)
       
  1451                 {
       
  1452                 PRINT ( _L("CPcsAlgorithm2::WriteSortOrderToCenRepL. cenrep error.") );
       
  1453                 return;
       
  1454                 }
       
  1455 
       
  1456             if (str == KNullDesC)
       
  1457                 {
       
  1458                 keyIndex = i; // i has the next free location
       
  1459                 break;
       
  1460                 }
       
  1461             }
       
  1462         }
       
  1463 
       
  1464     if (keyIndex == -1)
       
  1465         {
       
  1466         PRINT ( _L("CPcsAlgorithm2::WriteSortOrderToCenRepL. Persist limit violated.") );
       
  1467         return;
       
  1468         }
       
  1469 
       
  1470     // Persist the sort order
       
  1471     HBufC* str1 = HBufC::NewLC(KCRMaxLen);
       
  1472     TPtr ptr(str1->Des());
       
  1473 
       
  1474     // Append the URI
       
  1475     ptr.Append(aURI);
       
  1476     ptr.Append(KSpace);
       
  1477 
       
  1478     // Append the sort order fields
       
  1479     const TInt sortOrderCount =  aSortOrder.Count();
       
  1480     for (TInt j = 0; j < sortOrderCount; j++)
       
  1481         {
       
  1482         ptr.AppendNum(aSortOrder[j]);
       
  1483         ptr.Append(KSpace);
       
  1484         }
       
  1485 
       
  1486     // Write to persistent store
       
  1487     TInt err = repository->Set(keyIndex, ptr);
       
  1488 
       
  1489     User::LeaveIfError(err);
       
  1490 
       
  1491     CleanupStack::PopAndDestroy( str1 );
       
  1492 
       
  1493     CleanupStack::PopAndDestroy( repository );
       
  1494 
       
  1495     PRINT ( _L("End CPcsAlgorithm2::WriteSortOrderToCenRepL.") );
       
  1496     }
       
  1497 
       
  1498 // ---------------------------------------------------------------------------------
       
  1499 // WriteClientDataL.
       
  1500 // Write the content required by client
       
  1501 // ---------------------------------------------------------------------------------
       
  1502 CPsClientData* CPcsAlgorithm2::WriteClientDataL(CPsData& aPsData)
       
  1503     {
       
  1504     CPsClientData* clientData = CPsClientData::NewL();
       
  1505     CleanupStack::PushL(clientData);
       
  1506 
       
  1507     // set Id
       
  1508     clientData->SetId(aPsData.Id());
       
  1509 
       
  1510     // set Uri
       
  1511     clientData->SetUriL(GetUriForIdL(aPsData.UriId()));
       
  1512 
       
  1513     // set pointer to the each data element
       
  1514     const TInt dataElementCount = aPsData.DataElementCount(); 
       
  1515     for (TInt i = 0; i <dataElementCount; i++)
       
  1516         {
       
  1517         clientData->SetDataL(i, *(aPsData.Data(i)));
       
  1518         }
       
  1519 
       
  1520     // set data extension
       
  1521     clientData->SetDataExtensionL(aPsData.DataExtension());
       
  1522 
       
  1523     // Set the Field match
       
  1524     clientData->SetFieldMatch(aPsData.DataMatch());
       
  1525     CleanupStack::Pop(clientData);
       
  1526 
       
  1527     return clientData;
       
  1528     }
       
  1529 
       
  1530 // ---------------------------------------------------------------------------------
       
  1531 // HandleCacheUpdated.
       
  1532 // ---------------------------------------------------------------------------------
       
  1533 void CPcsAlgorithm2::HandleCacheUpdated( TCachingStatus aStatus )
       
  1534     {
       
  1535     TInt psKey( KErrNotFound );
       
  1536     
       
  1537     switch ( aStatus )
       
  1538         {
       
  1539         case ECacheUpdateContactRemoved:
       
  1540             psKey = EPsKeyContactRemovedCounter;
       
  1541             break;
       
  1542             
       
  1543         case ECacheUpdateContactModified:
       
  1544             psKey = EPsKeyContactModifiedCounter;
       
  1545             break;
       
  1546             
       
  1547         case ECacheUpdateContactAdded:
       
  1548             psKey = EPsKeyContactAddedCounter;
       
  1549             break;
       
  1550             
       
  1551         default:
       
  1552             break;
       
  1553         }
       
  1554     
       
  1555     // Increment the relevant counter in P&S by one to signal the clients about
       
  1556     // the cache update.
       
  1557     if( psKey != KErrNotFound )
       
  1558         {
       
  1559         TInt counter( KErrNotFound );
       
  1560         TInt err = RProperty::Get( KPcsInternalUidCacheStatus, psKey, counter );
       
  1561         if ( !err )
       
  1562             {
       
  1563             counter++;
       
  1564             RProperty::Set( KPcsInternalUidCacheStatus, psKey, counter );
       
  1565             }
       
  1566         }
       
  1567     }
       
  1568 
       
  1569 // ---------------------------------------------------------------------------------
       
  1570 // ReconstructCacheDataL.
       
  1571 // ---------------------------------------------------------------------------------
       
  1572 void CPcsAlgorithm2::ReconstructCacheDataL()
       
  1573     {
       
  1574     PRINT ( _L("Enter CPcsAlgorithm2::ReconstructCacheDataL.") );
       
  1575 
       
  1576     TInt err;
       
  1577     TRAP( err, iKeyMap->ReconstructKeymapL());
       
  1578     if (err != KErrNone)
       
  1579         {    
       
  1580         PRINT1 ( _L("keyMap ReconstructKeymapL, err =%d"),err );
       
  1581         }
       
  1582     
       
  1583     for (TInt index = 0; index < iCacheCount; index++)
       
  1584         {
       
  1585         CPcsCache* cache = iPcsCache[index];
       
  1586 
       
  1587         HBufC* uri = cache->GetUri();
       
  1588         // Clear the cache
       
  1589         cache->RemoveAllFromCache();
       
  1590 
       
  1591         if (err != KErrNone)
       
  1592             {
       
  1593             SetCachingError(*uri, err);
       
  1594             }
       
  1595         //Update the caching status as ECachingInProgress, since now the caching
       
  1596         // would be started again
       
  1597         UpdateCachingStatus(*uri, ECachingInProgress);
       
  1598 
       
  1599         // Request for data again
       
  1600         TRAP(err, iPsDataPluginInterface->RequestForDataL(*uri));
       
  1601         PRINT1 ( _L("iPsDataPluginInterface->RequestForDataL, err =%d"),err );
       
  1602 
       
  1603         if (err != KErrNone)
       
  1604             {
       
  1605             SetCachingError(*uri, err);
       
  1606             }
       
  1607         }
       
  1608     }
       
  1609 
       
  1610 // ---------------------------------------------------------------------------------
       
  1611 // DoLaunchPluginsL.
       
  1612 // launch plugins by idle
       
  1613 // ---------------------------------------------------------------------------------
       
  1614 TInt CPcsAlgorithm2::DoLaunchPluginsL(TAny* aPtr)
       
  1615     {
       
  1616     CPcsAlgorithm2* ptr = (CPcsAlgorithm2*) aPtr;
       
  1617     ptr->DoLaunchPluginsL();
       
  1618     return EFalse;
       
  1619     }
       
  1620 
       
  1621 // ---------------------------------------------------------------------------------
       
  1622 // DoLaunchPluginsL.
       
  1623 // lauch plugins
       
  1624 // ---------------------------------------------------------------------------------
       
  1625 void CPcsAlgorithm2::DoLaunchPluginsL()
       
  1626     {
       
  1627     // Initialize available data adapters
       
  1628     iPsDataPluginInterface = CPsDataPluginInterface::NewL(this, this);
       
  1629     iPsDataPluginInterface->InstantiateAllPlugInsL();
       
  1630 
       
  1631     // Store the cache list in TLS
       
  1632     // Required to support sort order changes in a memory efficient way
       
  1633     // This avoids storing sort order information in the CPsData element
       
  1634     // and storing it in CPcsCache. Refer CPcsAlgorithm2Utils::CompareDataBySortOrder
       
  1635     // to see how this is being used.
       
  1636     User::LeaveIfError(Dll::SetTls(&iPcsCache));
       
  1637 
       
  1638     // Initialize cache
       
  1639     RPointerArray<TDesC> dataStores;
       
  1640     CleanupClosePushL( dataStores );
       
  1641 
       
  1642     iPsDataPluginInterface->GetAllSupportedDataStoresL(dataStores);
       
  1643 
       
  1644     const TInt dataStoresCount = dataStores.Count();
       
  1645     for (TInt dIndex = 0; dIndex < dataStoresCount; dIndex++)
       
  1646         {
       
  1647         AddDataStore(*(dataStores[dIndex]));
       
  1648         }
       
  1649 
       
  1650     CleanupStack::PopAndDestroy( &dataStores ); // Close
       
  1651     }
       
  1652 
       
  1653 /**
       
  1654 * Returns the Adaptive Grid for one or more URI
       
  1655 * 
       
  1656 */
       
  1657  void CPcsAlgorithm2::GetAdaptiveGridL( const MDesCArray& /*aURIs*/,
       
  1658                                const TBool /*aCompanyName*/,
       
  1659                                TDes& /*aAdaptiveGrid*/ )
       
  1660     {
       
  1661      PRINT ( _L("Enter CPcsAlgorithm2::GetAdaptiveGridL") );
       
  1662 
       
  1663 
       
  1664      PRINT ( _L("End CPcsAlgorithm2::GetAdaptiveGridL") );
       
  1665 
       
  1666     }
       
  1667 // End of file
       
  1668