|         |      1 /* | 
|         |      2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:  Mail viewer contact finder. | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18 #include "cmsgmailviewercontactmatcher.h" | 
|         |     19 #include "MailLog.h" | 
|         |     20 #include <MsgMailViewer.rsg> | 
|         |     21 #include <coemain.h> | 
|         |     22 #include <basched.h> // KLeaveExit | 
|         |     23 #include <contactmatcher.h> | 
|         |     24 #include <CVPbkContactManager.h> | 
|         |     25 #include <CVPbkContactLinkArray.h> | 
|         |     26 #include <MVPbkStoreContact.h> | 
|         |     27 #include <CVPbkFieldTypeSelector.h> | 
|         |     28 #include <VPbkContactViewFilterBuilder.h> | 
|         |     29 #include <MVPbkContactFieldTextData.h> | 
|         |     30 #include <CVPbkFieldTypeRefsList.h> | 
|         |     31 #include <TVPbkFieldVersitProperty.h> | 
|         |     32 #include <AiwServiceHandler.h> | 
|         |     33 #include <finditemmenu.h> | 
|         |     34 #include <e32base.h> | 
|         |     35 #include <AknWaitDialog.h> | 
|         |     36  | 
|         |     37 // Constants  | 
|         |     38      | 
|         |     39 // --------------------------------------------------------------------------- | 
|         |     40 // CMsgMailViewerContactMatcher | 
|         |     41 // --------------------------------------------------------------------------- | 
|         |     42 // | 
|         |     43 CMsgMailViewerContactMatcher::CMsgMailViewerContactMatcher( | 
|         |     44     CAiwServiceHandler& aServiceHandler ) | 
|         |     45     : CActive( EPriorityStandard ), | 
|         |     46     iServiceHandler( aServiceHandler ) | 
|         |     47     { | 
|         |     48     CActiveScheduler::Add( this ); | 
|         |     49     } | 
|         |     50  | 
|         |     51 // --------------------------------------------------------------------------- | 
|         |     52 // ConstructL | 
|         |     53 // --------------------------------------------------------------------------- | 
|         |     54 // | 
|         |     55 inline void CMsgMailViewerContactMatcher::ConstructL() | 
|         |     56     { | 
|         |     57     LOG("CMsgMailViewerContactMatcher::ConstructL()"); | 
|         |     58     iContactMatcher = CContactMatcher::NewL(  | 
|         |     59         &CCoeEnv::Static()->FsSession() ); | 
|         |     60          | 
|         |     61     //Changed to open only default stores. | 
|         |     62     //Opening of all stores caused | 
|         |     63     //frequent jamming. | 
|         |     64     iContactMatcher->OpenDefaultMatchStoresL(); | 
|         |     65      | 
|         |     66     iContactLinks = CVPbkContactLinkArray::NewL(); | 
|         |     67     iChangedLinks = CVPbkContactLinkArray::NewL(); | 
|         |     68      | 
|         |     69     //Idle object is needed because we can't | 
|         |     70     //call callback method straight from HandleNotifyL(). | 
|         |     71     //It causes KErrInUse leave. | 
|         |     72     iIdle = CIdle::NewL(CActive::EPriorityIdle); | 
|         |     73      | 
|         |     74     iServiceHandler.AttachL( R_PHONENUMBER_MATCH_INTEREST );     | 
|         |     75     LOG("CMsgMailViewerContactMatcher::ConstructL() -> END"); | 
|         |     76     } | 
|         |     77  | 
|         |     78 // --------------------------------------------------------------------------- | 
|         |     79 // NewL | 
|         |     80 // --------------------------------------------------------------------------- | 
|         |     81 // | 
|         |     82 CMsgMailViewerContactMatcher* CMsgMailViewerContactMatcher::NewL( | 
|         |     83     CAiwServiceHandler& aServiceHandler ) | 
|         |     84     { | 
|         |     85     CMsgMailViewerContactMatcher* self = | 
|         |     86         new( ELeave ) CMsgMailViewerContactMatcher( aServiceHandler ); | 
|         |     87     CleanupStack::PushL( self ); | 
|         |     88     self->ConstructL(); | 
|         |     89  | 
|         |     90     CleanupStack::Pop( self ); | 
|         |     91     return self; | 
|         |     92     } | 
|         |     93  | 
|         |     94 // --------------------------------------------------------------------------- | 
|         |     95 // ~CMsgMailViewerContactMatcher | 
|         |     96 // --------------------------------------------------------------------------- | 
|         |     97 // | 
|         |     98 CMsgMailViewerContactMatcher::~CMsgMailViewerContactMatcher() | 
|         |     99     { | 
|         |    100     Cancel(); | 
|         |    101     // delete link arrays first to avoid access violations: | 
|         |    102     delete iContactLinks;    | 
|         |    103     delete iChangedLinks;     | 
|         |    104     // doesn't matter really if detaching fails | 
|         |    105     TRAP_IGNORE( iServiceHandler.DetachL( R_PHONENUMBER_MATCH_INTEREST ) );   | 
|         |    106     delete iContactMatcher; | 
|         |    107     delete iIdle;    | 
|         |    108     }  | 
|         |    109      | 
|         |    110 // ---------------------------------------------------------------------------- | 
|         |    111 // FindContactL | 
|         |    112 // ---------------------------------------------------------------------------- | 
|         |    113 // | 
|         |    114 void CMsgMailViewerContactMatcher::FindContactL( | 
|         |    115     const TDesC& aMailAddress, | 
|         |    116     TPurpose aPurpose, | 
|         |    117     TCallBack aCallBack ) | 
|         |    118     { | 
|         |    119     LOG1("CMsgMailViewerContactMatcher::FindContactL: %S", &aMailAddress);     | 
|         |    120     if ( !IsActive() )          | 
|         |    121         {         | 
|         |    122         iPurpose = aPurpose; | 
|         |    123         iCallBack = aCallBack; | 
|         |    124         // reset old data | 
|         |    125         iContactLinks->ResetAndDestroy(); | 
|         |    126         iChangedLinks->ResetAndDestroy();         | 
|         |    127          | 
|         |    128         const MVPbkFieldTypeList& fieldTypes = iContactMatcher->FieldTypes();          | 
|         |    129         iContactMatcher->MatchDataL( aMailAddress,  | 
|         |    130                                      fieldTypes,  | 
|         |    131                                      *iContactLinks, | 
|         |    132                                      iStatus );   | 
|         |    133         SetActive(); | 
|         |    134          | 
|         |    135         ASSERT( !iWaitDialog ); // should not exist! | 
|         |    136         // dialog sets iWaitDialog to NULL when it gets deleted | 
|         |    137         iWaitDialog = new( ELeave ) CAknWaitDialog( | 
|         |    138             ( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ) )); | 
|         |    139 		// safe to call LD even as a member variable, since sets itself to NULL when deleting | 
|         |    140         iWaitDialog->ExecuteLD( R_VIEWER_WAIT_MATCHING_NOTE ); // CSI: 50 # see comment above | 
|         |    141         } | 
|         |    142     }     | 
|         |    143      | 
|         |    144      | 
|         |    145 //---------------------------------------------------------------------------- | 
|         |    146 // GetDataL() | 
|         |    147 // Returns NULL pointer if no data is found | 
|         |    148 //---------------------------------------------------------------------------- | 
|         |    149 HBufC* CMsgMailViewerContactMatcher::GetDataL() const | 
|         |    150     { | 
|         |    151     ASSERT( !IsActive() ); | 
|         |    152      | 
|         |    153     HBufC* text( NULL ); | 
|         |    154     if ( iChangedLinks->Count() > 0 ) | 
|         |    155         { | 
|         |    156         ASSERT( iChangedLinks->Count() == 1 ); // single item fetch -> 1 | 
|         |    157         MVPbkStoreContact* storeContact = NULL; | 
|         |    158         MVPbkStoreContactField* selectedField = NULL;         | 
|         |    159         const MVPbkContactLink& link = iChangedLinks->At( 0 ); | 
|         |    160         iContactMatcher->GetStoreContactL( link, &storeContact );  | 
|         |    161         storeContact->PushL();    | 
|         |    162         MVPbkStoreContactFieldCollection& fieldCollection = | 
|         |    163             storeContact->Fields(); | 
|         |    164         selectedField = fieldCollection.RetrieveField( link );  | 
|         |    165         if ( selectedField ) | 
|         |    166             { | 
|         |    167             // Set field data | 
|         |    168             const MVPbkContactFieldTextData* textData = | 
|         |    169                 &MVPbkContactFieldTextData::Cast( selectedField->FieldData() ); | 
|         |    170             text = textData->Text().AllocL(); | 
|         |    171             } | 
|         |    172         CleanupStack::PopAndDestroy( storeContact ); | 
|         |    173         }         | 
|         |    174     return text; | 
|         |    175     } | 
|         |    176 //---------------------------------------------------------------------------- | 
|         |    177 // GetNameL() | 
|         |    178 // Returns NULL pointer if no data is found | 
|         |    179 //---------------------------------------------------------------------------- | 
|         |    180 HBufC* CMsgMailViewerContactMatcher::GetNameL() const | 
|         |    181     { | 
|         |    182     MVPbkStoreContact* storeContact = NULL; | 
|         |    183     HBufC* name( NULL ); | 
|         |    184      | 
|         |    185     ASSERT(iContactMatcher); // should exist | 
|         |    186      | 
|         |    187     if(iContactLinks->Count() > 0) | 
|         |    188         { | 
|         |    189         //We should have only one contact link. | 
|         |    190         iContactMatcher->GetStoreContactL( iContactLinks->At(0), &storeContact );  | 
|         |    191         storeContact->PushL();    | 
|         |    192              | 
|         |    193         MVPbkStoreContactFieldCollection& fieldCollection = | 
|         |    194             storeContact->Fields(); | 
|         |    195         | 
|         |    196         name = iContactMatcher->GetNameL(fieldCollection); | 
|         |    197          | 
|         |    198         CleanupStack::PopAndDestroy( storeContact ); | 
|         |    199         } | 
|         |    200      | 
|         |    201      | 
|         |    202     return name; | 
|         |    203     }        | 
|         |    204      | 
|         |    205 // ---------------------------------------------------------------------------- | 
|         |    206 // From CActive | 
|         |    207 // ---------------------------------------------------------------------------- | 
|         |    208 // | 
|         |    209 void CMsgMailViewerContactMatcher::DoCancel() | 
|         |    210     { | 
|         |    211     if ( iContactMatcher ) | 
|         |    212         { | 
|         |    213         iContactMatcher->CancelOperation(); | 
|         |    214         } | 
|         |    215     } | 
|         |    216      | 
|         |    217 // ---------------------------------------------------------------------------- | 
|         |    218 // From CActive | 
|         |    219 // ---------------------------------------------------------------------------- | 
|         |    220 // | 
|         |    221 void CMsgMailViewerContactMatcher::RunL() | 
|         |    222     { | 
|         |    223     LOG1("CMsgMailViewerContactMatcher::RunL: %d", iStatus.Int()); | 
|         |    224      | 
|         |    225     ASSERT( iWaitDialog ); // should exist! | 
|         |    226     iWaitDialog->ProcessFinishedL(); // deletes the dialog | 
|         |    227      | 
|         |    228     if(iContactLinks->Count() == 0) | 
|         |    229         { | 
|         |    230         //No matching contacts found -> no need to do fetch. | 
|         |    231          | 
|         |    232         //We can't call iCallBack straight away, | 
|         |    233         //because it triggers events that cause KErrInUse leave. | 
|         |    234         iIdle->Start(iCallBack); // CSI: 10 #  | 
|         |    235         } | 
|         |    236     else | 
|         |    237         { | 
|         |    238         // We need to delete excess matches, otherwise Fetch AIW may | 
|         |    239         // continue with next match when user presses Cancel. | 
|         |    240         DeleteExcessMatches( *iContactLinks ); | 
|         |    241         CVPbkFieldTypeSelector* filter = CreateFilterLC( iPurpose ); | 
|         |    242         TAiwSingleItemSelectionDataV3 selectionData = SelectionData( iPurpose, | 
|         |    243                                                                      *filter);         | 
|         |    244         ExecuteSingleItemFetchL( selectionData, *iContactLinks );     | 
|         |    245         CleanupStack::PopAndDestroy( filter ); | 
|         |    246         } | 
|         |    247     } | 
|         |    248 	 | 
|         |    249 // ---------------------------------------------------------------------------- | 
|         |    250 // From CActive | 
|         |    251 // ---------------------------------------------------------------------------- | 
|         |    252 // | 
|         |    253 TInt CMsgMailViewerContactMatcher::RunError( TInt aError ) | 
|         |    254     { | 
|         |    255     LOG1("CMsgMailViewerContactMatcher::RunError: %d", aError); | 
|         |    256        | 
|         |    257     if( aError == KLeaveExit ) | 
|         |    258         { | 
|         |    259         return aError;     | 
|         |    260         } | 
|         |    261     else | 
|         |    262         { | 
|         |    263         return KErrNone; | 
|         |    264         } | 
|         |    265     } | 
|         |    266  | 
|         |    267 // ---------------------------------------------------------------------------- | 
|         |    268 // From MAiwNotifyCallback | 
|         |    269 // ---------------------------------------------------------------------------- | 
|         |    270 // | 
|         |    271 TInt CMsgMailViewerContactMatcher::HandleNotifyL( // CSI: 40 # We must return  | 
|         |    272 												  // the integer value although this  | 
|         |    273 												  // is a leaving method. | 
|         |    274     TInt LOGPARAM_ONLY( aCmdId ), | 
|         |    275     TInt aEventId, | 
|         |    276     CAiwGenericParamList& aEventParamList, | 
|         |    277     const CAiwGenericParamList& /*aInParamList*/ ) | 
|         |    278     { | 
|         |    279     LOG1("CMsgMailViewerContactMatcher::HandleNotifyL: %d", aCmdId); | 
|         |    280     TInt retVal( KErrNone ); | 
|         |    281     if ( aEventId == KAiwEventCompleted ) | 
|         |    282         { | 
|         |    283         TInt index( 0 ); | 
|         |    284         const TAiwGenericParam* param = | 
|         |    285             aEventParamList.FindFirst( index, EGenericParamContactLinkArray ); | 
|         |    286         if ( param ) | 
|         |    287             { | 
|         |    288             TPtrC8 contactLinks = param->Value().AsData(); | 
|         |    289             if ( contactLinks.Length() > 0 ) | 
|         |    290                 { | 
|         |    291                 CVPbkContactLinkArray* links = CVPbkContactLinkArray::NewLC( | 
|         |    292                     contactLinks, iContactMatcher->GetContactStoresL() ); | 
|         |    293                 CleanupStack::Pop();//links | 
|         |    294                 iChangedLinks->ResetAndDestroy(); | 
|         |    295                 delete iChangedLinks; | 
|         |    296                 iChangedLinks = links; | 
|         |    297                 LOG1("CMsgMailViewerContactMatcher::HandleNotifyL: LA %d",  | 
|         |    298                      iChangedLinks->Count()); | 
|         |    299                  | 
|         |    300                 //We can't call iCallBack straight away, | 
|         |    301                 //because it triggers events that cause KErrInUse leave. | 
|         |    302                 iIdle->Start(iCallBack); // CSI: 10 #  | 
|         |    303                 } | 
|         |    304             else | 
|         |    305                 { | 
|         |    306                 retVal = KErrArgument;     | 
|         |    307                 } | 
|         |    308             }  | 
|         |    309         } | 
|         |    310     return retVal; | 
|         |    311     } | 
|         |    312  | 
|         |    313 //---------------------------------------------------------------------------- | 
|         |    314 //  DeleteExcessMatches() | 
|         |    315 //---------------------------------------------------------------------------- | 
|         |    316 void CMsgMailViewerContactMatcher::DeleteExcessMatches( | 
|         |    317     CVPbkContactLinkArray& aLinks ) const | 
|         |    318     { | 
|         |    319     TInt i( aLinks.Count() - 1 ); | 
|         |    320     // delete all but link at index 0 | 
|         |    321     while ( i > 0 ) | 
|         |    322         { | 
|         |    323         aLinks.Delete( i-- ); | 
|         |    324         } | 
|         |    325     } | 
|         |    326  | 
|         |    327 //---------------------------------------------------------------------------- | 
|         |    328 //  CreateFilterLC() | 
|         |    329 //---------------------------------------------------------------------------- | 
|         |    330 CVPbkFieldTypeSelector* CMsgMailViewerContactMatcher::CreateFilterLC( | 
|         |    331     TPurpose aPurpose ) const | 
|         |    332     { | 
|         |    333     CVPbkContactManager& contactMgr = iContactMatcher->GetContactManager(); | 
|         |    334     CVPbkFieldTypeSelector* contactViewFilter = | 
|         |    335         CVPbkFieldTypeSelector::NewL( contactMgr.FieldTypes() ); | 
|         |    336     CleanupStack::PushL( contactViewFilter ); | 
|         |    337  | 
|         |    338     ASSERT( aPurpose != EPurposeNone ); | 
|         |    339  | 
|         |    340     if ( aPurpose == ECallToContact ||  aPurpose == EMsgToContact ) | 
|         |    341         {         | 
|         |    342         // Append the filter object with suitable criteria | 
|         |    343         VPbkContactViewFilterBuilder::BuildContactViewFilterL( | 
|         |    344             *contactViewFilter, EVPbkContactViewFilterPhoneNumber, contactMgr ); | 
|         |    345         } | 
|         |    346          | 
|         |    347     // if message, then add also email addresses in addition to phone numbers | 
|         |    348     if ( aPurpose == EMsgToContact ) | 
|         |    349         {         | 
|         |    350         VPbkContactViewFilterBuilder::BuildContactViewFilterL( | 
|         |    351             *contactViewFilter, EVPbkContactViewFilterEmail, contactMgr ); | 
|         |    352         } | 
|         |    353          | 
|         |    354     return contactViewFilter; | 
|         |    355     } | 
|         |    356  | 
|         |    357 //---------------------------------------------------------------------------- | 
|         |    358 //  SelectionData() | 
|         |    359 //---------------------------------------------------------------------------- | 
|         |    360 TAiwSingleItemSelectionDataV3 | 
|         |    361 CMsgMailViewerContactMatcher::SelectionData( | 
|         |    362     TPurpose aPurpose, | 
|         |    363     CVPbkFieldTypeSelector& aFilter ) const | 
|         |    364     { | 
|         |    365     TAiwAddressSelectType addressSelectType( EAiwAllItemsSelect ); | 
|         |    366     if ( aPurpose == ECallToContact ) | 
|         |    367         { | 
|         |    368         addressSelectType = EAiwPhoneNumberSelect; | 
|         |    369         } | 
|         |    370     else  | 
|         |    371         {         | 
|         |    372         ASSERT( aPurpose == EMsgToContact ); | 
|         |    373         addressSelectType = EAiwMMSSelect; | 
|         |    374         } | 
|         |    375     TAiwSingleItemSelectionDataV3 selData; | 
|         |    376     selData.SetAddressSelectType( addressSelectType ) | 
|         |    377            .SetFetchFilter( &aFilter ); | 
|         |    378     return selData; | 
|         |    379     } | 
|         |    380  | 
|         |    381 //---------------------------------------------------------------------------- | 
|         |    382 //  ExecuteSingleItemFetchL() | 
|         |    383 //---------------------------------------------------------------------------- | 
|         |    384 void CMsgMailViewerContactMatcher::ExecuteSingleItemFetchL(  | 
|         |    385     TAiwSingleItemSelectionDataV3 aData, | 
|         |    386     const CVPbkContactLinkArray& aLinks ) | 
|         |    387     { | 
|         |    388     CAiwGenericParamList& inParamList = iServiceHandler.InParamListL();     | 
|         |    389     inParamList.AppendL( | 
|         |    390         TAiwGenericParam( EGenericParamContactSelectionData, | 
|         |    391         TAiwVariant( TAiwSingleItemSelectionDataV3Pckg( aData ) ) ) ); | 
|         |    392  | 
|         |    393     //Contacts that matched search | 
|         |    394     HBufC8* packedLinks = aLinks.PackLC(); | 
|         |    395          | 
|         |    396     inParamList.AppendL( TAiwGenericParam( EGenericParamContactLinkArray, | 
|         |    397                                            TAiwVariant( *packedLinks ) ) ); | 
|         |    398  | 
|         |    399     iServiceHandler.ExecuteServiceCmdL( KAiwCmdSelect,  | 
|         |    400                                         inParamList,  | 
|         |    401                                         iServiceHandler.OutParamListL(), | 
|         |    402                                         0, | 
|         |    403                                         this ); | 
|         |    404     CleanupStack::PopAndDestroy( packedLinks );  | 
|         |    405     } | 
|         |    406  | 
|         |    407 // End of File | 
|         |    408  |