--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/searchfw/plugins/contactsplugin/src/contactssearcher.cpp Wed Sep 01 12:32:31 2010 +0100
@@ -0,0 +1,1293 @@
+/*
+* Copyright (c) 2006-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: Plugin for contactsplugin information search.
+*
+*/
+
+
+//SYSTEM INCLUDES
+#include <utf.h>
+#include <e32std.h>
+#include <searchcondition.h>
+#include <searchtextsearcher.h>
+#include <searchdocumentid.h>
+#include <searchlightresult.h>
+#include <searchresult.h>
+#include <searchcommon.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 <MVPbkContactFieldDateTimeData.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactLink.h>
+#include <VPbkEng.rsg>
+#include <VPbkContactStoreUris.h>
+#include <TVPbkWordParserCallbackParam.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <searchpluginobserver.h>
+
+#include <MVPbkContactViewBase.h>
+#include <MVPbkContactStoreInfo.h>
+#include <CVPbkContactViewDefinition.h>
+#include <CVPbkSortOrder.h>
+#include <MVPbkContactViewFiltering.h>
+#include <CPbk2SortOrderManager.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <contactssearchresource.rsg>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+//USER INCLUDES
+#include "contactssearcher.h"
+#include "contactssearchplugindefines.h"
+#include <featmgr.h>
+//FORWARD DECLARATION
+TInt VPbkParseDataL( TAny* aParam );
+
+
+// ---------------------------------------------------------------------------------
+// 1st phase constructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher* CContactsSearcher::NewL( const RArray<TUid>& aContentIdArray,
+ const CSearchCondition& aCondition,
+ const TUid& aPluginId,
+ MSearchPluginObserver& aObserver )
+ {
+ CContactsSearcher* self = new ( ELeave ) CContactsSearcher( aPluginId );
+ CleanupStack::PushL( self );
+ self->ConstructL( aContentIdArray, aCondition,aObserver );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher::~CContactsSearcher()
+ {
+ delete iFilterView;
+ delete iContactViewBase;
+
+ ifSession.Close();
+ if( iCurrentlyOpenStores)
+ {
+ // Close all the stores opened
+ if(iContactManager)
+ {
+ TRAP_IGNORE(iContactManager->ContactStoresL().CloseAll( *this ));
+ }
+ if(iCurrentlyOpenStores)
+ {
+ const TInt count = iCurrentlyOpenStores->Count();
+ for ( TInt i = count - 1; i >= 0; --i )
+ {
+ iCurrentlyOpenStores->Remove( (*iCurrentlyOpenStores)[i] );
+ }
+ delete iCurrentlyOpenStores;
+ iCurrentlyOpenStores = NULL;
+
+ }
+ }
+ if ( iContactManager )
+ {
+ delete iContactManager;
+ iContactManager = NULL;
+ }
+
+ if ( iTextSearcher )
+ {
+ delete iTextSearcher;
+ iTextSearcher = NULL;
+ }
+
+
+
+
+ if(iAllContactItemsFromDb)
+ {
+ iAllContactItemsFromDb->ResetAndDestroy();
+ delete iAllContactItemsFromDb;
+ iAllContactItemsFromDb = NULL;
+ }
+ iContactArrayMapper.Reset();
+ iCotnactDeletedList.Reset();
+ iHeavyResultsArray.ResetAndDestroy();
+
+ FeatureManager::UnInitializeLib();
+
+}
+
+
+// ---------------------------------------------------------------------------
+// A function that returns the contact link at given index of the iContactLinkArray
+// ---------------------------------------------------------------------------
+//
+//
+MVPbkContactLink* CContactsSearcher::GetContactLinkAtIndexLC(TInt aIndex)
+ {
+ if(aIndex < iContactArrayMapper.Count() && (EFalse == iCotnactDeletedList[aIndex] ))
+ {
+ if ( iAllContactItemsFromDb )
+ {
+ return iAllContactItemsFromDb->At(iContactArrayMapper[aIndex]).CloneLC();
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+return NULL;
+}
+
+// ---------------------------------------------------------------------------------
+// Releases the resources
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::Destroy()
+ {
+ if( IsActive() )
+ {
+ CActive::Cancel();
+ }
+ else
+ {
+ CleanUp();
+ }
+ delete this;
+}
+
+// ---------------------------------------------------------------------------------
+// Starts the search
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::SearchL()
+ {
+ iSearchCancelled = EFalse;
+
+
+ iHeavyResultsArray.ResetAndDestroy();
+ // iContactLinkIndexArray.Reset();
+
+ if(iAllContactItemsFromDb)
+ {
+
+ iAllContactItemsFromDb->ResetAndDestroy();
+ }
+ iContactManager->ContactStoresL().OpenAllL( *this );
+
+ }
+
+// ---------------------------------------------------------------------------------
+// Returns true,f search is in progress
+// ---------------------------------------------------------------------------------
+//
+TBool CContactsSearcher::IsSearching()
+ {
+ return IsActive();
+ }
+
+// ---------------------------------------------------------------------------------
+// Cancels the search
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CancelSearch()
+ {
+ iSearchCancelled = ETrue;
+ CActive::Cancel();
+
+ }
+
+// ---------------------------------------------------------------------------------
+// Gets the results
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::GetResultsL(
+ const RPointerArray<CSearchDocumentId>& aDocumentIdArray )
+ {
+
+ //Check the aDocumentIdArray
+ // For all the matching documentIds, fetch the corresponding
+ // Heavy Result from iHeavyResultsArray and append it to heavyResultResponse
+
+ RPointerArray<CSearchResult> heavyResultResponse;
+ //Search through the aDocumentIdArray, and select those heavy results
+ // which belong to this plugin with the corresponding document id
+ for( TInt j = 0; j < aDocumentIdArray.Count(); j++ )
+ {
+ TUid pluginId;
+ pluginId.iUid = aDocumentIdArray[j]->PluginId().iUid;
+ if ( ( pluginId.iUid == iPluginId.iUid ) &&
+ (aDocumentIdArray[j]->RepositoryId() == KSearchCClassContactsUid.iUid)
+ )
+ {
+
+ TInt myArrayIndex =aDocumentIdArray[j]->DocumentId() ;
+
+ heavyResultResponse.AppendL(iHeavyResultsArray[myArrayIndex]);
+
+ }
+ }
+
+ iObserver->ResultsRetrieveCompleteL( heavyResultResponse );
+ heavyResultResponse.Reset();
+ }
+
+// ---------------------------------------------------------------------------------
+// Cancels the result retrieval
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CancelResultsRetrieve()
+ {
+
+ }
+
+
+//---------------------------------------------------------------------------------
+// Returns the search progress
+//---------------------------------------------------------------------------------
+//
+void CContactsSearcher::GetSearchProgressL( TUid& /*aContentClassId*/, TInt& /*aCurrentDocument*/, TInt& /*aTotalDocuments*/ )
+ {
+
+ }
+
+
+
+// ---------------------------------------------------------------------------------
+// Called when a result is found matching the search criteria
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::HitL( TInt /*aResult*/ )
+ {
+ // If search is still in progress, then process the search result
+ if( !iSearchCancelled )
+ {
+ CSearchDocumentId* searchDocId = NULL;
+
+ TBuf8<KBufferLength> tempDes;
+
+
+ // Set the repository id
+ searchDocId = CSearchDocumentId::NewL( iTotalHits,iPluginId );
+ searchDocId->SetRepositoryIdL( KSearchCClassContactsUid.iUid );
+ CSearchLightResult* searchLightResult = CSearchLightResult::NewL( searchDocId );
+ CleanupStack::PushL(searchLightResult);
+ searchLightResult->SetContentClassId( KSearchCClassContactsUid );
+ searchLightResult->SetServiceId( KNullUid );
+
+ //HBufC8 *repositoryId = HBufC8::NewL( KBufferLength ) ;
+ //repositoryId->Des().Append(KSpace);
+ searchDocId->SetRepositoryIdL( KSearchCClassContactsUid.iUid );
+ //delete repositoryId;
+ //repositoryId = NULL;
+
+ iContactArrayMapper.Append(iCurrentDatatBaseItemIndex - 1);
+
+ // Form the heavy result and append it to the iHeavyResultsArray
+ CSearchResult* tmpHeavyRes = NULL;
+ tmpHeavyRes = CSearchResult::NewL(searchLightResult);
+ CleanupStack::PushL(tmpHeavyRes);
+ //Set the Title for the heavy result
+ if ( iCurrentTitle )
+ {
+ tmpHeavyRes->SetTitleL( *iCurrentTitle );
+ delete iCurrentTitle; iCurrentTitle = NULL;
+ }
+
+ //Set the snippet for the heavy result
+ if ( iCurrentSnippet )
+ {
+ tmpHeavyRes->SetSnippetL(*iCurrentSnippet);
+ delete iCurrentSnippet;iCurrentSnippet = NULL;
+ }
+
+ // Check if the contact is a phone contact or a sim contact
+ // Accordingly set the folder id
+
+ TInt tempIndex = iContactArrayMapper[iTotalHits];
+ TVPbkContactStoreUriPtr uri = iAllContactItemsFromDb->At(tempIndex).ContactStore().StoreProperties().Uri();
+ TVPbkContactStoreUriPtr phoneMemoryUri( VPbkContactStoreUris::DefaultCntDbUri() );
+
+ if ( uri.Compare( phoneMemoryUri,TVPbkContactStoreUriPtr::EContactStoreUriStoreType) == 0 )
+ {
+ searchLightResult->SetContentFolderId( KSearchCFolderPhoneUid );
+ }
+ else
+ {
+
+ searchLightResult->SetContentFolderId( KSearchCFolderSIMUid );
+ }
+ //Set the SetSnippetFormatL
+ HBufC8 *snippetFormat = HBufC8::NewL( KBufferLength ) ;
+ snippetFormat->Des().Append(KSpace);
+ tmpHeavyRes->SetSnippetFormatL( snippetFormat->Des() );
+ delete snippetFormat;
+ snippetFormat = NULL;
+
+ //Append the heavy result to the iHeavyResultsArray
+ iHeavyResultsArray.AppendL(tmpHeavyRes);
+
+ // Increment the iTotalHits and call ResultFoundL()
+ iTotalHits++;
+ iObserver->ResultFoundL( searchLightResult, iTotalHits, iTotalNumOfContactsSearched );
+
+
+ CleanupStack::Pop(tmpHeavyRes);
+ CleanupStack::Pop(searchLightResult);
+
+
+ }
+
+}
+
+HBufC8* CContactsSearcher::LaunchInfoL( const CSearchDocumentId& aDocumentID )
+{
+ if((aDocumentID.PluginId() == iPluginId) &&
+ (aDocumentID.RepositoryId() == KSearchCClassContactsUid.iUid))
+ {
+ //HBufC *temp = HBufC::NewL(KMaxFileName) ;
+ //TPtr docIdPtr = temp->Des();
+
+ TInt myArrayIndex = aDocumentID.DocumentId();
+ //CnvUtfConverter::ConvertToUnicodeFromUtf8( docIdPtr,aDocumentID.DocumentId() );
+ //TLex16 myDocId(docIdPtr);
+ if(myArrayIndex < iContactArrayMapper.Count() && (EFalse == iCotnactDeletedList[myArrayIndex] ))
+ {
+ if ( iAllContactItemsFromDb )
+ {
+ MVPbkContactLink* launchContact = iAllContactItemsFromDb->At(iContactArrayMapper[myArrayIndex]).CloneLC();
+
+ HBufC8 *launchInfo = launchContact->PackLC();
+ CleanupStack::Pop();
+ CleanupStack::Pop();
+ delete launchContact;
+ launchContact= NULL;
+ return launchInfo;
+ }
+ }
+
+ else
+ {
+ return NULL;
+ }
+
+ }
+
+ return NULL;
+
+
+}
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreListObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::OpenComplete()
+ {
+ // If atleast one store is ready,
+ // set iStoreReadyForAccessing = ETrue so that we can start the serach
+ // else
+ // Finish the search as no stores are available
+ if(iAtLeastOneStoreReady)
+ {
+ iStoreReadyForAccessing = ETrue;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+
+ }
+ else
+ {
+ //No stores available, so set the appropriate flag
+ iNoContactStoreAvailable = ETrue;
+ }
+
+
+ }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::StoreReady(MVPbkContactStore& aStore)
+ {
+ // This function is called every time a store is ready to be
+ // accessed.
+ const TDesC& uri = aStore.StoreProperties().Uri().UriDes();
+ if ( !iCurrentlyOpenStores->IsIncluded( uri ) )
+ {
+ TRAP_IGNORE(iCurrentlyOpenStores->AppendL( uri ));
+ }
+ // We know that atleast one store is ready, so we can set this flag to ETrue
+ iAtLeastOneStoreReady = ETrue;
+
+
+ }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::StoreUnavailable(
+ MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/)
+ {
+ //The store is not availble..so do notthing....
+ //TRequestStatus* status = &iStatus;
+ //User::RequestComplete( status, KErrNone );
+ //SetActive();
+ }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactStoreObserver.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::HandleStoreEventL(MVPbkContactStore& aContactStore,
+ TVPbkContactStoreEvent aStoreEvent)
+ {
+
+ //if there is deletetion of contact, then we need to update
+ MVPbkContactStore* storeInList = iContactManager->ContactStoresL().Find(aContactStore.StoreProperties().Uri());
+ TInt contactLocation = 0;
+ if (storeInList !=NULL)
+ {
+ switch(aStoreEvent.iEventType)
+ {
+ case TVPbkContactStoreEvent::EContactDeleted:
+ contactLocation = iAllContactItemsFromDb->Find(*aStoreEvent.iContactLink);
+ if( KErrNotFound != contactLocation)
+ {
+ TInt tempLoc = iContactArrayMapper.Find(contactLocation);
+ if( KErrNotFound != tempLoc)
+ {
+ iCotnactDeletedList[tempLoc] = ETrue;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ // Dont't show store events
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+
+// ---------------------------------------------------------------------------
+// Callback Method.Called when one Retrieve operation is complete
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& /*aOperation*/, MVPbkStoreContact* aContact)
+ {
+
+ delete iVPbkOperation;
+ iVPbkOperation = NULL;
+
+ // Delete the retrieved link
+ //iAllContactItemsFromDb->Delete( iCurrentDatatBaseItemIndex );
+
+ // Handle the fetched contact....
+ TRAPD( res, HandleRetrievedContactL( aContact ) );
+ if ( res != KErrNone )
+ {
+
+ }
+
+ if(iAllContactsSearched)
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// Callback Method.Called when one Retrieve operation fails.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
+ {
+ //delete the operation, since its completed
+ delete iVPbkOperation;
+ iVPbkOperation = NULL;
+
+ }
+
+
+
+// ---------------------------------------------------------------------------------
+// Implements cancellation of an outstanding request.
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::DoCancel()
+ {
+
+ }
+
+
+// ---------------------------------------------------------------------------------
+// The function is called by the active scheduler
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::RunL()
+ {
+
+ if( !DoActualSearchL() )
+ {
+ ReportFinishedL();
+
+ }
+
+ }
+
+// ---------------------------------------------------------------------------------
+// Called in case of any errros
+// ---------------------------------------------------------------------------------
+//
+TInt CContactsSearcher::RunError(TInt /*aError*/)
+ {
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------------
+// CContactsSearcher::CContactsSearcher()
+// Constructor
+// ---------------------------------------------------------------------------------
+//
+CContactsSearcher::CContactsSearcher( const TUid& aPluginId ) :
+ CActive( CActive::EPriorityStandard ),
+ iPluginId( aPluginId ),
+ iTotalNumOfContactsSearched(0),
+ iTotalHits(0),
+ iStoreReadyForAccessing(EFalse),
+ iAtLeastOneStoreReady(EFalse),
+ iAllContactsSearched (EFalse),
+ iNoContactStoreAvailable (EFalse),
+ iSearchStarted (EFalse),
+ iSearchCancelled(EFalse)
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------------
+// CContactsSearcher::ConstructL()
+// 2nd phase constructor
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::ConstructL( const RArray<TUid>& /*aContentIdArray*/,
+ const CSearchCondition& aCondition,
+ MSearchPluginObserver& aObserver )
+ {
+
+ iObserver = &aObserver;
+ User::LeaveIfError( ifSession.Connect() );
+
+ // initialize virtual phonebook with phonebook and sim contact uris.
+ CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC();
+ uriArray->AppendL( TVPbkContactStoreUriPtr(VPbkContactStoreUris::DefaultCntDbUri()));
+ uriArray->AppendL( TVPbkContactStoreUriPtr( VPbkContactStoreUris::SimGlobalAdnUri() ) );
+
+
+ iContactManager = CVPbkContactManager::NewL(*uriArray);
+ CleanupStack::PopAndDestroy(uriArray);
+
+ // Create the container for currently open stores
+ iCurrentlyOpenStores = CVPbkContactStoreUriArray::NewL();
+
+ // create containers for holding the contacts data
+ iAllContactItemsFromDb = CVPbkContactLinkArray::NewL();
+
+
+ //Create the text searcher
+ SetPriority( EPriorityStandard );
+ iTextSearcher = CSearchTextSearcher::NewL( *this );
+ iTextSearcher->SetParametersL( aCondition );
+
+ iIsFilterView = EFalse;
+ FeatureManager::InitializeLibL();
+ }
+
+// ---------------------------------------------------------------------------------
+// Called when search is finished
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::ReportFinishedL()
+ {
+ //Search is completed, call the appropriate function
+ for( TInt j = 0; j < iHeavyResultsArray.Count(); j++ )
+ {
+
+ iCotnactDeletedList.Append(EFalse);
+ }
+ iObserver->SearchCompletedL( iTotalHits, iTotalNumOfContactsSearched );
+
+ }
+
+// ---------------------------------------------------------------------------------
+// Will be called when the CActive::Cancel() is called.. by DoCancel()
+// ---------------------------------------------------------------------------------
+//
+void CContactsSearcher::CleanUp()
+ {
+ //Cleanup the resources
+ // delete all the data members owned.
+
+ delete iCurrentTitle;
+ iCurrentTitle = NULL;
+
+ delete iCurrentSnippet;
+ iCurrentSnippet = NULL;
+
+ delete iContactsDataTobeSearched ;
+ iContactsDataTobeSearched = NULL;
+
+ delete iCurrentContactDataString;
+ iCurrentContactDataString = NULL;
+
+
+ if( iAllContactItemsFromDb)
+ {
+ delete iAllContactItemsFromDb;
+ iAllContactItemsFromDb = NULL ;
+ }
+
+
+ if(iFieldTypeRefList )
+ {
+ iFieldTypeRefList->Reset();
+ delete iFieldTypeRefList;
+ iFieldTypeRefList = NULL;
+ }
+ delete iVPbkOperation;
+ iVPbkOperation = NULL;
+
+ delete iSearchStrings;
+ iSearchStrings = NULL;
+
+ delete iBufferForQuery;
+ iBufferForQuery = NULL;
+
+
+
+ }
+
+
+// ---------------------------------------------------------------------------------
+// Does the search for the file. Called from RunL.
+// Return: ETrue: if more note items need to be searched.
+// EFalse: otherwise (i.e if iAllContactsSearched is set to true)
+// ---------------------------------------------------------------------------------
+//
+TBool CContactsSearcher::DoActualSearchL()
+ {
+
+ if (iNoContactStoreAvailable || iAllContactsSearched )
+ {
+ // Either store is not available, or all data has been searched
+ // so retrun EFalse
+ return EFalse;
+ }
+
+ if(iStoreReadyForAccessing )
+ {
+ // Start the search if not yet started
+ if(!iSearchStarted)
+ {
+ iSearchStarted = ETrue;
+ FetchContactItemsFromDbAndSearchL();
+ }
+
+ }
+
+ return ETrue;
+
+ }
+
+// ---------------------------------------------------------------------------
+// From class MVPbkContactFindObserver.
+// When using the FindL, check that the field type of the find result is correct
+// since the underlying db find isnt perfect, ex. uses SQL to optimize the find.
+// Test application doesn't check the contact fields, it might be possible
+// the a field whose type was not given in Find has been matched.
+// ---------------------------------------------------------------------------
+//
+
+// ---------------------------------------------------------------------------
+// Fetches the contact items from the database.
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::FetchContactItemsFromDbAndSearchL(void)
+ {
+ // We just fire a find function with null value to get all the links
+ // in the contact store. Once we get the links, we extract data from them
+ // to be searched, and then pass the same to the text searcher
+
+ CPbk2SortOrderManager* sortOrderManager = CPbk2SortOrderManager::NewL( iContactManager->FieldTypes() );
+ CleanupStack::PushL( sortOrderManager );
+
+ CVPbkContactViewDefinition* viewDef = CVPbkContactViewDefinition::NewL();
+ CleanupStack::PushL( viewDef );
+ viewDef->SetType( EVPbkCompositeView );
+
+ MVPbkContactStoreList& stores = iContactManager->ContactStoresL();
+ TInt totalNumberOfContacts = 0;
+ for ( TInt i(0); i < iCurrentlyOpenStores->Count(); ++i)
+ {
+
+ TInt numberOfContacts = stores.Find((*iCurrentlyOpenStores)[i])->StoreInfo().NumberOfContactsL();
+ totalNumberOfContacts += numberOfContacts;
+ if ( numberOfContacts != 0)
+ {
+ CVPbkContactViewDefinition* subViewDef = CVPbkContactViewDefinition::NewL();
+ CleanupStack::PushL( subViewDef );
+ subViewDef->SetUriL( (*iCurrentlyOpenStores)[i].UriDes() );
+ viewDef->AddSubViewL( subViewDef );
+ CleanupStack::Pop( subViewDef ); // Ownership changed.
+ }
+ }
+ if (totalNumberOfContacts == 0)
+ {
+ iAllContactsSearched = ETrue;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+ iContactViewBase = iContactManager->CreateContactViewLC(
+ *this, *viewDef, sortOrderManager->SortOrder() );
+
+ CleanupStack::Pop(); // CreateContactViewLC
+ CleanupStack::PopAndDestroy( viewDef );
+ CleanupStack::PopAndDestroy( sortOrderManager );
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// Handles the operations for a single contact after it is fetched
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::HandleRetrievedContactL(
+ MVPbkStoreContact* aContact )
+ {
+
+ // 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.)
+ //Fetch all the editable data of the fetched contact
+ // and pass it to the iTextSearcher for searching
+ GetDataForSingleContactL( *aContact );
+ iTotalNumOfContactsSearched++;
+ if(!iSearchCancelled)
+ {
+ iTextSearcher->SearchL( *iCurrentContactDataString );
+ }
+
+ }
+ else
+ {
+
+ }
+
+ CleanupStack::PopAndDestroy(); // aContact
+ if(iCurrentContactDataString)
+ {
+ delete iCurrentContactDataString;
+ iCurrentContactDataString = NULL;
+ }
+
+
+ // Start reading next contact
+ if ( iAllContactItemsFromDb)
+ {
+ if ( !iSearchCancelled && (iAllContactItemsFromDb->Count() > iCurrentDatatBaseItemIndex ))
+ {
+ const MVPbkContactLink& link = iAllContactItemsFromDb->At( iCurrentDatatBaseItemIndex );
+ iCurrentDatatBaseItemIndex++;
+
+ iVPbkOperation = iContactManager->RetrieveContactL( link, *this );
+
+ }
+ else
+ {
+ // All the contacts have been read so set the iAllContactsSearched flag
+ iAllContactsSearched = ETrue;
+
+ }
+ }
+
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Fetches the data from a particular contact
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::GetDataForSingleContactL( MVPbkBaseContact& aContact )
+ {
+ // Fetches all the editable fields for a particular contact. The AddContactFieldsL()
+ // function fetches the data for a particular entry of the contact.
+ // iCurrentContactDataString will contain the final space separated string
+ if(iCurrentContactDataString)
+ {
+ delete iCurrentContactDataString;
+ iCurrentContactDataString = NULL;
+ }
+ delete iCurrentSnippet;
+ iCurrentSnippet = NULL;
+
+ // First fetch the last name and first name
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_COMPANYNAME);
+
+ // Now the iCurrentContactDataString contains last name and first name.
+ // This forms the title for our contact.
+ if(iCurrentContactDataString)
+ {
+ if(iCurrentTitle)
+ {
+ delete iCurrentTitle;
+ iCurrentTitle = NULL;
+ }
+ iCurrentTitle = HBufC::NewL(iCurrentContactDataString->Des().Length());
+ TPtr ptr( iCurrentTitle->Des() );
+ ptr.Append(iCurrentContactDataString->Des());
+ //delete iCurrentContactDataString; iCurrentContactDataString = NULL;
+ }
+ else
+ {
+ iCurrentTitle = HBufC::NewL(KBufferLength);
+ TPtr ptr( iCurrentTitle->Des() );
+ ptr.Append( KUnnamedContact );
+ }
+
+ if(iCurrentSnippet)
+ {
+ delete iCurrentSnippet;
+ iCurrentSnippet = NULL;
+ }
+
+ // Add the Phone number
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEGEN);
+
+ //AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LASTNAMEREADING);
+ //AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FIRSTNAMEREADING);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_PREFIX);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SUFFIX);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SECONDNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOHOME );
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEHOME );
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYHOME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_JOBTITLE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_COMPANYNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEWORK );
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYWORK);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LANDPHONEGEN);
+ //AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MOBILEPHONEGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VIDEONUMBERGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_FAXNUMBERGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_VOIPGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_POC);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SWIS );
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SIP);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_EMAILGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_URLGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLABELGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDREXTGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRSTREETGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRLOCALGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRREGIONGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRPOSTCODEGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ADDRCOUNTRYGEN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_PAGERNUMBER);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DTMFSTRING);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_WVADDRESS);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DATE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_NOTE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_THUMBNAILPIC);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_RINGTONE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CALLEROBJIMG);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CALLEROBJTEXT);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_MIDDLENAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_DEPARTMENT );
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ASSTNAME);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SPOUSE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CHILDREN);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ASSTPHONE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_CARPHONE);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_ANNIVERSARY);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_SYNCCLASS);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_LOCPRIVACY);
+ AddContactFieldsL( aContact,R_VPBK_FIELD_TYPE_GENLABEL);
+
+ //Set the snippet if not set yet
+ if(!iCurrentSnippet)
+ {
+ iCurrentSnippet =HBufC8::NewL(KSpace().Length());
+ iCurrentSnippet->Des().Append( KSpace );
+ }
+
+}
+
+
+// ---------------------------------------------------------------------------
+// Add the data from contact fields
+// ---------------------------------------------------------------------------
+//
+void CContactsSearcher::AddContactFieldsL(MVPbkBaseContact& aContact,TInt afieldtype)
+ {
+
+ const MVPbkFieldType* myContactDataField =
+ iContactManager->FieldTypes().Find( afieldtype );
+
+ CVPbkBaseContactFieldTypeIterator* itr =
+ CVPbkBaseContactFieldTypeIterator::NewLC( *myContactDataField,
+ aContact.Fields() );
+ while ( itr->HasNext() )
+ {
+
+ const MVPbkBaseContactField* field = itr->Next();
+ // last name field is text data
+ HBufC* fieldToAdd = NULL;
+
+ //Check if the contact filed is a date field or a text field
+ if( (field->FieldData()).DataType() == EVPbkFieldStorageTypeDateTime)
+ {
+
+ const MVPbkContactFieldDateTimeData& myDate = MVPbkContactFieldDateTimeData::Cast( field->FieldData() );
+ TTime dateValue = myDate.DateTime();
+ TDateTime xyz = dateValue.DateTime();
+ TInt yearDate = xyz.Year();
+ TInt monthDate = xyz.Month() + 1; //Add 1,since month starts from 0
+ TInt dayDate = xyz.Day() + 1;//Add 1,since day starts from 0
+
+ //Form the date filed .. DD/MM/YYYY
+ fieldToAdd = HBufC::NewLC( KMaxFileName );
+ TPtr fieldToAddPtr( fieldToAdd->Des() );
+ fieldToAddPtr.AppendNum( dayDate );
+ fieldToAddPtr.Append( KForwardSlash );
+ fieldToAddPtr.AppendNum( monthDate );
+ fieldToAddPtr.Append( KForwardSlash );
+
+ //The year is shown as YYYY. So append appropriate
+ // number of zeros in the year
+ if(yearDate < 10)
+ {
+ fieldToAddPtr.AppendNum(0);
+ fieldToAddPtr.AppendNum(0);
+ fieldToAddPtr.AppendNum(0);
+ }
+ else if(yearDate < 100)
+ {
+ fieldToAddPtr.AppendNum(0);
+ fieldToAddPtr.AppendNum(0);
+ }
+ else if(yearDate < 1000)
+ {
+ fieldToAddPtr.AppendNum(0);
+
+ }
+
+ fieldToAddPtr.AppendNum( yearDate );
+
+
+ }
+ else if( (field->FieldData()).DataType() == EVPbkFieldStorageTypeText)
+ {
+
+ const MVPbkContactFieldTextData& data =
+ MVPbkContactFieldTextData::Cast( field->FieldData() );
+
+ fieldToAdd = data.Text().AllocLC();
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( itr );
+ return;
+ }
+
+ if(!iCurrentSnippet)
+ {
+
+ switch(afieldtype)
+ {
+
+ case R_VPBK_FIELD_TYPE_LANDPHONEGEN:
+ case R_VPBK_FIELD_TYPE_LANDPHONEWORK:
+ case R_VPBK_FIELD_TYPE_LANDPHONEHOME:
+ case R_VPBK_FIELD_TYPE_MOBILEPHONEWORK:
+ case R_VPBK_FIELD_TYPE_MOBILEPHONEGEN:
+ case R_VPBK_FIELD_TYPE_MOBILEPHONEHOME:
+
+ if(fieldToAdd->Des().Length())
+ {
+ iCurrentSnippet = HBufC8::NewL(KSpace().Length() + fieldToAdd->Des().Length() ) ;
+ TPtr8 ptr8(iCurrentSnippet->Des()) ;
+ TPtr16 ptr16(fieldToAdd->Des()) ;
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( ptr8,ptr16 );
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ }
+ if(iCurrentContactDataString)
+ {
+ iCurrentContactDataString = iCurrentContactDataString->ReAllocL(
+ iCurrentContactDataString->Length() +
+ KSpace().Length() + fieldToAdd->Des().Length() );
+
+ }
+ else
+ {
+ iCurrentContactDataString =HBufC::NewL(KSpace().Length() + fieldToAdd->Des().Length() ) ;
+
+ }
+
+ iCurrentContactDataString->Des().Append( fieldToAdd->Des() );
+ iCurrentContactDataString->Des().Append( KSpace );
+ CleanupStack::PopAndDestroy( fieldToAdd );
+ }
+
+ CleanupStack::PopAndDestroy( itr );
+
+ }
+
+void CContactsSearcher::ContactViewReadyL(
+ MVPbkContactViewBase& aView )
+ {
+ aView.RemoveObserver( *this );
+ if ( !iIsFilterView )
+ {
+ iSearchStrings = new( ELeave ) CDesCArrayFlat( 2 );
+ for ( TInt i = 0; i < iTextSearcher->SearchKeyword()->MdcaCount(); ++i )
+ {
+ TPtrC searchWord = iTextSearcher->SearchKeyword()->MdcaPoint( i );
+ TVPbkWordParserCallbackParam param( &searchWord, iSearchStrings );
+ VPbkParseDataL( ¶m );
+ }
+
+ if (iSearchStrings->MdcaCount() == 0)
+ {
+ iSearchStrings->AppendL(KNullDesC);
+ }
+
+ iFilterView = iContactViewBase->ViewFiltering()->CreateFilteredViewLC(*this, *iSearchStrings, NULL );
+ CleanupStack::Pop();
+ iIsFilterView = ETrue;
+ return;
+ }
+ delete iVPbkOperation;
+ iVPbkOperation = NULL;
+
+ delete iSearchStrings;
+ iSearchStrings = NULL;
+
+ delete iBufferForQuery;
+ iBufferForQuery = NULL;
+
+ TInt cnt = aView.ContactCountL();
+ for ( TInt i = 0; i < cnt; ++i )
+ {
+ if ( iAllContactItemsFromDb )
+ {
+ iAllContactItemsFromDb->AppendL( aView.CreateLinkLC(i) );
+ CleanupStack::Pop();
+ }
+ }
+
+ if ( iAllContactItemsFromDb )
+ {
+ if ( iAllContactItemsFromDb->Count() >0)
+ {
+ // If there are still contacts available, then retrieve them one by one
+ const MVPbkContactLink& link = iAllContactItemsFromDb->At( iCurrentDatatBaseItemIndex );
+ iCurrentDatatBaseItemIndex++;
+ //Retrieve the contact
+ TRAP_IGNORE( iVPbkOperation = iContactManager->RetrieveContactL( link, *this ) );
+ }
+ else
+ {
+ // All contacts searched, set the appropriate flag
+ iAllContactsSearched = ETrue;
+
+ // Active object needs to be activated.
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+ }
+ }
+// --------------------------------------------------------------------
+//Called when a view is ready for use.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewReady(
+ MVPbkContactViewBase& aView )
+ {
+ TRAP_IGNORE(ContactViewReadyL(aView));
+ }
+
+// --------------------------------------------------------------------
+// Called when a view is unavailable for a while.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewUnavailable(
+ MVPbkContactViewBase& aView )
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ return;
+ }
+
+// --------------------------------------------------------------------
+// Called when a contact has been added to the view.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactAddedToView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex,
+ const MVPbkContactLink& aContactLink )
+ {
+ }
+
+// --------------------------------------------------------------------
+// Called when an error occurs in the view.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactRemovedFromView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex,
+ const MVPbkContactLink& aContactLink )
+ {
+ }
+
+// --------------------------------------------------------------------
+// Called when a contact has been removed from a view.
+// --------------------------------------------------------------------
+//
+void CContactsSearcher::ContactViewError(
+ MVPbkContactViewBase& aView,
+ TInt aError,
+ TBool aErrorNotified )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// A function that parser field data into words
+// This function is used as a callback in the iContactManager->FindL()
+// ---------------------------------------------------------------------------
+//
+TInt VPbkParseDataL( TAny* aParam )
+ {
+ TVPbkWordParserCallbackParam* param =
+ static_cast<TVPbkWordParserCallbackParam*>( aParam );
+ const TText* ptr = param->iStringToParse->Ptr();
+ const TText* end = ptr + param->iStringToParse->Length();
+ const TText* startOfWord = NULL;
+
+ if ( FeatureManager::FeatureSupported( KFeatureIdJapanese ) ||
+ FeatureManager::FeatureSupported( KFeatureIdChinese ) ||
+ FeatureManager::FeatureSupported( KFeatureIdThai ) )
+ {
+ while(ptr != end)
+ {
+ if (*ptr >= 0x4e00)
+ {
+ TPtrC addWord(ptr, 1);
+ param->iWordArray->AppendL(addWord);
+ }
+ ptr++;
+ }
+ }
+ else
+ {
+ FOREVER
+ {
+ // Other than alpha digit are separators
+ if (ptr==end || !TChar(*ptr).IsAlphaDigit())
+ {
+ if (startOfWord)
+ {
+ TPtrC addWord(startOfWord,ptr-startOfWord);
+ param->iWordArray->AppendL(addWord);
+ startOfWord=NULL;
+ }
+ if (ptr==end)
+ break;
+ }
+ else if (!startOfWord)
+ startOfWord=ptr;
+ ptr++;
+ }
+ }
+ return KErrNone;
+ }
+
+