messagingappbase/msgavkon/muiu_internal/servicesinternal/src/MuiuContactAddressMatcher.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/msgavkon/muiu_internal/servicesinternal/src/MuiuContactAddressMatcher.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,462 @@
+/*
+* 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:   Searches contact using email address as search filter from address books.
+*
+*/
+
+
+#include "MuiuContactAddressMatcher.h"
+#include <data_caging_path_literals.hrh>    // KDC_RESOURCE_FILES_DIR
+#include <muiu_internal.rsg>                // R_MUIU_PHONENUMBER_MATCH_INTEREST
+#include <eikenv.h>
+#include <coemain.h>
+#include <basched.h>                        // KLeaveExit
+#include <bautils.h>                        // BaflUtils
+#include <contactmatcher.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkContactLinkArray.h>
+#include <MVPbkStoreContact.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <VPbkContactViewFilterBuilder.h>
+#include <MVPbkContactFieldTextData.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <TVPbkFieldVersitProperty.h>
+#include <AiwServiceHandler.h>
+#include <finditemmenu.h>
+#include <e32base.h>
+#include <AknWaitDialog.h>
+#include <aknnotewrappers.h>        // CAknInformationNote
+#include <StringLoader.h>
+
+#include "MuiuMsvUiServiceUtilities.h"
+
+
+
+// Constants 
+// Resource file
+_LIT( KMuiuInternalResourceFileName, "muiu_internal.rsc" );
+
+
+// ---------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::NewL
+// ---------------------------------------------------------------------------
+//
+CMuiuContactAddressMatcher* CMuiuContactAddressMatcher::NewL(
+    CEikonEnv& aEikonEnv )
+    {
+    CMuiuContactAddressMatcher* self =
+        new( ELeave ) CMuiuContactAddressMatcher( aEikonEnv );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+
+    CleanupStack::Pop( self );
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::CMuiuContactAddressMatcher
+// ---------------------------------------------------------------------------
+//
+CMuiuContactAddressMatcher::CMuiuContactAddressMatcher( 
+        CEikonEnv& aEikonEnv ):
+    CActive( EPriorityStandard ),
+    iEikEnv( aEikonEnv ),
+    iResourceOffset( KErrNotFound )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::ConstructL
+// ---------------------------------------------------------------------------
+//
+inline void CMuiuContactAddressMatcher::ConstructL()
+    {
+	iServiceHandler = CAiwServiceHandler::NewL();    
+
+    iContactMatcher = CContactMatcher::NewL( &iEikEnv.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);
+    
+    if ( !iEikEnv.IsResourceAvailableL( R_MUIU_PHONENUMBER_MATCH_INTEREST ) )
+        {
+        TFileName fileName;
+        TParse parse;
+        parse.Set( KMuiuInternalResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL );
+        fileName = parse.FullName();
+        BaflUtils::NearestLanguageFile( iEikEnv.FsSession(), fileName );
+        iResourceOffset = iEikEnv.AddResourceFileL( fileName );
+        }
+    
+    iServiceHandler->AttachL( R_MUIU_PHONENUMBER_MATCH_INTEREST );    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::~CMuiuContactAddressMatcher
+// ---------------------------------------------------------------------------
+//
+CMuiuContactAddressMatcher::~CMuiuContactAddressMatcher()
+    {
+    Cancel();
+    // delete link arrays first to avoid access violations:
+    delete iContactLinks;   
+    delete iChangedLinks;    
+    // doesn't matter really if detaching fails
+    if( iServiceHandler )
+        {
+        TRAP_IGNORE( iServiceHandler->DetachL( R_MUIU_PHONENUMBER_MATCH_INTEREST ) ); 
+        } 
+    delete iContactMatcher;
+    delete iIdle;   
+    delete iServiceHandler;
+    if ( iResourceOffset != KErrNotFound )
+        {
+        iEikEnv.DeleteResourceFile( iResourceOffset );
+        }
+    } 
+    
+// ----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::FindContactL
+// ----------------------------------------------------------------------------
+//
+TBool CMuiuContactAddressMatcher::FindContactL(
+    const TDesC& aMailAddress,
+    TCallBack aCallBack )
+    {
+    if ( !MsvUiServiceUtilities::IsValidEmailAddressL( aMailAddress ) )
+        {
+        return  EFalse;
+        }
+
+    if ( !IsActive() )         
+        {        
+        iCallBack = aCallBack;
+        // reset old data
+        iContactLinks->ResetAndDestroy();
+        iChangedLinks->ResetAndDestroy();        
+        
+        const MVPbkFieldTypeList& fieldTypes = iContactMatcher->FieldTypes();         
+        iContactMatcher->MatchDataL( aMailAddress, 
+                                     fieldTypes, 
+                                     *iContactLinks,
+                                     iStatus );  
+        SetActive();
+        
+        // dialog sets iWaitDialog to NULL when it gets deleted
+        if (!iWaitDialog )
+            {
+            iWaitDialog = new( ELeave ) CAknWaitDialog(
+                ( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ) ), ETrue );
+            }
+        iWaitDialog->ExecuteLD( R_MUIU_MATCHING_ADDRESS_WAIT_NOTE );
+        }
+    else
+        {
+        User::Leave( KErrInUse );
+        }
+    return ETrue;
+    }    
+
+    
+//----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::GetAddressL()
+// Returns NULL pointer if no data is found
+//----------------------------------------------------------------------------
+HBufC* CMuiuContactAddressMatcher::GetAddressL() 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 );
+        }        
+    iChangedLinks->ResetAndDestroy();        
+    return text;
+    }
+//----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::GetNameL()
+// Returns NULL pointer if no data is found
+//----------------------------------------------------------------------------
+HBufC* CMuiuContactAddressMatcher::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 );
+        }
+    iContactLinks->ResetAndDestroy();    
+    return name;
+    }       
+    
+// ----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::DoCancel()
+// From CActive
+// ----------------------------------------------------------------------------
+//
+void CMuiuContactAddressMatcher::DoCancel()
+    {
+    if ( iContactMatcher )
+        {
+        iContactMatcher->CancelOperation();
+        }
+    }
+    
+// ----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::RunL()
+// From CActive
+// ----------------------------------------------------------------------------
+//
+void CMuiuContactAddressMatcher::RunL()
+    {        
+    // We need to delete excess matches, otherwise Fetch AIW may
+    // continue with next match when user presses Cancel.
+    DeleteExcessMatchesL( *iContactLinks );
+    if( iContactLinks->Count() == 0)
+        {
+        HBufC* string = StringLoader::LoadLC( R_MUIU_QTN_PHOB_NOTE_NO_NUMBER, &iEikEnv );
+        CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+        note->ExecuteLD( *string );
+        CleanupStack::PopAndDestroy( string ); 
+        // Deleting wait dialog in the beginning of the function causes
+        // info note to flicker
+        if ( iWaitDialog )
+            {
+            iWaitDialog->ProcessFinishedL(); // deletes the dialog
+            }
+        
+        //We can't call iCallBack straight away,
+        //because it triggers events that cause KErrInUse leave.
+        iIdle->Start(iCallBack);
+        }
+    else
+        {
+        if ( iWaitDialog )
+            {
+            iWaitDialog->ProcessFinishedL(); // deletes the dialog
+            }
+        CVPbkFieldTypeSelector* filter = CreateFilterLC( );
+        TAiwSingleItemSelectionDataV3 selectionData = SelectionData( *filter);        
+        ExecuteSingleItemFetchL( selectionData, *iContactLinks );    
+        CleanupStack::PopAndDestroy( filter );
+        }
+    }
+	
+// ----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::RunError
+// From CActive
+// ----------------------------------------------------------------------------
+//
+TInt CMuiuContactAddressMatcher::RunError( TInt aError )
+    {      
+    if( aError == KLeaveExit )
+        {
+        return aError;    
+        }
+    else
+        {
+        return KErrNone;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMuiuContactAddressMatcher::HandleNotifyL
+// From MAiwNotifyCallback
+// ----------------------------------------------------------------------------
+//
+TInt CMuiuContactAddressMatcher::HandleNotifyL(
+    TInt /*aCmdId*/,
+    TInt aEventId,
+    CAiwGenericParamList& aEventParamList,
+    const CAiwGenericParamList& /*aInParamList*/ )
+    {
+    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;
+                }
+            else
+                {
+                retVal = KErrArgument;    
+                }
+            } 
+        }
+    //Notify waiter always, even if error.
+    //We can't call iCallBack straight away,
+    //because it triggers events that cause KErrInUse leave.
+    iIdle->Start(iCallBack);
+    return retVal;
+    }
+
+//----------------------------------------------------------------------------
+//  CMuiuContactAddressMatcher::DeleteExcessMatches()
+//----------------------------------------------------------------------------
+void CMuiuContactAddressMatcher::DeleteExcessMatchesL(
+    CVPbkContactLinkArray& aLinks ) const
+    {
+    // It may be that first contact has not phone number but others has.
+    TInt count = aLinks.Count();
+    // Search for first contact that has phone number
+    for (TInt i=0 ; i < count ; i++ )
+        {
+        MVPbkStoreContact* storeContact = NULL;
+        const MVPbkContactLink& link = aLinks.At( i );
+        iContactMatcher->GetStoreContactL( link, &storeContact ); 
+        storeContact->PushL();   
+        if (    storeContact
+            &&  iContactMatcher->ContactHasFieldOfTypeL( EAiwPhoneNumberSelect, *storeContact ) == KErrNotFound )
+            {
+            aLinks.Delete( i-- );
+            count = aLinks.Count();
+            }
+        else if ( !storeContact )
+            {
+            // is this possible?
+            aLinks.Delete( i-- );
+            count = aLinks.Count();
+            }
+        else
+            {
+            CleanupStack::PopAndDestroy( storeContact );
+            break;
+            }
+        CleanupStack::PopAndDestroy( storeContact );
+        }
+     
+    TInt k( aLinks.Count() - 1 );
+    // delete all but link at index 0
+    while ( k > 0 )
+        {
+        aLinks.Delete( k-- );
+        }
+    }
+
+//----------------------------------------------------------------------------
+//  CMuiuContactAddressMatcher::CreateFilterLC()
+//----------------------------------------------------------------------------
+CVPbkFieldTypeSelector* CMuiuContactAddressMatcher::CreateFilterLC( ) const
+    {
+    CVPbkContactManager& contactMgr = iContactMatcher->GetContactManager();
+    CVPbkFieldTypeSelector* contactViewFilter =
+        CVPbkFieldTypeSelector::NewL( contactMgr.FieldTypes() );
+    CleanupStack::PushL( contactViewFilter );
+
+    // Append the filter object with suitable criteria
+    VPbkContactViewFilterBuilder::BuildContactViewFilterL(
+        *contactViewFilter, EVPbkContactViewFilterPhoneNumber, contactMgr );
+    
+    //VPbkContactViewFilterBuilder::BuildContactViewFilterL(
+    //    *contactViewFilter, EVPbkContactViewFilterEmail, contactMgr );
+        
+    return contactViewFilter;
+    }
+
+//----------------------------------------------------------------------------
+//  CMuiuContactAddressMatcher::SelectionData()
+//----------------------------------------------------------------------------
+TAiwSingleItemSelectionDataV3
+CMuiuContactAddressMatcher::SelectionData(
+    CVPbkFieldTypeSelector& aFilter ) const
+    {
+    TAiwAddressSelectType addressSelectType( EAiwAllItemsSelect );
+    addressSelectType = EAiwPhoneNumberSelect;
+
+    TAiwSingleItemSelectionDataV3 selData;
+    selData.SetAddressSelectType( addressSelectType )
+           .SetFetchFilter( &aFilter );
+    return selData;
+    }
+
+//----------------------------------------------------------------------------
+//  CMuiuContactAddressMatcher::ExecuteSingleItemFetchL()
+//----------------------------------------------------------------------------
+void CMuiuContactAddressMatcher::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
+