phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,915 @@
+/*
+* Copyright (c) 2009-2009 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:  Implementation of MyCard
+*
+*/
+
+
+#include "ccappmycard.h"
+#include "ccappmycardcommon.h"
+
+// System
+#include <coemain.h>
+#include <f32file.h>
+#include <avkon.hrh>
+#include <eikenv.h>
+#include <aknViewAppUi.h>
+
+// Virtual phonebook
+#include <CVPbkContactManager.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <MVPbkContactStoreProperties.h>
+#include <VPbkContactStoreUris.h>
+#include <MVPbkContactStoreList.h>
+#include <MVPbkContactStore.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <MVPbkContactStore2.h>
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkStoreContact2.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactLink.h>
+#include <VPbkEng.rsg>
+#include <MVPbkFieldType.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkContactFieldUriData.h>
+
+// Phonebook 2
+#include <CPbk2StorePropertyArray.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2StoreSpecificFieldPropertyArray.h>
+#include <CPbk2FieldPropertyArray.h>
+#include <CPbk2SortOrderManager.h>
+#include <Pbk2ContactNameFormatterFactory.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <CPbk2ApplicationServices.h>
+#include <CPbk2StoreManager.h>
+#include <CPbk2StoreConfiguration.h>
+#include <CPbk2ContactEditorDlg.h>
+#include <MVPbkBaseContactField.h>
+
+// internal
+#include "ccappmycardplugin.h"
+#include <ccappmycardpluginrsc.rsg>
+
+/**
+ * Helper class for making delayed callbacks
+ * @see public methods of CTimer for help
+ */
+class CTimerCallBack : public CTimer
+    {
+public:
+    /**
+     * @param aCallBack called when CTimer is due to run
+     * @param aPriority priority of CTimer
+     */
+    static CTimerCallBack* NewL(
+        const TCallBack& aCallBack,
+        CActive::TPriority aPriority = CActive::EPriorityIdle );
+
+protected: // From CActive
+    void RunL();
+    TInt RunError( TInt /*aError*/ );
+
+protected:
+    CTimerCallBack( const TCallBack& aCallBack, CActive::TPriority aPriority );
+
+private: // data
+    TCallBack iCallBack;
+    };
+
+
+// ---------------------------------------------------------------------------
+// CTimerCallBack::NewL
+// ---------------------------------------------------------------------------
+//
+CTimerCallBack* CTimerCallBack::NewL(
+    const TCallBack& aCallBack,
+    CActive::TPriority aPriority )
+    {
+    CTimerCallBack* self = new(ELeave) CTimerCallBack( aCallBack, aPriority );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CTimerCallBack::RunL
+// ---------------------------------------------------------------------------
+//
+CTimerCallBack::CTimerCallBack( const TCallBack& aCallBack, CActive::TPriority aPriority ) :
+    CTimer( aPriority ), iCallBack( aCallBack )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CTimerCallBack::RunL
+// ---------------------------------------------------------------------------
+//
+void CTimerCallBack::RunL()
+    {
+    iCallBack.CallBack();
+    }
+
+// ---------------------------------------------------------------------------
+// CTimerCallBack::RunError
+// ---------------------------------------------------------------------------
+//
+TInt CTimerCallBack::RunError( TInt /*aError*/ )
+    {
+    // Leaves in RunL are ignored
+    return KErrNone;
+    }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::NewL
+// ---------------------------------------------------------------------------
+//
+CCCAppMyCard* CCCAppMyCard::NewL( CCCAppMyCardPlugin& aPlugin, RFs* aFs )
+    {
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::NewL()"));
+
+    CCCAppMyCard* self = new ( ELeave ) CCCAppMyCard( aPlugin );
+    CleanupStack::PushL( self );
+    self->ConstructL(aFs);
+    CleanupStack::Pop( self );
+
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::NewL()"));
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::~CCCAppMyCard
+// ---------------------------------------------------------------------------
+//
+CCCAppMyCard::~CCCAppMyCard()
+    {
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::~CCCAppMyCard()"));
+
+    delete iOperation;
+    delete iFetchOperation;
+    delete iMyCard;
+    delete iPresentationContact;
+    delete iMyCardContact;
+    delete iFieldProperties;
+    delete iSpecificFieldProperties;
+
+    iObservers.Reset();
+
+    if( iAppServices )
+	   {
+	   iAppServices->StoreManager().DeregisterStoreEvents(*this);
+	   }
+	Release(iAppServices);
+
+	delete iCloseCallBack;
+    delete iCreateCallBack;
+    delete iDlgCloseCallBack;
+    delete iStoreCallBack;
+
+	CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::~CCCAppMyCard()"));
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::CCCAppMyCard()
+// ---------------------------------------------------------------------------
+//
+inline CCCAppMyCard::CCCAppMyCard( CCCAppMyCardPlugin& aPlugin )
+: iPlugin( aPlugin ), iEvent( MMyCardObserver::EEventContactLoaded )
+
+	{
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ConstructL
+// ---------------------------------------------------------------------------
+//
+inline void CCCAppMyCard::ConstructL( RFs* /*aFs*/ )
+    {
+    // Get the AppServices instance
+	iAppServices = CPbk2ApplicationServices::InstanceL();
+
+	CPbk2StoreManager& storeManager = iAppServices->StoreManager();
+	iVPbkContactManager = &iAppServices->ContactManager();
+	storeManager.RegisterStoreEventsL( *this );
+	storeManager.EnsureDefaultSavingStoreIncludedL();
+
+	iCloseCallBack = new(ELeave) CAsyncCallBack(
+        TCallBack( CloseCcaL, this ), CActive::EPriorityIdle );
+    iCreateCallBack = new(ELeave) CAsyncCallBack(
+        TCallBack( CreateMyCardContact, this ), CActive::EPriorityHigh );
+    iDlgCloseCallBack = new(ELeave) CAsyncCallBack(
+        TCallBack( ExitDlgL, this ), CActive::EPriorityHigh );
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::PresentationContactL
+// ---------------------------------------------------------------------------
+//
+CPbk2PresentationContact& CCCAppMyCard::PresentationContactL()
+    {
+    if( !iPresentationContact )
+        {
+        if( !iMyCardContact )
+            {
+            // own contact not loaded
+            User::Leave( KErrNotReady );
+            }
+
+        const MVPbkContactStoreProperties& storeProperties =
+            iMyCardContact->ParentStore().StoreProperties();
+        const MVPbkFieldTypeList& supportedFieldTypes =
+            storeProperties.SupportedFields();
+
+        if( !iFieldProperties )
+            {
+            iFieldProperties = CPbk2FieldPropertyArray::NewL(
+                supportedFieldTypes, iVPbkContactManager->FsSession() );
+            }
+
+        // Create a field property list of the supported
+        // field types of the used store
+        CPbk2StorePropertyArray* pbk2StoreProperties = CPbk2StorePropertyArray::NewL();
+        CleanupStack::PushL( pbk2StoreProperties );
+
+        if( !iSpecificFieldProperties )
+            {
+            iSpecificFieldProperties = CPbk2StoreSpecificFieldPropertyArray::NewL(
+                *iFieldProperties,
+                *pbk2StoreProperties,
+                supportedFieldTypes,
+                iMyCardContact->ParentStore() );
+            }
+
+        iPresentationContact = CPbk2PresentationContact::NewL(
+            *iMyCardContact, *iSpecificFieldProperties );
+
+        CleanupStack::PopAndDestroy( pbk2StoreProperties );
+        }
+
+    return *iPresentationContact;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::StoreContact
+// ---------------------------------------------------------------------------
+//
+MVPbkStoreContact& CCCAppMyCard::StoreContact()
+    {
+    __ASSERT_ALWAYS( iMyCardContact, Panic( ECCAppMyCardPanicContactNotReady ) );
+    return *iMyCardContact;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactManager
+// ---------------------------------------------------------------------------
+//
+CVPbkContactManager& CCCAppMyCard::ContactManager()
+    {
+    return *iVPbkContactManager;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::IsContactLinkReady
+// ---------------------------------------------------------------------------
+//
+TBool CCCAppMyCard::IsContactLinkReady() const
+    {
+    return iMyCard != NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactLink
+// ---------------------------------------------------------------------------
+//
+MVPbkContactLink& CCCAppMyCard::ContactLink()
+    {
+    __ASSERT_ALWAYS( iMyCard, Panic( ECCAppMyCardPanicLinkNotReady ) );
+    return *iMyCard;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::AddObserverL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::AddObserverL( MMyCardObserver* aObserver )
+    {
+    if( aObserver )
+        {
+        TInt index = iObservers.Find( aObserver );
+        if( index == KErrNotFound )
+            {
+            iObservers.AppendL( aObserver );
+            if( iMyCardContact )
+                {
+                aObserver->MyCardEventL( MMyCardObserver::EEventContactLoaded );
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::RemoveObserver
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::RemoveObserver( MMyCardObserver* aObserver )
+    {
+    TInt index = iObservers.Find( aObserver );
+    if( index != KErrNotFound )
+        {
+        iObservers.Remove( index );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::SetLinkL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::SetLinkL( const MVPbkContactLink& aLink )
+    {
+    MVPbkContactLink* link = aLink.CloneLC();
+    CleanupStack::Pop(); // link
+    delete iMyCard;
+    iMyCard = link;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::FetchMyCardL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::FetchMyCardL()
+    {
+    if( !iStoreCallBack )
+        {
+        if ( !iMyCard && iForceCreateMyCard )
+            {
+            // Disable LSK if new contact will be created
+            // to avoid opening wrong menu
+            iPlugin.EnableOptionsMenu( EFalse );
+            }
+        
+        iStoreCallBack = CTimerCallBack::NewL(
+            TCallBack( &CCCAppMyCard::OpenStoresL, this ) );
+
+        // 200 ms delay before open. Used to prevent system jamming before the
+        // UI is drawn, so that launching of mycard feels a lot faster.
+        iStoreCallBack->After( 200e3 );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ForceCreateMyCard
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ForceCreateMyCard()
+    {
+    iForceCreateMyCard = ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::HeaderControlBlocked
+// ---------------------------------------------------------------------------
+//
+TBool CCCAppMyCard::HeaderControlBlocked()
+    {
+    return iDialogIsRunning;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::NotifyObservers
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::NotifyObservers( MMyCardObserver::TEvent aEvent ) const
+    {
+    TInt count = iObservers.Count();
+    for( TInt i = 0; i < count; i++ )
+        {
+        TRAPD( err, iObservers[i]->MyCardEventL( aEvent ) );
+        if( err )
+            {
+            CCA_DP(KMyCardLogFile,
+                CCA_L("<-CCCAppMyCard::NotifyObservers notify error (%d)"), err );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::LoadContact
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::LoadContact()
+    {
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::LoadContact()"));
+
+    if( !iFetchOperation && iMyCard )
+        {
+        TRAPD( err, iFetchOperation =
+            iVPbkContactManager->RetrieveContactL( *iMyCard, *this ) );
+        if( err )
+            {
+            // Cannot load own contact from VPbk
+            CCA_DP(KMyCardLogFile,
+                CCA_L("  CCCAppMyCard::LoadContact load error = %d"), err );
+
+            iPlugin.HandleError( err );
+            }
+        }
+
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::LoadContact()"));
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::StoreReady
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::StoreReady( MVPbkContactStore& aContactStore )
+	{
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::StoreReady()"));
+
+	const MVPbkContactStoreProperties& storeProperties =
+		aContactStore.StoreProperties();
+	TVPbkContactStoreUriPtr uri = storeProperties.Uri();
+	TInt isSame = uri.Compare( VPbkContactStoreUris::DefaultCntDbUri(),
+		TVPbkContactStoreUriPtr::EContactStoreUriAllComponents );
+
+	if( isSame != 0 )
+		{
+		return;
+		}
+
+    if( iMyCard )
+        {
+        // if link is already available then use that
+        LoadContact();
+        }
+    else if( iForceCreateMyCard )
+        {
+        // launch editor because we don't have mycard
+        iCreateCallBack->Call();
+        }
+    else
+        {
+        // MyCard is always created to contact model. So we check that event was
+        // from the correct store.
+		delete iOperation;
+		iOperation = NULL;
+
+		MVPbkContactStore2* phoneStoreExtension =
+			static_cast<MVPbkContactStore2*>(aContactStore.ContactStoreExtension(KMVPbkContactStoreExtension2Uid));
+		if ( phoneStoreExtension )
+			{
+			TRAPD( err, iOperation = phoneStoreExtension->OwnContactLinkL(*this) );
+			if( err )
+				{
+                iPlugin.HandleError( err );
+				}
+			}
+        }
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::StoreReady()"));
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::StoreUnavailable
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::StoreUnavailable(
+		MVPbkContactStore& /*aContactStore*/,
+        TInt /*aReason*/)
+	{
+    CCA_DP(KMyCardLogFile, CCA_L("  CCCAppMyCard::StoreUnavailable()"));
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::HandleStoreEventL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::HandleStoreEventL(
+        MVPbkContactStore& /*aContactStore*/,
+        TVPbkContactStoreEvent aStoreEvent )
+	{
+    CCA_DP(KMyCardLogFile,
+        CCA_L("->CCCAppMyCard::HandleStoreEventL Event = %d"),
+        aStoreEvent.iEventType );
+
+    if( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactChanged )
+        {
+        if( iMyCard && aStoreEvent.iContactLink->IsSame( *iMyCard ) )
+            {
+            // Own contact has changed. Reload contact to update content
+            iEvent = MMyCardObserver::EEventContactChanged;
+            LoadContact();
+            }
+        }
+    else if( aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactDeleted )
+        {
+        if( iMyCard && aStoreEvent.iContactLink->IsSame( *iMyCard ) )
+            {
+            if( !iDialogIsRunning )
+                {
+                CEikAppUi* aEikAppUi = CEikonEnv::Static()->EikAppUi();
+                CAknViewAppUi* appUi = static_cast<CAknViewAppUi*> ( aEikAppUi );
+                appUi->RunAppShutter();
+                }
+            }
+        }
+
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::HandleStoreEventL()") );
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::VPbkSingleContactLinkOperationComplete
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::VPbkSingleContactLinkOperationComplete(
+        MVPbkContactOperationBase& /*aOperation*/,
+        MVPbkContactLink* aLink )
+	{
+    CCA_DP(KMyCardLogFile,
+        CCA_L("->CCCAppMyCard::VPbkSingleContactLinkOperationComplete()") );
+
+    delete iMyCard;
+	iMyCard = aLink;
+
+	LoadContact();
+
+	CCA_DP(KMyCardLogFile,
+        CCA_L("<-CCCAppMyCard::VPbkSingleContactLinkOperationComplete()") );
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::VPbkSingleContactLinkOperationFailed
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::VPbkSingleContactLinkOperationFailed(
+        MVPbkContactOperationBase& /*aOperation*/,
+        TInt aError )
+	{
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("->CCCAppMyCard::VPbkSingleContactLinkOperationFailed error = %d"),
+        aError );    
+    
+	delete iMyCard;
+	iMyCard = NULL;
+	TInt error(aError);
+	// if link is not found
+	if( KErrNotFound == error )
+	    {
+        // launch contact editor
+        iCreateCallBack->Call();
+        }
+	if( error != KErrNone && error != KErrNotFound )
+	    {
+        iPlugin.HandleError( error );
+	    }
+	
+	CCA_DP(KMyCardLogFile, 
+        CCA_L("<-CCCAppMyCard::VPbkSingleContactLinkOperationFailed()"));    
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::CreateMyCardContact
+// ---------------------------------------------------------------------------
+//
+TInt CCCAppMyCard::CreateMyCardContact( TAny* aPtr )
+	{
+	CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
+	TRAPD( err, self->LaunchContactEditorL( TPbk2ContactEditorParams::ENewContact | 
+        TPbk2ContactEditorParams::EOwnContact ) );
+			
+	if( err != KErrNone )
+        {        
+        self->iPlugin.HandleError( err );
+        
+        if( !self->iMyCard )
+            {
+            self->iCloseCallBack->Call();
+            }
+        else
+            {
+            self->LoadContact();
+            }
+        }
+	
+	return err;
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::LaunchContactEditorL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::LaunchContactEditorL( TUint32 aFlags )
+	{
+	// default contact store
+	MVPbkContactStore* store = iVPbkContactManager->ContactStoresL().Find( 
+        VPbkContactStoreUris::DefaultCntDbUri() );
+	
+	MVPbkBaseContactField* field = NULL;
+	MVPbkStoreContact* contact = NULL;
+	if( aFlags & TPbk2ContactEditorParams::ENewContact )
+		{
+		// create empty store contact and launch editor
+		contact = store->CreateNewContactLC();
+		CleanupStack::Pop(); // contact, whose ownership is taken away
+		}
+	else if( aFlags & TPbk2ContactEditorParams::EModified )
+		{
+        if( iFocusedFieldIndex >= KErrNone )
+            {
+            // focused field
+            field = iMyCardContact->Fields().FieldAtLC( iFocusedFieldIndex ); 
+            }
+        				
+		// pass current store contact, ownership is taken
+		contact = iMyCardContact;
+		iMyCardContact = NULL;		
+		delete iPresentationContact;
+		iPresentationContact = NULL;		
+		}
+	// params for the editor
+	TPbk2ContactEditorParams params( aFlags, field, NULL, this );
+	
+	// pass custom title text
+    if ( contact )
+        {
+        HBufC* title = CCoeEnv::Static()->AllocReadResourceLC( 
+            R_QTN_CCA_MC_TITLE_EDIT_MY_CARD );
+        // ownership of the title is passed
+        CPbk2ContactEditorDlg* dlg = CPbk2ContactEditorDlg::NewL( params, contact, 
+            *this, iAppServices, title, R_SOCIAL_PHONEBOOK_FIELD_PROPERTIES );
+        CleanupStack::Pop( title );
+        iEditorEliminator = dlg;
+        dlg->ResetWhenDestroyed( &iEditorEliminator );
+        
+        iDialogIsRunning = ETrue;
+        dlg->ExecuteLD();
+        
+        if( aFlags & TPbk2ContactEditorParams::ENewContact )
+            {
+            // Enable LSK in my card view after edit dialog is opened
+            iPlugin.EnableOptionsMenu( ETrue );
+            }
+        }
+	
+	// if field was created, destroy it
+	if( field )
+		{
+		CleanupStack::PopAndDestroy( field );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::EditContactL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::EditContactL( TInt aFocusedFieldIndex )
+	{
+	// if exists
+	if( iMyCardContact )
+		{
+		// store focused index
+		iFocusedFieldIndex = aFocusedFieldIndex;
+		iMyCardContact->LockL( *this );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactEditingComplete
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactEditingComplete( MVPbkStoreContact* aEditedContact )
+	{
+    // create link of mycard
+    MVPbkContactLink* link = NULL;       
+    
+    TRAPD( err,
+        {
+        link = aEditedContact->CreateLinkLC(); 
+        
+        if( link )
+            {
+            CleanupStack::Pop(); //link
+            }
+        } );
+        
+    delete aEditedContact; // ignore given contact
+    
+    if( link && err == KErrNone )
+        {
+        
+        delete iMyCard;
+        iMyCard = link;
+        
+        // reload mycard to get rid of the empty template fields
+        LoadContact();
+        }
+    else if( !iMyCard )
+        {
+        iCloseCallBack->Call();
+        }               
+    
+    iDialogIsRunning = EFalse;
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactEditingDeletedContact
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactEditingDeletedContact( 
+    MVPbkStoreContact* aEditedContact )
+	{
+	// Editing was cancelled, go back to phonebook
+	delete aEditedContact;	
+	iCloseCallBack->Call();
+	iDialogIsRunning = EFalse;
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactEditingAborted
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactEditingAborted()
+	{
+    iDialogIsRunning = EFalse;
+	// Editing was aborted -> move to pb2
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::OkToExitL
+// ---------------------------------------------------------------------------
+//
+TBool CCCAppMyCard::OkToExitL( TInt /*aCommandId*/ )
+    {
+    // Handle exit via callback. Calls CCCAppMyCard::ExitDlg.
+    // Dialog's exit is handled this way to make the address selector's 
+    // exit work as it should.
+    iDlgCloseCallBack->Call();
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::CloseCcaL
+// ---------------------------------------------------------------------------
+//
+TInt CCCAppMyCard::CloseCcaL( TAny* aPtr )
+	{
+	CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
+	// if fields are empty, and user pushes "Done" or "Exit" this function is 
+	// called. Card is not created -> goto pbk2
+	self->DoCloseCCaL();
+	return KErrNone;
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::CloseCcaL
+// ---------------------------------------------------------------------------
+//
+TInt CCCAppMyCard::ExitDlgL( TAny* aPtr )
+    {
+    CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
+    if( self->iEditorEliminator )
+        {
+        self->iEditorEliminator->RequestExitL( EAknCmdExit );
+        }
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::OpenStoresL
+// ---------------------------------------------------------------------------
+//
+TInt CCCAppMyCard::OpenStoresL( TAny* aPtr )
+    {
+    CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
+    self->iAppServices->StoreManager().OpenStoresL();
+    return 0;
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::DoCloseCCaL
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::DoCloseCCaL()
+	{
+	// close the plugin
+	iPlugin.HandleCommandL( EAknSoftkeyBack );
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactOperationCompleted( TContactOpResult aResult )
+    {
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::ContactOperationCompleted()"));   
+    
+    // contact locked complete for editing
+    if( aResult.iOpCode == MVPbkContactObserver::EContactLock )
+    	{
+    	TRAPD( err, LaunchContactEditorL( TPbk2ContactEditorParams::EModified | 
+            TPbk2ContactEditorParams::EOwnContact) );
+    	    	    	
+    	if( err == KLeaveExit )
+    	    {                                                                           
+            iCloseCallBack->Call();
+            }    	    
+    	else if( err != KErrNone )
+			{
+            LoadContact();
+            iPlugin.HandleError( err );
+            if( !iMyCard )
+                {
+                iCloseCallBack->Call();
+                }                
+			}
+    	}    
+    else if( aResult.iOpCode == MVPbkContactObserver::EContactDelete )
+    	{
+		iCloseCallBack->Call();
+    	}   
+        
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::ContactOperationCompleted()")); 
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactOperationFailed
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactOperationFailed(
+    TContactOp aOpCode, TInt aErrorCode, TBool /*aErrorNotified*/ )    
+    {
+    if ( aErrorCode != KErrNone )          
+        {                                  
+        iPlugin.HandleError( aErrorCode );    
+        }        
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::VPbkSingleContactOperationComplete
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::VPbkSingleContactOperationComplete(
+        MVPbkContactOperationBase& /*aOperation*/,
+        MVPbkStoreContact* aContact )
+    {
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("->CCCAppMyCard::VPbkSingleContactOperationComplete()") );    
+    
+    delete iFetchOperation;
+    iFetchOperation = NULL;
+    
+    delete iMyCardContact;
+    iMyCardContact = aContact;
+    
+    // also delete presentation contact, since it points to old store contact
+    delete iPresentationContact;
+    iPresentationContact = NULL;
+    
+    NotifyObservers( iEvent );
+
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("<-CCCAppMyCard::VPbkSingleContactOperationComplete()"));    
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::VPbkSingleContactOperationFailed
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::VPbkSingleContactOperationFailed(
+        MVPbkContactOperationBase& /*aOperation*/, 
+        TInt aError )
+    {
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("->CCCAppMyCard::VPbkSingleContactOperationFailed error = %d"),
+        aError );    
+    
+    delete iFetchOperation;
+    iFetchOperation = NULL;
+
+    delete iOperation;
+    iOperation = NULL;
+    
+    if( aError != KErrNone )
+        {
+        iPlugin.HandleError( aError );
+        }
+
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("<-CCCAppMyCard::VPbkSingleContactOperationFailed()") );    
+    }
+
+// End of File