predictivesearch/adapters/contacts/src/cpcscontactstore.cpp
changeset 0 e686773b3f54
child 6 e8e3147d53eb
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     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:  Active object to read all the contacts from a 
       
    15 *                particular data store. Handles add/ modify/ delete of contacts.
       
    16 *
       
    17 */
       
    18 
       
    19 // SYSTEM INCLUDES
       
    20 #include <barsread.h>
       
    21 #include <coemain.h>
       
    22 #include <utf.h>
       
    23 #include <e32std.h>
       
    24 #include <badesca.h>
       
    25 #include <CVPbkContactManager.h>
       
    26 #include <CVPbkContactStoreUriArray.h>
       
    27 #include <CVPbkContactFieldIterator.h>
       
    28 #include <CVPbkFieldTypeRefsList.h>
       
    29 #include <CVPbkContactLinkArray.h>
       
    30 #include <TVPbkContactStoreUriPtr.h>
       
    31 #include <MVPbkContactOperationBase.h>
       
    32 #include <MVPbkContactStoreList.h>
       
    33 #include <MVPbkContactStore.h>
       
    34 #include <MVPbkStoreContact.h>
       
    35 #include <MVPbkContactFieldData.h>
       
    36 #include <MVPbkContactFieldTextData.h>
       
    37 #include <MVPbkContactStoreProperties.h>
       
    38 #include <MVPbkContactLink.h>
       
    39 #include <VPbkEng.rsg>
       
    40 #include <VPbkContactStoreUris.h>
       
    41 #include <CVPbkContactViewDefinition.h>
       
    42 #include <MVPbkContactViewBase.h>
       
    43 #include <VPbkContactView.hrh>
       
    44 #include <CVPbkContactIdConverter.h>
       
    45 #include <centralrepository.h>
       
    46 #include <MVPbkContactGroup.h>
       
    47 #include <CVPbkFieldTypeSelector.h>
       
    48 #include <CVPbkContactLinkArray.h>
       
    49 #include <CVPbkSortOrder.h>
       
    50 #include <data_caging_path_literals.hrh>
       
    51 #include <bautils.h>
       
    52 
       
    53 // USER INCLUDES
       
    54 #include "cpcscontactstore.h"
       
    55 #include "CPsData.h"
       
    56 #include "CPcsDebug.h" 
       
    57 #include "CPcsDefs.h"
       
    58 #include <contactsort.rsg>
       
    59 
       
    60 // CONSTANTS
       
    61 const TInt KSimStoreOffset            = -5000;
       
    62 
       
    63 _LIT(KResourceFileName, "contactsort.rsc");
       
    64 _LIT(KPcsViewPrefix,"PCSView_");
       
    65 
       
    66 // FORWARD DECLARATION
       
    67 
       
    68 // ============================== MEMBER FUNCTIONS ================================
       
    69 
       
    70 // ---------------------------------------------------------------------------------
       
    71 // 2 phase construction
       
    72 // ---------------------------------------------------------------------------------
       
    73 CPcsContactStore* CPcsContactStore::NewL(CVPbkContactManager&  aContactManager,
       
    74                                          MDataStoreObserver& aObserver,
       
    75                                          const TDesC& aUri)
       
    76 {
       
    77 	PRINT ( _L("Enter CPcsContactStore::NewL") );
       
    78 
       
    79 	CPcsContactStore* self = new ( ELeave ) CPcsContactStore( );
       
    80 	CleanupStack::PushL( self );
       
    81 	
       
    82 	self->ConstructL(aContactManager,aObserver,aUri);
       
    83 	CleanupStack::Pop( self );
       
    84 	
       
    85 	PRINT ( _L("End CPcsContactStore::NewL") );
       
    86 	return self;
       
    87 }
       
    88 
       
    89 // ---------------------------------------------------------------------------------
       
    90 // Constructor
       
    91 // ---------------------------------------------------------------------------------
       
    92 CPcsContactStore::CPcsContactStore():
       
    93 	CActive( CActive::EPriorityLow),
       
    94     iAllContactLinksCount(0),
       
    95     iFetchedContactCount(0),
       
    96     iContactViewReady(EFalse)
       
    97 {
       
    98     PRINT ( _L("Enter CPcsContactStore::CPcsContactStore") );
       
    99     CActiveScheduler::Add( this );
       
   100 	PRINT ( _L("End CPcsContactStore::CPcsContactStore") );
       
   101 }
       
   102 
       
   103 
       
   104 // ---------------------------------------------------------------------------------
       
   105 // CPcsContactStore::ConstructL() 
       
   106 // 2nd phase constructor
       
   107 // ---------------------------------------------------------------------------------
       
   108 void CPcsContactStore::ConstructL(CVPbkContactManager&  aContactManager,
       
   109                                   MDataStoreObserver& aObserver,
       
   110                                   const TDesC& aUri)
       
   111 {
       
   112     PRINT ( _L("Enter CPcsContactStore::ConstructL") );
       
   113     
       
   114 	iContactManager  = &aContactManager;
       
   115 	iObserver = &aObserver;
       
   116 	
       
   117 	iUri = HBufC::NewL(aUri.Length());
       
   118 	iUri->Des().Copy(aUri);
       
   119 	
       
   120 	// create containers for holding the sim data      
       
   121     iSimContactItems = CVPbkContactLinkArray::NewL();
       
   122    
       
   123 	
       
   124 	// for creating sort order
       
   125 	iSortOrder = CVPbkFieldTypeRefsList::NewL();
       
   126 	
       
   127 	// Read the fields to cache from the central repository
       
   128 	ReadFieldsToCacheFromCenrepL();
       
   129 	
       
   130     // Local timer for block fetch delay
       
   131     iTimer.CreateLocal();
       
   132     
       
   133     // Initial state
       
   134 	iNextState = ECreateView;
       
   135 	IssueRequest();
       
   136 	
       
   137 	PRINT ( _L("End CPcsContactStore::ConstructL") );
       
   138 }
       
   139 
       
   140 // ---------------------------------------------------------------------------------
       
   141 // Destructor
       
   142 // ---------------------------------------------------------------------------------
       
   143 CPcsContactStore::~CPcsContactStore() 
       
   144 {
       
   145 	PRINT ( _L("Enter CPcsContactStore::~CPcsContactStore") );
       
   146 	
       
   147 	delete iContactViewBase;
       
   148 	iContactViewBase = NULL;
       
   149 	
       
   150 	delete iSortOrder;
       
   151 	iSortOrder = NULL;
       
   152 	
       
   153     delete iSimContactItems;
       
   154     iSimContactItems = NULL ;
       
   155      
       
   156 	delete iWait;
       
   157 	iWait = NULL;
       
   158 	
       
   159 	delete iUri;
       
   160 	iUri = NULL;
       
   161 		
       
   162 	iTimer.Cancel();
       
   163     iTimer.Close();
       
   164 	iFieldsToCache.Close();	
       
   165 	
       
   166 	iFs.Close();
       
   167 	
       
   168 	if(IsActive())
       
   169 	{
       
   170 		Deque();
       
   171 	}
       
   172 	
       
   173 	PRINT ( _L("End CPcsContactStore::~CPcsContactStore") );
       
   174 }
       
   175 
       
   176 
       
   177 // ---------------------------------------------------------------------------------
       
   178 // Handles addition/deletion/modification of contacts
       
   179 // ---------------------------------------------------------------------------------
       
   180 void CPcsContactStore::HandleStoreEventL(MVPbkContactStore& aContactStore, 
       
   181                 TVPbkContactStoreEvent aStoreEvent)
       
   182 {
       
   183    	PRINT ( _L("Enter CPcsContactStore::HandleStoreEventL") );
       
   184 
       
   185 	switch (aStoreEvent.iEventType) 
       
   186 	{
       
   187 		case TVPbkContactStoreEvent::EContactAdded:
       
   188 		{
       
   189 		    PRINT ( _L("Add contact/group event received") );
       
   190 		    iContactManager->RetrieveContactL( *(aStoreEvent.iContactLink),
       
   191 	                                           *this);
       
   192 			break;
       
   193 		}
       
   194 		
       
   195         case TVPbkContactStoreEvent::EUnknownChanges:
       
   196             {
       
   197             iObserver->RemoveAll( *iUri );
       
   198             iContactViewReady = EFalse;
       
   199             iContactViewBase->AddObserverL(*this);
       
   200             }
       
   201             break;
       
   202 
       
   203 		case TVPbkContactStoreEvent::EContactDeleted:
       
   204 		case TVPbkContactStoreEvent::EContactChanged:
       
   205 		case TVPbkContactStoreEvent::EGroupDeleted:
       
   206 		case TVPbkContactStoreEvent::EGroupChanged:
       
   207 		{
       
   208 		    if ( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactChanged ) 
       
   209 		    {
       
   210 		    	PRINT ( _L("Change contact/group event received") );
       
   211 		    }
       
   212 		    else 
       
   213 		    {
       
   214 		    	PRINT ( _L("Delete contact/group event received") );
       
   215 		    }
       
   216 			
       
   217 			CVPbkContactIdConverter* converter = NULL;
       
   218 			
       
   219 		    TRAPD ( err, converter = CVPbkContactIdConverter::NewL( aContactStore ) );
       
   220 
       
   221 	        TInt32 contactId(-1);
       
   222 	        
       
   223 	        if ( err == KErrNotSupported )
       
   224 	        {
       
   225 	            // sim domain  
       
   226 	            // Pass the sim observer string in the next line
       
   227 	            TInt contactLocation =  iSimContactItems->Find(*aStoreEvent.iContactLink);	
       
   228 				if( KErrNotFound != contactLocation)
       
   229 				{
       
   230 				    // We are not removing from the array cache. If you try to fetch, 
       
   231 				    // then it will give an error			       
       
   232 				    TInt index = CreateCacheIDfromSimArrayIndex (contactLocation);
       
   233 				    
       
   234 	                iObserver->RemoveData(*iUri,index );
       
   235 		       	} 	               	           
       
   236 		               	           
       
   237 	        }
       
   238 	        else
       
   239 	        {
       
   240 	           // cntdb domain
       
   241 	           // Get contact id by mapping the link
       
   242 	           contactId = converter->LinkToIdentifier(*(aStoreEvent.iContactLink));
       
   243 	           
       
   244 	           // Remove the contact
       
   245 		       iObserver->RemoveData(*iUri, contactId);
       
   246 		    }
       
   247 		    
       
   248 		    delete converter;
       
   249 		    converter = NULL;
       
   250 		    
       
   251 	        if (( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactChanged ) ||
       
   252 	            ( aStoreEvent.iEventType == TVPbkContactStoreEvent::EGroupChanged ) )
       
   253 	        {
       
   254 	  		    // Add the contact
       
   255 	  		   iContactManager->RetrieveContactL( *(aStoreEvent.iContactLink),
       
   256 	  		                                                           *this );
       
   257 	        }
       
   258 	        	  		  
       
   259 			break;
       
   260 		}
       
   261 	}
       
   262 
       
   263 	PRINT ( _L("End CPcsContactStore::HandleStoreEventL") );
       
   264 }
       
   265 
       
   266 // ---------------------------------------------------------------------------
       
   267 //  Returns ths database URI
       
   268 // ---------------------------------------------------------------------------
       
   269 TDesC& CPcsContactStore::GetStoreUri()
       
   270 {
       
   271   return *iUri;
       
   272 }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 //  Callback Method. Called when one Retrieve operation is complete
       
   276 // --------------------------------------------------------------------------- 
       
   277 void CPcsContactStore::VPbkSingleContactOperationComplete(
       
   278         MVPbkContactOperationBase& aOperation, MVPbkStoreContact* aContact)
       
   279 {    
       
   280     iFetchedContactCount++;
       
   281 
       
   282 			       
       
   283 	// Handle the fetched contact....
       
   284 	TRAPD(err, HandleRetrievedContactL(aContact) );
       
   285 	if( err != KErrNone)
       
   286 	{
       
   287 		iObserver->UpdateCachingStatus(*iUri, err);
       
   288 	}
       
   289 	
       
   290 	MVPbkContactOperationBase* Opr = &aOperation;
       
   291 	if ( Opr )
       
   292 	{
       
   293 		delete Opr;
       
   294 		Opr = NULL;
       
   295 	}
       
   296 	
       
   297 	// Update the iNextState variable to proper state
       
   298 	if( iFetchedContactCount == iAllContactLinksCount )
       
   299 	{
       
   300 	    // Fetch complete
       
   301 	    // Update the caching status
       
   302 		iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
       
   303 		iNextState = EComplete;
       
   304 		IssueRequest();
       
   305 	}
       
   306 	else if ( (iFetchedContactCount % KLinksToFetchInOneGo) == 0 )
       
   307 	{
       
   308 	    // Fetch next block
       
   309 		iNextState = EFetchContactBlock;
       
   310 		IssueRequest();
       
   311 	}
       
   312 	
       
   313 }
       
   314     
       
   315 // ---------------------------------------------------------------------------
       
   316 //  Callback Method.Called when one Retrieve operation fails.
       
   317 // ---------------------------------------------------------------------------
       
   318 void CPcsContactStore::VPbkSingleContactOperationFailed(
       
   319         MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
       
   320 {
       
   321   	PRINT ( _L("Enter CPcsContactStore::VPbkSingleContactOperationFailed") );
       
   322 	iFetchedContactCount++;
       
   323 
       
   324 	// Update the iNextState variable to proper state
       
   325 	if( iFetchedContactCount == iAllContactLinksCount )
       
   326 	{
       
   327 		// Fetch complete
       
   328 		iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
       
   329 		iNextState = EComplete;
       
   330 		IssueRequest();
       
   331 	}
       
   332 	else if ( (iFetchedContactCount % KLinksToFetchInOneGo) == 0 ) 
       
   333 	{
       
   334 		// Fetch next block
       
   335 		iNextState = EFetchContactBlock;
       
   336 		IssueRequest();
       
   337 	}
       
   338 	
       
   339 	PRINT ( _L("End CPcsContactStore::VPbkSingleContactOperationFailed") );
       
   340 }
       
   341 
       
   342 // ---------------------------------------------------------------------------
       
   343 // Handles the operations for a single contact after it is fetched
       
   344 // ---------------------------------------------------------------------------
       
   345 void CPcsContactStore::HandleRetrievedContactL(MVPbkStoreContact* aContact)
       
   346 {    
       
   347     // Fill the contact link
       
   348 	MVPbkContactLink* tmpLink = aContact->CreateLinkLC();
       
   349 		
       
   350     // If the link is null, then it is not put on the cleanup stack,
       
   351     // so we need not pop in such a case
       
   352     if( NULL == tmpLink )
       
   353     {
       
   354         delete aContact;
       
   355         aContact = NULL;
       
   356     	return;
       
   357     }
       
   358    
       
   359     // Recover the URI
       
   360     HBufC* storeUri = HBufC::NewL(aContact->ParentStore().StoreProperties().Uri().UriDes().Length());
       
   361     storeUri->Des().Copy(aContact->ParentStore().StoreProperties().Uri().UriDes());
       
   362         			
       
   363 	CPsData *phoneContact = CPsData::NewL();
       
   364 
       
   365 	
       
   366 	// Fill the contact id
       
   367 	CVPbkContactIdConverter* converter = NULL;
       
   368 	TRAPD ( err, converter = CVPbkContactIdConverter::NewL( aContact->ParentStore() ) );
       
   369 	
       
   370 	if ( err == KErrNotSupported )
       
   371 	{
       
   372 		// simdb domain	
       
   373 		PRINT ( _L("SIM domain data received") );
       
   374 			
       
   375 		TInt tempIndex =  iSimContactItems->Find(*tmpLink);	
       
   376 		
       
   377 		if( KErrNotFound == tempIndex)
       
   378 
       
   379 		    {
       
   380 		    	tempIndex = iSimContactItems->Count();
       
   381 	        iSimContactItems->AppendL(tmpLink);
       
   382 	      }
       
   383 	    //Create a dummy sim index and set it
       
   384 	    TInt simIndex = CreateCacheIDfromSimArrayIndex(tempIndex);
       
   385 	    phoneContact->SetId(simIndex);
       
   386 	    
       
   387 	    // Set the contact link 
       
   388 	    HBufC8* extnInfo = tmpLink->PackLC();
       
   389 	    phoneContact->SetDataExtension(extnInfo);
       
   390 	    CleanupStack::Pop();//extnInfo		      
       
   391 	    CleanupStack::Pop(); // tmpLink
       
   392 	}
       
   393 	else 
       
   394 	{
       
   395 	    // cntdb domain
       
   396 		TInt32 contactId = converter->LinkToIdentifier(*tmpLink);
       
   397 		phoneContact->SetId(contactId);		
       
   398 		CleanupStack::PopAndDestroy(); // tmpLink
       
   399 	}
       
   400    	 
       
   401 	// Take the ownership
       
   402 	aContact->PushL();
       
   403 
       
   404 	MVPbkContactGroup* myContactGroup= aContact->Group();
       
   405 	
       
   406 	// The retrieved contact can be a contact item or a contact group, Handle accordingly
       
   407 	if ( NULL == myContactGroup )
       
   408 	{
       
   409 		// The fetched contact item (and not a contact group.)
       
   410 		GetDataForSingleContactL( *aContact, phoneContact );
       
   411 		//Add the data to the relevent cache through the observer
       
   412 		iObserver->AddData(*storeUri, phoneContact);
       
   413 	}
       
   414 	else
       
   415 	{  
       
   416 	    // Fetch the group name 
       
   417 	    HBufC* groupName = HBufC::NewL(myContactGroup->GroupLabel().Length());
       
   418 	    groupName->Des().Copy(myContactGroup->GroupLabel());
       
   419 	    TInt grpArrayIndex = -1; 
       
   420 	    for(TInt i =0; i  <iFieldsToCache.Count(); i++)
       
   421 	    {
       
   422 	    	if(iFieldsToCache[i] == R_VPBK_FIELD_TYPE_LASTNAME)
       
   423          
       
   424 			 {
       
   425 			 grpArrayIndex = i;
       
   426 			 	
       
   427 			 }
       
   428 			 phoneContact->SetDataL(i,KNullDesC);
       
   429 	    }
       
   430 	    if(grpArrayIndex != -1)
       
   431 	    {
       
   432 	    	phoneContact->SetDataL(grpArrayIndex,groupName->Des());
       
   433 	    	storeUri->Des().Copy(KVPbkDefaultGrpDbURI);	    
       
   434 	    
       
   435 	
       
   436 	    
       
   437 	    
       
   438         // Check for the contact in the group.
       
   439 	    MVPbkContactLinkArray* contactsContainedInGroup = myContactGroup->ItemsContainedLC();
       
   440         for(TInt i = 0; i < contactsContainedInGroup->Count(); i++)
       
   441 		{
       
   442 			TInt grpContactId = converter->LinkToIdentifier(contactsContainedInGroup->At(i));
       
   443 			phoneContact->AddIntDataExtL(grpContactId);
       
   444 		}
       
   445 		CleanupStack::PopAndDestroy(); // contactsContainedInGroup
       
   446  
       
   447  		
       
   448  		//Add the data to the relevent cache through the observer
       
   449 	    iObserver->AddData(*storeUri, phoneContact);
       
   450 	 	}
       
   451 	    else
       
   452 	    {
       
   453 	    	//We do not add anything here since Lastname does not exists in cenrep
       
   454 	    	delete 	phoneContact;
       
   455 	    	phoneContact = NULL;
       
   456 	    }
       
   457 	    delete groupName;
       
   458 	    groupName = NULL;
       
   459 	}
       
   460 	
       
   461 	delete converter;
       
   462 	converter = NULL;
       
   463 
       
   464 	delete storeUri;
       
   465     storeUri = NULL;
       
   466     
       
   467 	CleanupStack::PopAndDestroy(aContact); // aContact
       
   468 }
       
   469  
       
   470     
       
   471 // ---------------------------------------------------------------------------
       
   472 // Fetches the data from a particular contact 
       
   473 // --------------------------------------------------------------------------- 
       
   474 void CPcsContactStore::GetDataForSingleContactL( MVPbkBaseContact& aContact,
       
   475                                                  CPsData* aPhoneData )
       
   476 {      
       
   477 
       
   478     for(TInt i =0; i < iFieldsToCache.Count(); i++)
       
   479     {
       
   480 	    aPhoneData->SetDataL(i, KNullDesC);
       
   481 		AddContactFieldsL( aContact, iFieldsToCache[i], aPhoneData);			
       
   482     }
       
   483 	
       
   484 }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 // Add the data from contact fields
       
   488 // --------------------------------------------------------------------------- 
       
   489 void CPcsContactStore::AddContactFieldsL( MVPbkBaseContact& aContact,
       
   490                                           TInt afieldtype,
       
   491                                           CPsData *aPhoneData)
       
   492 {
       
   493 	const MVPbkFieldType*  myContactDataField = 
       
   494 		iContactManager->FieldTypes().Find( afieldtype );
       
   495 
       
   496 	CVPbkBaseContactFieldTypeIterator* itr = 
       
   497 		CVPbkBaseContactFieldTypeIterator::NewLC( *myContactDataField, 
       
   498 		aContact.Fields() );	
       
   499 			
       
   500 	// Iterate through each of the data fields
       
   501 	while ( itr->HasNext() )
       
   502 	{
       
   503 		const MVPbkBaseContactField* field = itr->Next();
       
   504 
       
   505 	    if ( ( field->FieldData()).DataType() == EVPbkFieldStorageTypeText )
       
   506 		{
       
   507 			const MVPbkContactFieldTextData& data = 
       
   508 				MVPbkContactFieldTextData::Cast( field->FieldData() );
       
   509 			
       
   510 			//If the field exist in iFieldsToCache, then set it
       
   511 			for( TInt i = 0 ; i< iFieldsToCache.Count(); i++)
       
   512 			{
       
   513 				if(afieldtype == iFieldsToCache[i])
       
   514 				{	
       
   515                     // Check if the field has any data entry. If so
       
   516                     // concatenate the next data to the existing one.
       
   517                     // A unit seperator is used to show that these are
       
   518                     // two entries.
       
   519                     HBufC* previousData = aPhoneData->Data(i);
       
   520                     if( (previousData != NULL) && (previousData->Des().Length()> 1) )
       
   521                     {
       
   522                         HBufC* newData = HBufC::NewLC(data.Text().Length() + previousData->Des().Length() + 5);
       
   523                         TPtr newDataPtr(newData->Des());
       
   524                         newDataPtr.Append(previousData->Des());
       
   525                         newDataPtr.Append(KSpaceCharacter);
       
   526                         newDataPtr.Append(KUnitSeparator);
       
   527                         newDataPtr.Append(KSpaceCharacter);
       
   528                         newDataPtr.Append(data.Text());
       
   529                         aPhoneData->SetDataL(i,*newData);
       
   530                         CleanupStack::PopAndDestroy(); // newData
       
   531                     }
       
   532                     else
       
   533                     {
       
   534                         aPhoneData->SetDataL(i,data.Text());
       
   535                     }
       
   536 				}			
       
   537 			}					
       
   538 		}
       
   539 	}
       
   540 	
       
   541 	CleanupStack::PopAndDestroy( itr ); 
       
   542 }
       
   543 
       
   544 // ---------------------------------------------------------------------------
       
   545 // Fetches the data from the vpbk using the contact links 
       
   546 // --------------------------------------------------------------------------- 
       
   547 void CPcsContactStore::FetchlinksL()
       
   548 {		
       
   549 
       
   550 	PRINT1 ( _L("CPcsContactStore::Total contacts downloaded = %d"),
       
   551 	          iFetchedContactCount );
       
   552 	          						
       
   553     TInt blockCount = iFetchedContactCount + KLinksToFetchInOneGo;
       
   554     
       
   555     if( blockCount >= iAllContactLinksCount)
       
   556     	blockCount = iAllContactLinksCount;
       
   557     
       
   558 	for(int cnt = iFetchedContactCount; cnt < blockCount; cnt++)
       
   559 	{	
       
   560 		// Retrieve the contact 
       
   561 		MVPbkContactLink* tempLink =iContactViewBase->CreateLinkLC(cnt);
       
   562 		iContactManager->RetrieveContactL( *tempLink, *this );
       
   563 		CleanupStack::PopAndDestroy();
       
   564 	}				
       
   565 
       
   566 }
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 // Implements the view ready function of MVPbkContactViewObserver
       
   570 // --------------------------------------------------------------------------- 
       
   571 void CPcsContactStore::ContactViewReady(
       
   572                 MVPbkContactViewBase& aView ) 
       
   573 {
       
   574     PRINT ( _L("Enter CPcsContactStore::ContactViewReady") );
       
   575     iFs.Close();
       
   576     aView.RemoveObserver(*this);
       
   577     // Get the total number of contacts for this view
       
   578     TRAPD(err,iAllContactLinksCount = aView.ContactCountL());
       
   579     
       
   580     if(err != KErrNone)
       
   581     {
       
   582     	PRINT( _L("CPcsContactStore::ContactViewReady - Unable to obtain contact count"));
       
   583     	iNextState = EComplete;
       
   584    		IssueRequest();
       
   585    		return;
       
   586     }
       
   587     
       
   588     PRINT1 ( _L("Total number of contacts for this view: %d"), iAllContactLinksCount);
       
   589     if( iAllContactLinksCount == 0)
       
   590     {
       
   591         // No Contactsb to cache, hence update the status accordingly
       
   592     	iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
       
   593     	iNextState = EComplete;
       
   594    		IssueRequest();
       
   595    		return;
       
   596     }
       
   597     iFetchedContactCount = 0;
       
   598     
       
   599     // Change the iNextState to fetch the contacts 
       
   600     if( iContactViewReady == EFalse)
       
   601     {
       
   602     	iObserver->UpdateCachingStatus(*iUri, ECachingInProgress);
       
   603     	iContactViewReady = ETrue;
       
   604     	iNextState = EFetchContactBlock;
       
   605    		IssueRequest();
       
   606     }
       
   607 	
       
   608 	PRINT ( _L("End CPcsContactStore::ContactViewReady") );
       
   609 }
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // Implements the view unavailable function of MVPbkContactViewObserver
       
   613 // --------------------------------------------------------------------------- 
       
   614 void CPcsContactStore::ContactViewUnavailable(
       
   615                 MVPbkContactViewBase& /*aView*/ )  
       
   616 {
       
   617     PRINT ( _L("Enter CPcsContactStore::ContactViewUnavailable") );
       
   618     // Update the caching status to complete
       
   619 	iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
       
   620     iFs.Close();
       
   621 	PRINT ( _L("End CPcsContactStore::ContactViewUnavailable") );
       
   622 }
       
   623 
       
   624 // ---------------------------------------------------------------------------
       
   625 // Implements the add contact function of MVPbkContactViewObserver
       
   626 // --------------------------------------------------------------------------- 
       
   627 void CPcsContactStore::ContactAddedToView(
       
   628             MVPbkContactViewBase& /*aView*/, 
       
   629             TInt /*aIndex*/, 
       
   630             const MVPbkContactLink& /*aContactLink*/ ) 
       
   631 {
       
   632 }
       
   633 
       
   634 // ---------------------------------------------------------------------------
       
   635 // Implements the remove contact function of MVPbkContactViewObserver
       
   636 // --------------------------------------------------------------------------- 
       
   637 void CPcsContactStore::ContactRemovedFromView(
       
   638                 MVPbkContactViewBase& /*aView*/, 
       
   639                 TInt /*aIndex*/, 
       
   640                 const MVPbkContactLink& /*aContactLink*/ )  
       
   641 {
       
   642 }
       
   643 
       
   644 // ---------------------------------------------------------------------------
       
   645 // Implements the view error function of MVPbkContactViewObserver
       
   646 // --------------------------------------------------------------------------- 
       
   647 void CPcsContactStore::ContactViewError(
       
   648             MVPbkContactViewBase& /*aView*/, 
       
   649             TInt /*aError*/, 
       
   650             TBool /*aErrorNotified*/ )  
       
   651 {
       
   652 }
       
   653 
       
   654 // ---------------------------------------------------------------------------
       
   655 // Creates the contact view to fetch data from this store
       
   656 // --------------------------------------------------------------------------- 
       
   657 void CPcsContactStore::CreateContactFetchViewL()
       
   658 {
       
   659 	PRINT ( _L("Enter CPcsContactStore::CreateContactFetchViewL") );
       
   660 	
       
   661 	// Create the view definition
       
   662     CVPbkContactViewDefinition* viewDef = CVPbkContactViewDefinition::NewL();
       
   663 	CleanupStack::PushL( viewDef );
       
   664 
       
   665   // Create the View Name for the view
       
   666   // The views are named as PCSView_<uri>		
       
   667 	HBufC* viewName = HBufC::NewL(KBufferMaxLen);
       
   668 	viewName->Des().Append(KPcsViewPrefix);
       
   669 	viewName->Des().Append(iUri->Des());
       
   670 	CleanupStack::PushL(viewName);
       
   671 
       
   672 	// Set the Uri
       
   673 	if ( iUri->Des().CompareC(KVPbkDefaultGrpDbURI) == 0)
       
   674 	{	    
       
   675 		// Special Handling required for Groups Data Store
       
   676 		// Read the resource file and create the sort order
       
   677 		// The sort order created is used in view creation.
       
   678 		
       
   679 		User::LeaveIfError( iFs.Connect() );
       
   680 		TPtrC driveLetter = TParsePtrC( RProcess().FileName() ).Drive();
       
   681 		TBuf<KMaxFileName> resourceFileName;
       
   682 		RResourceFile iResourceFile;
       
   683 		
       
   684 		//Read the path of the resource file
       
   685 		resourceFileName.Copy( driveLetter );
       
   686 		resourceFileName.Append( KDC_RESOURCE_FILES_DIR );
       
   687 		resourceFileName.Append( KResourceFileName );
       
   688 		
       
   689 		//Open the resource file
       
   690 	  	BaflUtils::NearestLanguageFile( iFs, resourceFileName );
       
   691 	    iResourceFile.OpenL( iFs, resourceFileName );
       
   692 	  	iResourceFile.ConfirmSignatureL(0);
       
   693 	
       
   694 
       
   695         //Read resource	             
       
   696         HBufC8* textbuffer = iResourceFile.AllocReadL(R_SORTORDER_LASTNAME);
       
   697         CleanupStack::PushL(textbuffer);
       
   698         
       
   699         // Set the resource information into the reader
       
   700         TResourceReader reader;
       
   701         reader.SetBuffer(textbuffer);
       
   702 	
       
   703 	    // Create sort order with only last name
       
   704 	    CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL( reader, 
       
   705 	                                                      iContactManager->FieldTypes() );
       
   706 
       
   707 	    CleanupStack::PushL(sortOrder);
       
   708 		
       
   709 		// Set the groups type
       
   710 		viewDef->SetUriL(KVPbkDefaultCntDbURI);
       
   711 		viewDef->SetType( EVPbkGroupsView );
       
   712 
       
   713 		// Set name for the view
       
   714 		viewDef->SetNameL( *viewName );	
       
   715 		
       
   716 		// Create the contact view
       
   717 		iContactViewBase = iContactManager->CreateContactViewLC( 
       
   718 		                         *this, 
       
   719 		                         *viewDef, 
       
   720 		                         *sortOrder);
       
   721 
       
   722         CleanupStack::Pop(); // iContactViewBase
       
   723         CleanupStack::PopAndDestroy(sortOrder);	
       
   724         CleanupStack::PopAndDestroy(textbuffer);
       
   725     
       
   726     	// Close the resouce File
       
   727         iResourceFile.Close();                        
       
   728 	
       
   729 	}
       
   730 	else
       
   731 	{
       
   732 	
       
   733 		// Create sort order with the fields from cenrep
       
   734 		CreateSortOrderL(iContactManager->FieldTypes());
       
   735 		
       
   736 		CVPbkSortOrder* sortOrderPhone = CVPbkSortOrder::NewL(*iSortOrder);
       
   737 	    CleanupStack::PushL(sortOrderPhone);
       
   738 	    
       
   739 		// set contacts type
       
   740 		viewDef->SetUriL(iUri->Des());
       
   741 		viewDef->SetType( EVPbkContactsView );
       
   742 			
       
   743 		// Set name for the view
       
   744 		viewDef->SetNameL( *viewName );	
       
   745 		__LATENCY_MARK ( _L("CPcsContactStore::CreateContactFetchViewL===== create view start") );
       
   746     	iContactViewBase = iContactManager->CreateContactViewLC( 
       
   747 		                         *this, 
       
   748 		                         *viewDef, 
       
   749 		                         *sortOrderPhone );
       
   750 		__LATENCY_MARKEND ( _L("CPcsContactStore::CreateContactFetchViewL ==== create view end") );	                         
       
   751         
       
   752         CleanupStack::Pop(); // iContactViewBase	
       
   753         CleanupStack::PopAndDestroy(sortOrderPhone);	
       
   754 	}		 
       
   755 		                             
       
   756     CleanupStack::PopAndDestroy( viewName );	
       
   757     CleanupStack::PopAndDestroy( viewDef );	
       
   758     
       
   759     PRINT ( _L("End CPcsContactStore::CreateContactFetchViewL") );
       
   760 }
       
   761 
       
   762 // ---------------------------------------------------------------------------------
       
   763 // Implements cancellation of an outstanding request.
       
   764 // ---------------------------------------------------------------------------------
       
   765 void CPcsContactStore::DoCancel() 
       
   766 {    
       
   767 }
       
   768 
       
   769 // ---------------------------------------------------------------------------------
       
   770 // The function is called by the active scheduler 
       
   771 // ---------------------------------------------------------------------------------
       
   772 void CPcsContactStore::RunL() 
       
   773 {
       
   774 	TRequestStatus timerStatus;
       
   775 	iTimer.Cancel();
       
   776 	
       
   777     switch( iNextState)
       
   778     {
       
   779 	   	case ECreateView :
       
   780 			CreateContactFetchViewL();
       
   781 		    break;
       
   782    					      	
       
   783 	   	case EFetchContactBlock:
       
   784 	   		PRINT ( _L("Issuing the fetch request for next block") );
       
   785 			FetchlinksL();
       
   786 			
       
   787 			// Delay the next fetch since contact fetch is CPU intensive,
       
   788 			// this will give other threads a chance to use CPU
       
   789 			iTimer.After( timerStatus, 100000); // 100 milliseconds
       
   790 			User::WaitForRequest( timerStatus );
       
   791 			break;
       
   792 	   						
       
   793 	   	case EComplete:
       
   794 		    PRINT ( _L("Contacts Caching FINISHED") );
       
   795 		    break;
       
   796     }
       
   797 }
       
   798 
       
   799 // ---------------------------------------------------------------------------------
       
   800 // Called in case of any errros 
       
   801 // ---------------------------------------------------------------------------------
       
   802 TInt CPcsContactStore::RunError(TInt /*aError*/) 
       
   803 {
       
   804 	 PRINT ( _L(" Enter CPcsContactStore:: CPcsContactStore::RunError()") );
       
   805 
       
   806 	 PRINT1 ( _L(" CPcsContactStore:: RunError().  Completing caching in contacts store %S with status ECachingCompleteWithErrors "), &(iUri->Des()));
       
   807    iObserver->UpdateCachingStatus(*iUri, ECachingCompleteWithErrors);
       
   808  	 PRINT ( _L(" End CPcsContactStore:: CPcsContactStore::RunError()") );
       
   809 	return KErrNone;
       
   810 }
       
   811 
       
   812 // ---------------------------------------------------------------------------------
       
   813 // Read the fields to cache from the central repository
       
   814 // ---------------------------------------------------------------------------------
       
   815 void CPcsContactStore::ReadFieldsToCacheFromCenrepL()
       
   816 {
       
   817 	CRepository *repository = CRepository::NewL( KCRUidPSContacts );
       
   818 
       
   819     // Read the data fields from cenrep
       
   820     for (TInt i(KCenrepFieldsStartKey); i < KCenrepFieldsStartKey + KCenrepNumberOfFieldsCount; i++ )
       
   821     {
       
   822 	TInt fieldToCache (-1);
       
   823 	    TInt err = repository->Get(i, fieldToCache );
       
   824 	    
       
   825 	    if ( KErrNone != err )
       
   826 	    {
       
   827 		    break;
       
   828 	    }
       
   829 	    if ( fieldToCache != 0 )
       
   830 	    {
       
   831 		    iFieldsToCache.Append(fieldToCache);
       
   832 	    }
       
   833 	    		
       
   834     }
       
   835     
       
   836     delete repository;
       
   837     
       
   838 }
       
   839 
       
   840 // ---------------------------------------------------------------------------------
       
   841 // Creates a dummy id for the cache
       
   842 // ---------------------------------------------------------------------------------
       
   843 
       
   844 TInt CPcsContactStore::CreateCacheIDfromSimArrayIndex(TInt aSimId)
       
   845 {
       
   846 	return (KSimStoreOffset + aSimId);
       
   847 }
       
   848 
       
   849 // ---------------------------------------------------------------------------------
       
   850 // Issues request to active object to call RunL method
       
   851 // ---------------------------------------------------------------------------------
       
   852 void CPcsContactStore::IssueRequest()
       
   853 {
       
   854 	TRequestStatus* status = &iStatus;
       
   855 	User::RequestComplete( status, KErrNone );
       
   856 	SetActive();
       
   857 }
       
   858 // Creates a sort order depending on the fields specified in the cenrep
       
   859 // when calling this function pass the masterList (i.e list containing all the
       
   860 // vpbk fields)
       
   861 // ---------------------------------------------------------------------------------
       
   862 void CPcsContactStore::CreateSortOrderL(const MVPbkFieldTypeList& aMasterList)
       
   863 {
       
   864 		
       
   865 	TInt count = aMasterList.FieldTypeCount();
       
   866 	
       
   867 	// loop through the master list and find the types that are supported
       
   868 	for(TInt i = 0; i < count; i++)
       
   869 	{
       
   870 		const MVPbkFieldType& fieldType = aMasterList.FieldTypeAt(i);
       
   871 		TInt resourceId = fieldType.FieldTypeResId();
       
   872 		// if the field type is supported
       
   873 		// then append MVPbkFieldType to sortOrder
       
   874 		for(TInt j =0; j < iFieldsToCache.Count(); j++)
       
   875 		{
       
   876 			if(iFieldsToCache[j] == resourceId)
       
   877 			{
       
   878 				iSortOrder->AppendL(fieldType);
       
   879 			}
       
   880 		}
       
   881 		
       
   882 		if(iSortOrder->FieldTypeCount() == iFieldsToCache.Count())
       
   883 		{
       
   884 			break;
       
   885 		}
       
   886 	}
       
   887 	
       
   888 }
       
   889 
       
   890 // End of file