diff -r 000000000000 -r f979ecb2b13e searchfw/plugins/contactsplugin/src/contactssearcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/searchfw/plugins/contactsplugin/src/contactssearcher.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,1292 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//USER INCLUDES +#include "contactssearcher.h" +#include "contactssearchplugindefines.h" +#include +//FORWARD DECLARATION +TInt VPbkParseDataL( TAny* aParam ); + + +// --------------------------------------------------------------------------------- +// 1st phase constructor +// --------------------------------------------------------------------------------- +// +CContactsSearcher* CContactsSearcher::NewL( const RArray& 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& aDocumentIdArray ) + { + + //Check the aDocumentIdArray + // For all the matching documentIds, fetch the corresponding + // Heavy Result from iHeavyResultsArray and append it to heavyResultResponse + + RPointerArray 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 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 + { + User::Leave( KErrNotFound ); + } + + } + + 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& /*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 + + CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL( iContactManager->FieldTypes() ); + CleanupStack::PushL( sortOrder ); + + 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, *sortOrder ); + + CleanupStack::Pop(); // CreateContactViewLC + CleanupStack::PopAndDestroy( viewDef ); + CleanupStack::PopAndDestroy( sortOrder ); + } + + + +// --------------------------------------------------------------------------- +// 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( 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; + } + +