diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp --- /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 +#include +#include + +// Virtual phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Phonebook 2 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// internal +#include "ccappmycardplugin.h" +#include + + +// ======== 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(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( 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( 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