phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,654 @@
+/*
+* 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>
+
+// 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>
+
+
+// ======== 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;
+
+	CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::~CCCAppMyCard()"));
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::CCCAppMyCard()
+// ---------------------------------------------------------------------------
+//
+inline CCCAppMyCard::CCCAppMyCard( CCCAppMyCardPlugin& aPlugin )
+: iPlugin( aPlugin )
+	{
+    }
+
+// ---------------------------------------------------------------------------
+// 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();
+	// open stores
+	storeManager.OpenStoresL();
+	
+	iCloseCallBack = new(ELeave) CAsyncCallBack( 
+        TCallBack( CloseCcaL, this ), CActive::EPriorityIdle );	
+    iCreateCallBack = new(ELeave) CAsyncCallBack( 
+        TCallBack( CreateMyCardContact, 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::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()"));    
+
+    delete iFetchOperation;
+    iFetchOperation = NULL;
+    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 ); 
+
+        // TODO: How is this handled. show error on UI?
+        }
+    
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::LoadContact()"));    
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::StoreReady
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::StoreReady( MVPbkContactStore& aContactStore )
+	{
+    CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::StoreReady()"));
+    
+    // MyCard is always created to contact model. So we check that event was
+    // from the correct store.
+    const MVPbkContactStoreProperties& storeProperties = 
+				aContactStore.StoreProperties();
+    TVPbkContactStoreUriPtr uri = storeProperties.Uri();
+    TInt isSame = uri.Compare( VPbkContactStoreUris::DefaultCntDbUri(), 
+    		TVPbkContactStoreUriPtr::EContactStoreUriAllComponents );
+	if( isSame == 0 )
+		{				
+		delete iOperation;
+		iOperation = NULL;
+		
+		MVPbkContactStore2* phoneStoreExtension =
+			static_cast<MVPbkContactStore2*>(aContactStore.ContactStoreExtension(KMVPbkContactStoreExtension2Uid));
+		if ( phoneStoreExtension )
+			{
+			TRAPD( err, iOperation = phoneStoreExtension->OwnContactLinkL(*this) );
+			if( err )
+				{
+				// TODO: how is this handled?
+				}
+			}
+		}
+    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
+            LoadContact();
+            }
+        }
+
+    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 )
+	    {
+	    // TODO handle 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 ) );
+	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 )
+		{
+		// focused field
+		field = iMyCardContact->Fields().FieldAtLC( iFocusedFieldIndex );
+		// pass current store contact, ownership is taken
+		contact = iMyCardContact;
+		iMyCardContact = NULL;
+		}
+	// params for the editor
+	TPbk2ContactEditorParams params( aFlags, field, NULL, NULL );
+	
+	// pass custom title text
+	HBufC* title = CCoeEnv::Static()->AllocReadResourceLC( R_QTN_MYCARD_TITLE );
+	// ownership of the title is passed
+	CPbk2ContactEditorDlg* dlg =
+		CPbk2ContactEditorDlg::NewL( params, contact, *this, iAppServices, title,  
+        R_SOCIAL_PHONEBOOK_FIELD_PROPERTIES );
+	CleanupStack::Pop( title );
+	dlg->ExecuteLD();
+	
+	// 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 )
+	{
+    // My Card modifications are handled in HandleStoreEventL. Editor complete
+    // event is only interesting if we don't yet have mycard at all. Meaning
+    // it was just created.
+    
+    if( !iMyCard )
+        {
+        TRAPD( err, iMyCard = aEditedContact->CreateLinkLC();   
+            CleanupStack::Pop(); ); //link
+        if( err )
+            {
+            // TODO handle error 
+            }
+        else
+            {
+            // reload contact to get rid of the template(empty) fields. 
+            LoadContact();
+            }
+        }
+    delete aEditedContact; // ignore given contact
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactEditingDeletedContact
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactEditingDeletedContact( 
+    MVPbkStoreContact* aEditedContact )
+	{
+	// Editing was cancelled, go back to phonebook
+	delete aEditedContact;	
+	iCloseCallBack->Call();
+	}
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactEditingAborted
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactEditingAborted()
+	{
+	// Editing was aborted -> move to pb2
+	}
+
+// ---------------------------------------------------------------------------
+// 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::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 != KErrNone )
+			{
+			//TODO handle errors
+			}
+    	}    
+    else if( aResult.iOpCode == MVPbkContactObserver::EContactDelete )
+    	{
+		iCloseCallBack->Call();
+    	}
+    else
+    	{
+    	//TODO handle errors
+    	}
+        
+    CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::ContactOperationCompleted()")); 
+    }
+
+// ---------------------------------------------------------------------------
+// CCCAppMyCard::ContactOperationFailed
+// ---------------------------------------------------------------------------
+//
+void CCCAppMyCard::ContactOperationFailed(
+    TContactOp /*aOpCode*/, TInt /*aErrorCode*/, TBool /*aErrorNotified*/)    
+    {
+    // TODO handle error
+    }
+
+// ---------------------------------------------------------------------------
+// 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( MMyCardObserver::EEventContactLoaded );
+
+    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 iOperation;
+    iOperation = NULL;
+    
+    // TODO: How to handle loading error?
+
+    CCA_DP(KMyCardLogFile, 
+        CCA_L("<-CCCAppMyCard::VPbkSingleContactOperationFailed()") );    
+    }
+
+// End of File