diff -r 000000000000 -r 72b543305e3a email/mail/ViewerSrc/cmsgmailviewercontactmatcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/mail/ViewerSrc/cmsgmailviewercontactmatcher.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,408 @@ +/* +* Copyright (c) 2006 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: Mail viewer contact finder. +* +*/ + +#include "cmsgmailviewercontactmatcher.h" +#include "MailLog.h" +#include +#include +#include // KLeaveExit +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Constants + +// --------------------------------------------------------------------------- +// CMsgMailViewerContactMatcher +// --------------------------------------------------------------------------- +// +CMsgMailViewerContactMatcher::CMsgMailViewerContactMatcher( + CAiwServiceHandler& aServiceHandler ) + : CActive( EPriorityStandard ), + iServiceHandler( aServiceHandler ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +// +inline void CMsgMailViewerContactMatcher::ConstructL() + { + LOG("CMsgMailViewerContactMatcher::ConstructL()"); + iContactMatcher = CContactMatcher::NewL( + &CCoeEnv::Static()->FsSession() ); + + //Changed to open only default stores. + //Opening of all stores caused + //frequent jamming. + iContactMatcher->OpenDefaultMatchStoresL(); + + iContactLinks = CVPbkContactLinkArray::NewL(); + iChangedLinks = CVPbkContactLinkArray::NewL(); + + //Idle object is needed because we can't + //call callback method straight from HandleNotifyL(). + //It causes KErrInUse leave. + iIdle = CIdle::NewL(CActive::EPriorityIdle); + + iServiceHandler.AttachL( R_PHONENUMBER_MATCH_INTEREST ); + LOG("CMsgMailViewerContactMatcher::ConstructL() -> END"); + } + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CMsgMailViewerContactMatcher* CMsgMailViewerContactMatcher::NewL( + CAiwServiceHandler& aServiceHandler ) + { + CMsgMailViewerContactMatcher* self = + new( ELeave ) CMsgMailViewerContactMatcher( aServiceHandler ); + CleanupStack::PushL( self ); + self->ConstructL(); + + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// ~CMsgMailViewerContactMatcher +// --------------------------------------------------------------------------- +// +CMsgMailViewerContactMatcher::~CMsgMailViewerContactMatcher() + { + Cancel(); + // delete link arrays first to avoid access violations: + delete iContactLinks; + delete iChangedLinks; + // doesn't matter really if detaching fails + TRAP_IGNORE( iServiceHandler.DetachL( R_PHONENUMBER_MATCH_INTEREST ) ); + delete iContactMatcher; + delete iIdle; + } + +// ---------------------------------------------------------------------------- +// FindContactL +// ---------------------------------------------------------------------------- +// +void CMsgMailViewerContactMatcher::FindContactL( + const TDesC& aMailAddress, + TPurpose aPurpose, + TCallBack aCallBack ) + { + LOG1("CMsgMailViewerContactMatcher::FindContactL: %S", &aMailAddress); + if ( !IsActive() ) + { + iPurpose = aPurpose; + iCallBack = aCallBack; + // reset old data + iContactLinks->ResetAndDestroy(); + iChangedLinks->ResetAndDestroy(); + + const MVPbkFieldTypeList& fieldTypes = iContactMatcher->FieldTypes(); + iContactMatcher->MatchDataL( aMailAddress, + fieldTypes, + *iContactLinks, + iStatus ); + SetActive(); + + ASSERT( !iWaitDialog ); // should not exist! + // dialog sets iWaitDialog to NULL when it gets deleted + iWaitDialog = new( ELeave ) CAknWaitDialog( + ( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ) )); + // safe to call LD even as a member variable, since sets itself to NULL when deleting + iWaitDialog->ExecuteLD( R_VIEWER_WAIT_MATCHING_NOTE ); // CSI: 50 # see comment above + } + } + + +//---------------------------------------------------------------------------- +// GetDataL() +// Returns NULL pointer if no data is found +//---------------------------------------------------------------------------- +HBufC* CMsgMailViewerContactMatcher::GetDataL() const + { + ASSERT( !IsActive() ); + + HBufC* text( NULL ); + if ( iChangedLinks->Count() > 0 ) + { + ASSERT( iChangedLinks->Count() == 1 ); // single item fetch -> 1 + MVPbkStoreContact* storeContact = NULL; + MVPbkStoreContactField* selectedField = NULL; + const MVPbkContactLink& link = iChangedLinks->At( 0 ); + iContactMatcher->GetStoreContactL( link, &storeContact ); + storeContact->PushL(); + MVPbkStoreContactFieldCollection& fieldCollection = + storeContact->Fields(); + selectedField = fieldCollection.RetrieveField( link ); + if ( selectedField ) + { + // Set field data + const MVPbkContactFieldTextData* textData = + &MVPbkContactFieldTextData::Cast( selectedField->FieldData() ); + text = textData->Text().AllocL(); + } + CleanupStack::PopAndDestroy( storeContact ); + } + return text; + } +//---------------------------------------------------------------------------- +// GetNameL() +// Returns NULL pointer if no data is found +//---------------------------------------------------------------------------- +HBufC* CMsgMailViewerContactMatcher::GetNameL() const + { + MVPbkStoreContact* storeContact = NULL; + HBufC* name( NULL ); + + ASSERT(iContactMatcher); // should exist + + if(iContactLinks->Count() > 0) + { + //We should have only one contact link. + iContactMatcher->GetStoreContactL( iContactLinks->At(0), &storeContact ); + storeContact->PushL(); + + MVPbkStoreContactFieldCollection& fieldCollection = + storeContact->Fields(); + + name = iContactMatcher->GetNameL(fieldCollection); + + CleanupStack::PopAndDestroy( storeContact ); + } + + + return name; + } + +// ---------------------------------------------------------------------------- +// From CActive +// ---------------------------------------------------------------------------- +// +void CMsgMailViewerContactMatcher::DoCancel() + { + if ( iContactMatcher ) + { + iContactMatcher->CancelOperation(); + } + } + +// ---------------------------------------------------------------------------- +// From CActive +// ---------------------------------------------------------------------------- +// +void CMsgMailViewerContactMatcher::RunL() + { + LOG1("CMsgMailViewerContactMatcher::RunL: %d", iStatus.Int()); + + ASSERT( iWaitDialog ); // should exist! + iWaitDialog->ProcessFinishedL(); // deletes the dialog + + if(iContactLinks->Count() == 0) + { + //No matching contacts found -> no need to do fetch. + + //We can't call iCallBack straight away, + //because it triggers events that cause KErrInUse leave. + iIdle->Start(iCallBack); // CSI: 10 # + } + else + { + // We need to delete excess matches, otherwise Fetch AIW may + // continue with next match when user presses Cancel. + DeleteExcessMatches( *iContactLinks ); + CVPbkFieldTypeSelector* filter = CreateFilterLC( iPurpose ); + TAiwSingleItemSelectionDataV3 selectionData = SelectionData( iPurpose, + *filter); + ExecuteSingleItemFetchL( selectionData, *iContactLinks ); + CleanupStack::PopAndDestroy( filter ); + } + } + +// ---------------------------------------------------------------------------- +// From CActive +// ---------------------------------------------------------------------------- +// +TInt CMsgMailViewerContactMatcher::RunError( TInt aError ) + { + LOG1("CMsgMailViewerContactMatcher::RunError: %d", aError); + + if( aError == KLeaveExit ) + { + return aError; + } + else + { + return KErrNone; + } + } + +// ---------------------------------------------------------------------------- +// From MAiwNotifyCallback +// ---------------------------------------------------------------------------- +// +TInt CMsgMailViewerContactMatcher::HandleNotifyL( // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + TInt LOGPARAM_ONLY( aCmdId ), + TInt aEventId, + CAiwGenericParamList& aEventParamList, + const CAiwGenericParamList& /*aInParamList*/ ) + { + LOG1("CMsgMailViewerContactMatcher::HandleNotifyL: %d", aCmdId); + TInt retVal( KErrNone ); + if ( aEventId == KAiwEventCompleted ) + { + TInt index( 0 ); + const TAiwGenericParam* param = + aEventParamList.FindFirst( index, EGenericParamContactLinkArray ); + if ( param ) + { + TPtrC8 contactLinks = param->Value().AsData(); + if ( contactLinks.Length() > 0 ) + { + CVPbkContactLinkArray* links = CVPbkContactLinkArray::NewLC( + contactLinks, iContactMatcher->GetContactStoresL() ); + CleanupStack::Pop();//links + iChangedLinks->ResetAndDestroy(); + delete iChangedLinks; + iChangedLinks = links; + LOG1("CMsgMailViewerContactMatcher::HandleNotifyL: LA %d", + iChangedLinks->Count()); + + //We can't call iCallBack straight away, + //because it triggers events that cause KErrInUse leave. + iIdle->Start(iCallBack); // CSI: 10 # + } + else + { + retVal = KErrArgument; + } + } + } + return retVal; + } + +//---------------------------------------------------------------------------- +// DeleteExcessMatches() +//---------------------------------------------------------------------------- +void CMsgMailViewerContactMatcher::DeleteExcessMatches( + CVPbkContactLinkArray& aLinks ) const + { + TInt i( aLinks.Count() - 1 ); + // delete all but link at index 0 + while ( i > 0 ) + { + aLinks.Delete( i-- ); + } + } + +//---------------------------------------------------------------------------- +// CreateFilterLC() +//---------------------------------------------------------------------------- +CVPbkFieldTypeSelector* CMsgMailViewerContactMatcher::CreateFilterLC( + TPurpose aPurpose ) const + { + CVPbkContactManager& contactMgr = iContactMatcher->GetContactManager(); + CVPbkFieldTypeSelector* contactViewFilter = + CVPbkFieldTypeSelector::NewL( contactMgr.FieldTypes() ); + CleanupStack::PushL( contactViewFilter ); + + ASSERT( aPurpose != EPurposeNone ); + + if ( aPurpose == ECallToContact || aPurpose == EMsgToContact ) + { + // Append the filter object with suitable criteria + VPbkContactViewFilterBuilder::BuildContactViewFilterL( + *contactViewFilter, EVPbkContactViewFilterPhoneNumber, contactMgr ); + } + + // if message, then add also email addresses in addition to phone numbers + if ( aPurpose == EMsgToContact ) + { + VPbkContactViewFilterBuilder::BuildContactViewFilterL( + *contactViewFilter, EVPbkContactViewFilterEmail, contactMgr ); + } + + return contactViewFilter; + } + +//---------------------------------------------------------------------------- +// SelectionData() +//---------------------------------------------------------------------------- +TAiwSingleItemSelectionDataV3 +CMsgMailViewerContactMatcher::SelectionData( + TPurpose aPurpose, + CVPbkFieldTypeSelector& aFilter ) const + { + TAiwAddressSelectType addressSelectType( EAiwAllItemsSelect ); + if ( aPurpose == ECallToContact ) + { + addressSelectType = EAiwPhoneNumberSelect; + } + else + { + ASSERT( aPurpose == EMsgToContact ); + addressSelectType = EAiwMMSSelect; + } + TAiwSingleItemSelectionDataV3 selData; + selData.SetAddressSelectType( addressSelectType ) + .SetFetchFilter( &aFilter ); + return selData; + } + +//---------------------------------------------------------------------------- +// ExecuteSingleItemFetchL() +//---------------------------------------------------------------------------- +void CMsgMailViewerContactMatcher::ExecuteSingleItemFetchL( + TAiwSingleItemSelectionDataV3 aData, + const CVPbkContactLinkArray& aLinks ) + { + CAiwGenericParamList& inParamList = iServiceHandler.InParamListL(); + inParamList.AppendL( + TAiwGenericParam( EGenericParamContactSelectionData, + TAiwVariant( TAiwSingleItemSelectionDataV3Pckg( aData ) ) ) ); + + //Contacts that matched search + HBufC8* packedLinks = aLinks.PackLC(); + + inParamList.AppendL( TAiwGenericParam( EGenericParamContactLinkArray, + TAiwVariant( *packedLinks ) ) ); + + iServiceHandler.ExecuteServiceCmdL( KAiwCmdSelect, + inParamList, + iServiceHandler.OutParamListL(), + 0, + this ); + CleanupStack::PopAndDestroy( packedLinks ); + } + +// End of File +