--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/predictivesearch/adapters/contacts/src/cpcscontactstore.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,890 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Active object to read all the contacts from a
+* particular data store. Handles add/ modify/ delete of contacts.
+*
+*/
+
+// SYSTEM INCLUDES
+#include <barsread.h>
+#include <coemain.h>
+#include <utf.h>
+#include <e32std.h>
+#include <badesca.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <CVPbkContactFieldIterator.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <CVPbkContactLinkArray.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkContactStoreList.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactLink.h>
+#include <VPbkEng.rsg>
+#include <VPbkContactStoreUris.h>
+#include <CVPbkContactViewDefinition.h>
+#include <MVPbkContactViewBase.h>
+#include <VPbkContactView.hrh>
+#include <CVPbkContactIdConverter.h>
+#include <centralrepository.h>
+#include <MVPbkContactGroup.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <CVPbkContactLinkArray.h>
+#include <CVPbkSortOrder.h>
+#include <data_caging_path_literals.hrh>
+#include <bautils.h>
+
+// USER INCLUDES
+#include "cpcscontactstore.h"
+#include "CPsData.h"
+#include "CPcsDebug.h"
+#include "CPcsDefs.h"
+#include <contactsort.rsg>
+
+// CONSTANTS
+const TInt KSimStoreOffset = -5000;
+
+_LIT(KResourceFileName, "contactsort.rsc");
+_LIT(KPcsViewPrefix,"PCSView_");
+
+// FORWARD DECLARATION
+
+// ============================== MEMBER FUNCTIONS ================================
+
+// ---------------------------------------------------------------------------------
+// 2 phase construction
+// ---------------------------------------------------------------------------------
+CPcsContactStore* CPcsContactStore::NewL(CVPbkContactManager& aContactManager,
+ MDataStoreObserver& aObserver,
+ const TDesC& aUri)
+{
+ PRINT ( _L("Enter CPcsContactStore::NewL") );
+
+ CPcsContactStore* self = new ( ELeave ) CPcsContactStore( );
+ CleanupStack::PushL( self );
+
+ self->ConstructL(aContactManager,aObserver,aUri);
+ CleanupStack::Pop( self );
+
+ PRINT ( _L("End CPcsContactStore::NewL") );
+ return self;
+}
+
+// ---------------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------------
+CPcsContactStore::CPcsContactStore():
+ CActive( CActive::EPriorityLow),
+ iAllContactLinksCount(0),
+ iFetchedContactCount(0),
+ iContactViewReady(EFalse)
+{
+ PRINT ( _L("Enter CPcsContactStore::CPcsContactStore") );
+ CActiveScheduler::Add( this );
+ PRINT ( _L("End CPcsContactStore::CPcsContactStore") );
+}
+
+
+// ---------------------------------------------------------------------------------
+// CPcsContactStore::ConstructL()
+// 2nd phase constructor
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::ConstructL(CVPbkContactManager& aContactManager,
+ MDataStoreObserver& aObserver,
+ const TDesC& aUri)
+{
+ PRINT ( _L("Enter CPcsContactStore::ConstructL") );
+
+ iContactManager = &aContactManager;
+ iObserver = &aObserver;
+
+ iUri = HBufC::NewL(aUri.Length());
+ iUri->Des().Copy(aUri);
+
+ // create containers for holding the sim data
+ iSimContactItems = CVPbkContactLinkArray::NewL();
+
+
+ // for creating sort order
+ iSortOrder = CVPbkFieldTypeRefsList::NewL();
+
+ // Read the fields to cache from the central repository
+ ReadFieldsToCacheFromCenrepL();
+
+ // Local timer for block fetch delay
+ iTimer.CreateLocal();
+
+ // Initial state
+ iNextState = ECreateView;
+ IssueRequest();
+
+ PRINT ( _L("End CPcsContactStore::ConstructL") );
+}
+
+// ---------------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------------
+CPcsContactStore::~CPcsContactStore()
+{
+ PRINT ( _L("Enter CPcsContactStore::~CPcsContactStore") );
+
+ delete iContactViewBase;
+ iContactViewBase = NULL;
+
+ delete iSortOrder;
+ iSortOrder = NULL;
+
+ delete iSimContactItems;
+ iSimContactItems = NULL ;
+
+ delete iWait;
+ iWait = NULL;
+
+ delete iUri;
+ iUri = NULL;
+
+ iTimer.Cancel();
+ iTimer.Close();
+ iFieldsToCache.Close();
+
+ iFs.Close();
+
+ if(IsActive())
+ {
+ Deque();
+ }
+
+ PRINT ( _L("End CPcsContactStore::~CPcsContactStore") );
+}
+
+
+// ---------------------------------------------------------------------------------
+// Handles addition/deletion/modification of contacts
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::HandleStoreEventL(MVPbkContactStore& aContactStore,
+ TVPbkContactStoreEvent aStoreEvent)
+{
+ PRINT ( _L("Enter CPcsContactStore::HandleStoreEventL") );
+
+ switch (aStoreEvent.iEventType)
+ {
+ case TVPbkContactStoreEvent::EContactAdded:
+ {
+ PRINT ( _L("Add contact/group event received") );
+ iContactManager->RetrieveContactL( *(aStoreEvent.iContactLink),
+ *this);
+ break;
+ }
+
+ case TVPbkContactStoreEvent::EUnknownChanges:
+ {
+ iObserver->RemoveAll( *iUri );
+ iContactViewReady = EFalse;
+ iContactViewBase->AddObserverL(*this);
+ }
+ break;
+
+ case TVPbkContactStoreEvent::EContactDeleted:
+ case TVPbkContactStoreEvent::EContactChanged:
+ case TVPbkContactStoreEvent::EGroupDeleted:
+ case TVPbkContactStoreEvent::EGroupChanged:
+ {
+ if ( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactChanged )
+ {
+ PRINT ( _L("Change contact/group event received") );
+ }
+ else
+ {
+ PRINT ( _L("Delete contact/group event received") );
+ }
+
+ CVPbkContactIdConverter* converter = NULL;
+
+ TRAPD ( err, converter = CVPbkContactIdConverter::NewL( aContactStore ) );
+
+ TInt32 contactId(-1);
+
+ if ( err == KErrNotSupported )
+ {
+ // sim domain
+ // Pass the sim observer string in the next line
+ TInt contactLocation = iSimContactItems->Find(*aStoreEvent.iContactLink);
+ if( KErrNotFound != contactLocation)
+ {
+ // We are not removing from the array cache. If you try to fetch,
+ // then it will give an error
+ TInt index = CreateCacheIDfromSimArrayIndex (contactLocation);
+
+ iObserver->RemoveData(*iUri,index );
+ }
+
+ }
+ else
+ {
+ // cntdb domain
+ // Get contact id by mapping the link
+ contactId = converter->LinkToIdentifier(*(aStoreEvent.iContactLink));
+
+ // Remove the contact
+ iObserver->RemoveData(*iUri, contactId);
+ }
+
+ delete converter;
+ converter = NULL;
+
+ if (( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactChanged ) ||
+ ( aStoreEvent.iEventType == TVPbkContactStoreEvent::EGroupChanged ) )
+ {
+ // Add the contact
+ iContactManager->RetrieveContactL( *(aStoreEvent.iContactLink),
+ *this );
+ }
+
+ break;
+ }
+ }
+
+ PRINT ( _L("End CPcsContactStore::HandleStoreEventL") );
+}
+
+// ---------------------------------------------------------------------------
+// Returns ths database URI
+// ---------------------------------------------------------------------------
+TDesC& CPcsContactStore::GetStoreUri()
+{
+ return *iUri;
+}
+
+// ---------------------------------------------------------------------------
+// Callback Method. Called when one Retrieve operation is complete
+// ---------------------------------------------------------------------------
+void CPcsContactStore::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& aOperation, MVPbkStoreContact* aContact)
+{
+ iFetchedContactCount++;
+
+
+ // Handle the fetched contact....
+ TRAPD(err, HandleRetrievedContactL(aContact) );
+ if( err != KErrNone)
+ {
+ iObserver->UpdateCachingStatus(*iUri, err);
+ }
+
+ MVPbkContactOperationBase* Opr = &aOperation;
+ if ( Opr )
+ {
+ delete Opr;
+ Opr = NULL;
+ }
+
+ // Update the iNextState variable to proper state
+ if( iFetchedContactCount == iAllContactLinksCount )
+ {
+ // Fetch complete
+ // Update the caching status
+ iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
+ iNextState = EComplete;
+ IssueRequest();
+ }
+ else if ( (iFetchedContactCount % KLinksToFetchInOneGo) == 0 )
+ {
+ // Fetch next block
+ iNextState = EFetchContactBlock;
+ IssueRequest();
+ }
+
+}
+
+// ---------------------------------------------------------------------------
+// Callback Method.Called when one Retrieve operation fails.
+// ---------------------------------------------------------------------------
+void CPcsContactStore::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
+{
+ PRINT ( _L("Enter CPcsContactStore::VPbkSingleContactOperationFailed") );
+ iFetchedContactCount++;
+
+ // Update the iNextState variable to proper state
+ if( iFetchedContactCount == iAllContactLinksCount )
+ {
+ // Fetch complete
+ iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
+ iNextState = EComplete;
+ IssueRequest();
+ }
+ else if ( (iFetchedContactCount % KLinksToFetchInOneGo) == 0 )
+ {
+ // Fetch next block
+ iNextState = EFetchContactBlock;
+ IssueRequest();
+ }
+
+ PRINT ( _L("End CPcsContactStore::VPbkSingleContactOperationFailed") );
+}
+
+// ---------------------------------------------------------------------------
+// Handles the operations for a single contact after it is fetched
+// ---------------------------------------------------------------------------
+void CPcsContactStore::HandleRetrievedContactL(MVPbkStoreContact* aContact)
+{
+ // Fill the contact link
+ MVPbkContactLink* tmpLink = aContact->CreateLinkLC();
+
+ // If the link is null, then it is not put on the cleanup stack,
+ // so we need not pop in such a case
+ if( NULL == tmpLink )
+ {
+ delete aContact;
+ aContact = NULL;
+ return;
+ }
+
+ // Recover the URI
+ HBufC* storeUri = HBufC::NewL(aContact->ParentStore().StoreProperties().Uri().UriDes().Length());
+ storeUri->Des().Copy(aContact->ParentStore().StoreProperties().Uri().UriDes());
+
+ CPsData *phoneContact = CPsData::NewL();
+
+
+ // Fill the contact id
+ CVPbkContactIdConverter* converter = NULL;
+ TRAPD ( err, converter = CVPbkContactIdConverter::NewL( aContact->ParentStore() ) );
+
+ if ( err == KErrNotSupported )
+ {
+ // simdb domain
+ PRINT ( _L("SIM domain data received") );
+
+ TInt tempIndex = iSimContactItems->Find(*tmpLink);
+
+ if( KErrNotFound == tempIndex)
+
+ {
+ tempIndex = iSimContactItems->Count();
+ iSimContactItems->AppendL(tmpLink);
+ }
+ //Create a dummy sim index and set it
+ TInt simIndex = CreateCacheIDfromSimArrayIndex(tempIndex);
+ phoneContact->SetId(simIndex);
+
+ // Set the contact link
+ HBufC8* extnInfo = tmpLink->PackLC();
+ phoneContact->SetDataExtension(extnInfo);
+ CleanupStack::Pop();//extnInfo
+ CleanupStack::Pop(); // tmpLink
+ }
+ else
+ {
+ // cntdb domain
+ TInt32 contactId = converter->LinkToIdentifier(*tmpLink);
+ phoneContact->SetId(contactId);
+ CleanupStack::PopAndDestroy(); // tmpLink
+ }
+
+ // Take the ownership
+ aContact->PushL();
+
+ MVPbkContactGroup* myContactGroup= aContact->Group();
+
+ // The retrieved contact can be a contact item or a contact group, Handle accordingly
+ if ( NULL == myContactGroup )
+ {
+ // The fetched contact item (and not a contact group.)
+ GetDataForSingleContactL( *aContact, phoneContact );
+ //Add the data to the relevent cache through the observer
+ iObserver->AddData(*storeUri, phoneContact);
+ }
+ else
+ {
+ // Fetch the group name
+ HBufC* groupName = HBufC::NewL(myContactGroup->GroupLabel().Length());
+ groupName->Des().Copy(myContactGroup->GroupLabel());
+ TInt grpArrayIndex = -1;
+ for(TInt i =0; i <iFieldsToCache.Count(); i++)
+ {
+ if(iFieldsToCache[i] == R_VPBK_FIELD_TYPE_LASTNAME)
+
+ {
+ grpArrayIndex = i;
+
+ }
+ phoneContact->SetDataL(i,KNullDesC);
+ }
+ if(grpArrayIndex != -1)
+ {
+ phoneContact->SetDataL(grpArrayIndex,groupName->Des());
+ storeUri->Des().Copy(KVPbkDefaultGrpDbURI);
+
+
+
+
+ // Check for the contact in the group.
+ MVPbkContactLinkArray* contactsContainedInGroup = myContactGroup->ItemsContainedLC();
+ for(TInt i = 0; i < contactsContainedInGroup->Count(); i++)
+ {
+ TInt grpContactId = converter->LinkToIdentifier(contactsContainedInGroup->At(i));
+ phoneContact->AddIntDataExtL(grpContactId);
+ }
+ CleanupStack::PopAndDestroy(); // contactsContainedInGroup
+
+
+ //Add the data to the relevent cache through the observer
+ iObserver->AddData(*storeUri, phoneContact);
+ }
+ else
+ {
+ //We do not add anything here since Lastname does not exists in cenrep
+ delete phoneContact;
+ phoneContact = NULL;
+ }
+ delete groupName;
+ groupName = NULL;
+ }
+
+ delete converter;
+ converter = NULL;
+
+ delete storeUri;
+ storeUri = NULL;
+
+ CleanupStack::PopAndDestroy(aContact); // aContact
+}
+
+
+// ---------------------------------------------------------------------------
+// Fetches the data from a particular contact
+// ---------------------------------------------------------------------------
+void CPcsContactStore::GetDataForSingleContactL( MVPbkBaseContact& aContact,
+ CPsData* aPhoneData )
+{
+
+ for(TInt i =0; i < iFieldsToCache.Count(); i++)
+ {
+ aPhoneData->SetDataL(i, KNullDesC);
+ AddContactFieldsL( aContact, iFieldsToCache[i], aPhoneData);
+ }
+
+}
+
+// ---------------------------------------------------------------------------
+// Add the data from contact fields
+// ---------------------------------------------------------------------------
+void CPcsContactStore::AddContactFieldsL( MVPbkBaseContact& aContact,
+ TInt afieldtype,
+ CPsData *aPhoneData)
+{
+ const MVPbkFieldType* myContactDataField =
+ iContactManager->FieldTypes().Find( afieldtype );
+
+ CVPbkBaseContactFieldTypeIterator* itr =
+ CVPbkBaseContactFieldTypeIterator::NewLC( *myContactDataField,
+ aContact.Fields() );
+
+ // Iterate through each of the data fields
+ while ( itr->HasNext() )
+ {
+ const MVPbkBaseContactField* field = itr->Next();
+
+ if ( ( field->FieldData()).DataType() == EVPbkFieldStorageTypeText )
+ {
+ const MVPbkContactFieldTextData& data =
+ MVPbkContactFieldTextData::Cast( field->FieldData() );
+
+ //If the field exist in iFieldsToCache, then set it
+ for( TInt i = 0 ; i< iFieldsToCache.Count(); i++)
+ {
+ if(afieldtype == iFieldsToCache[i])
+ {
+ // Check if the field has any data entry. If so
+ // concatenate the next data to the existing one.
+ // A unit seperator is used to show that these are
+ // two entries.
+ HBufC* previousData = aPhoneData->Data(i);
+ if( (previousData != NULL) && (previousData->Des().Length()> 1) )
+ {
+ HBufC* newData = HBufC::NewLC(data.Text().Length() + previousData->Des().Length() + 5);
+ TPtr newDataPtr(newData->Des());
+ newDataPtr.Append(previousData->Des());
+ newDataPtr.Append(KSpaceCharacter);
+ newDataPtr.Append(KUnitSeparator);
+ newDataPtr.Append(KSpaceCharacter);
+ newDataPtr.Append(data.Text());
+ aPhoneData->SetDataL(i,*newData);
+ CleanupStack::PopAndDestroy(); // newData
+ }
+ else
+ {
+ aPhoneData->SetDataL(i,data.Text());
+ }
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( itr );
+}
+
+// ---------------------------------------------------------------------------
+// Fetches the data from the vpbk using the contact links
+// ---------------------------------------------------------------------------
+void CPcsContactStore::FetchlinksL()
+{
+
+ PRINT1 ( _L("CPcsContactStore::Total contacts downloaded = %d"),
+ iFetchedContactCount );
+
+ TInt blockCount = iFetchedContactCount + KLinksToFetchInOneGo;
+
+ if( blockCount >= iAllContactLinksCount)
+ blockCount = iAllContactLinksCount;
+
+ for(int cnt = iFetchedContactCount; cnt < blockCount; cnt++)
+ {
+ // Retrieve the contact
+ MVPbkContactLink* tempLink =iContactViewBase->CreateLinkLC(cnt);
+ iContactManager->RetrieveContactL( *tempLink, *this );
+ CleanupStack::PopAndDestroy();
+ }
+
+}
+
+// ---------------------------------------------------------------------------
+// Implements the view ready function of MVPbkContactViewObserver
+// ---------------------------------------------------------------------------
+void CPcsContactStore::ContactViewReady(
+ MVPbkContactViewBase& aView )
+{
+ PRINT ( _L("Enter CPcsContactStore::ContactViewReady") );
+ iFs.Close();
+ aView.RemoveObserver(*this);
+ // Get the total number of contacts for this view
+ TRAPD(err,iAllContactLinksCount = aView.ContactCountL());
+
+ if(err != KErrNone)
+ {
+ PRINT( _L("CPcsContactStore::ContactViewReady - Unable to obtain contact count"));
+ iNextState = EComplete;
+ IssueRequest();
+ return;
+ }
+
+ PRINT1 ( _L("Total number of contacts for this view: %d"), iAllContactLinksCount);
+ if( iAllContactLinksCount == 0)
+ {
+ // No Contactsb to cache, hence update the status accordingly
+ iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
+ iNextState = EComplete;
+ IssueRequest();
+ return;
+ }
+ iFetchedContactCount = 0;
+
+ // Change the iNextState to fetch the contacts
+ if( iContactViewReady == EFalse)
+ {
+ iObserver->UpdateCachingStatus(*iUri, ECachingInProgress);
+ iContactViewReady = ETrue;
+ iNextState = EFetchContactBlock;
+ IssueRequest();
+ }
+
+ PRINT ( _L("End CPcsContactStore::ContactViewReady") );
+}
+
+// ---------------------------------------------------------------------------
+// Implements the view unavailable function of MVPbkContactViewObserver
+// ---------------------------------------------------------------------------
+void CPcsContactStore::ContactViewUnavailable(
+ MVPbkContactViewBase& /*aView*/ )
+{
+ PRINT ( _L("Enter CPcsContactStore::ContactViewUnavailable") );
+ // Update the caching status to complete
+ iObserver->UpdateCachingStatus(*iUri, ECachingComplete);
+ iFs.Close();
+ PRINT ( _L("End CPcsContactStore::ContactViewUnavailable") );
+}
+
+// ---------------------------------------------------------------------------
+// Implements the add contact function of MVPbkContactViewObserver
+// ---------------------------------------------------------------------------
+void CPcsContactStore::ContactAddedToView(
+ MVPbkContactViewBase& /*aView*/,
+ TInt /*aIndex*/,
+ const MVPbkContactLink& /*aContactLink*/ )
+{
+}
+
+// ---------------------------------------------------------------------------
+// Implements the remove contact function of MVPbkContactViewObserver
+// ---------------------------------------------------------------------------
+void CPcsContactStore::ContactRemovedFromView(
+ MVPbkContactViewBase& /*aView*/,
+ TInt /*aIndex*/,
+ const MVPbkContactLink& /*aContactLink*/ )
+{
+}
+
+// ---------------------------------------------------------------------------
+// Implements the view error function of MVPbkContactViewObserver
+// ---------------------------------------------------------------------------
+void CPcsContactStore::ContactViewError(
+ MVPbkContactViewBase& /*aView*/,
+ TInt /*aError*/,
+ TBool /*aErrorNotified*/ )
+{
+}
+
+// ---------------------------------------------------------------------------
+// Creates the contact view to fetch data from this store
+// ---------------------------------------------------------------------------
+void CPcsContactStore::CreateContactFetchViewL()
+{
+ PRINT ( _L("Enter CPcsContactStore::CreateContactFetchViewL") );
+
+ // Create the view definition
+ CVPbkContactViewDefinition* viewDef = CVPbkContactViewDefinition::NewL();
+ CleanupStack::PushL( viewDef );
+
+ // Create the View Name for the view
+ // The views are named as PCSView_<uri>
+ HBufC* viewName = HBufC::NewL(KBufferMaxLen);
+ viewName->Des().Append(KPcsViewPrefix);
+ viewName->Des().Append(iUri->Des());
+ CleanupStack::PushL(viewName);
+
+ // Set the Uri
+ if ( iUri->Des().CompareC(KVPbkDefaultGrpDbURI) == 0)
+ {
+ // Special Handling required for Groups Data Store
+ // Read the resource file and create the sort order
+ // The sort order created is used in view creation.
+
+ User::LeaveIfError( iFs.Connect() );
+ TPtrC driveLetter = TParsePtrC( RProcess().FileName() ).Drive();
+ TBuf<KMaxFileName> resourceFileName;
+ RResourceFile iResourceFile;
+
+ //Read the path of the resource file
+ resourceFileName.Copy( driveLetter );
+ resourceFileName.Append( KDC_RESOURCE_FILES_DIR );
+ resourceFileName.Append( KResourceFileName );
+
+ //Open the resource file
+ BaflUtils::NearestLanguageFile( iFs, resourceFileName );
+ iResourceFile.OpenL( iFs, resourceFileName );
+ iResourceFile.ConfirmSignatureL(0);
+
+
+ //Read resource
+ HBufC8* textbuffer = iResourceFile.AllocReadL(R_SORTORDER_LASTNAME);
+ CleanupStack::PushL(textbuffer);
+
+ // Set the resource information into the reader
+ TResourceReader reader;
+ reader.SetBuffer(textbuffer);
+
+ // Create sort order with only last name
+ CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL( reader,
+ iContactManager->FieldTypes() );
+
+ CleanupStack::PushL(sortOrder);
+
+ // Set the groups type
+ viewDef->SetUriL(KVPbkDefaultCntDbURI);
+ viewDef->SetType( EVPbkGroupsView );
+
+ // Set name for the view
+ viewDef->SetNameL( *viewName );
+
+ // Create the contact view
+ iContactViewBase = iContactManager->CreateContactViewLC(
+ *this,
+ *viewDef,
+ *sortOrder);
+
+ CleanupStack::Pop(); // iContactViewBase
+ CleanupStack::PopAndDestroy(sortOrder);
+ CleanupStack::PopAndDestroy(textbuffer);
+
+ // Close the resouce File
+ iResourceFile.Close();
+
+ }
+ else
+ {
+
+ // Create sort order with the fields from cenrep
+ CreateSortOrderL(iContactManager->FieldTypes());
+
+ CVPbkSortOrder* sortOrderPhone = CVPbkSortOrder::NewL(*iSortOrder);
+ CleanupStack::PushL(sortOrderPhone);
+
+ // set contacts type
+ viewDef->SetUriL(iUri->Des());
+ viewDef->SetType( EVPbkContactsView );
+
+ // Set name for the view
+ viewDef->SetNameL( *viewName );
+ __LATENCY_MARK ( _L("CPcsContactStore::CreateContactFetchViewL===== create view start") );
+ iContactViewBase = iContactManager->CreateContactViewLC(
+ *this,
+ *viewDef,
+ *sortOrderPhone );
+ __LATENCY_MARKEND ( _L("CPcsContactStore::CreateContactFetchViewL ==== create view end") );
+
+ CleanupStack::Pop(); // iContactViewBase
+ CleanupStack::PopAndDestroy(sortOrderPhone);
+ }
+
+ CleanupStack::PopAndDestroy( viewName );
+ CleanupStack::PopAndDestroy( viewDef );
+
+ PRINT ( _L("End CPcsContactStore::CreateContactFetchViewL") );
+}
+
+// ---------------------------------------------------------------------------------
+// Implements cancellation of an outstanding request.
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::DoCancel()
+{
+}
+
+// ---------------------------------------------------------------------------------
+// The function is called by the active scheduler
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::RunL()
+{
+ TRequestStatus timerStatus;
+ iTimer.Cancel();
+
+ switch( iNextState)
+ {
+ case ECreateView :
+ CreateContactFetchViewL();
+ break;
+
+ case EFetchContactBlock:
+ PRINT ( _L("Issuing the fetch request for next block") );
+ FetchlinksL();
+
+ // Delay the next fetch since contact fetch is CPU intensive,
+ // this will give other threads a chance to use CPU
+ iTimer.After( timerStatus, 100000); // 100 milliseconds
+ User::WaitForRequest( timerStatus );
+ break;
+
+ case EComplete:
+ PRINT ( _L("Contacts Caching FINISHED") );
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------------
+// Called in case of any errros
+// ---------------------------------------------------------------------------------
+TInt CPcsContactStore::RunError(TInt /*aError*/)
+{
+ PRINT ( _L(" Enter CPcsContactStore:: CPcsContactStore::RunError()") );
+
+ PRINT1 ( _L(" CPcsContactStore:: RunError(). Completing caching in contacts store %S with status ECachingCompleteWithErrors "), &(iUri->Des()));
+ iObserver->UpdateCachingStatus(*iUri, ECachingCompleteWithErrors);
+ PRINT ( _L(" End CPcsContactStore:: CPcsContactStore::RunError()") );
+ return KErrNone;
+}
+
+// ---------------------------------------------------------------------------------
+// Read the fields to cache from the central repository
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::ReadFieldsToCacheFromCenrepL()
+{
+ CRepository *repository = CRepository::NewL( KCRUidPSContacts );
+
+ // Read the data fields from cenrep
+ for (TInt i(KCenrepFieldsStartKey); i < KCenrepFieldsStartKey + KCenrepNumberOfFieldsCount; i++ )
+ {
+ TInt fieldToCache (-1);
+ TInt err = repository->Get(i, fieldToCache );
+
+ if ( KErrNone != err )
+ {
+ break;
+ }
+ if ( fieldToCache != 0 )
+ {
+ iFieldsToCache.Append(fieldToCache);
+ }
+
+ }
+
+ delete repository;
+
+}
+
+// ---------------------------------------------------------------------------------
+// Creates a dummy id for the cache
+// ---------------------------------------------------------------------------------
+
+TInt CPcsContactStore::CreateCacheIDfromSimArrayIndex(TInt aSimId)
+{
+ return (KSimStoreOffset + aSimId);
+}
+
+// ---------------------------------------------------------------------------------
+// Issues request to active object to call RunL method
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::IssueRequest()
+{
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+}
+// Creates a sort order depending on the fields specified in the cenrep
+// when calling this function pass the masterList (i.e list containing all the
+// vpbk fields)
+// ---------------------------------------------------------------------------------
+void CPcsContactStore::CreateSortOrderL(const MVPbkFieldTypeList& aMasterList)
+{
+
+ TInt count = aMasterList.FieldTypeCount();
+
+ // loop through the master list and find the types that are supported
+ for(TInt i = 0; i < count; i++)
+ {
+ const MVPbkFieldType& fieldType = aMasterList.FieldTypeAt(i);
+ TInt resourceId = fieldType.FieldTypeResId();
+ // if the field type is supported
+ // then append MVPbkFieldType to sortOrder
+ for(TInt j =0; j < iFieldsToCache.Count(); j++)
+ {
+ if(iFieldsToCache[j] == resourceId)
+ {
+ iSortOrder->AppendL(fieldType);
+ }
+ }
+
+ if(iSortOrder->FieldTypeCount() == iFieldsToCache.Count())
+ {
+ break;
+ }
+ }
+
+}
+
+// End of file