--- a/phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp Fri Mar 12 15:41:25 2010 +0200
+++ b/phonebookui/Phonebook2/ccapplication/ccamycardplugin/src/ccappmycard.cpp Mon Mar 15 12:39:26 2010 +0200
@@ -23,6 +23,8 @@
#include <coemain.h>
#include <f32file.h>
#include <avkon.hrh>
+#include <eikenv.h>
+#include <aknViewAppUi.h>
// Virtual phonebook
#include <CVPbkContactManager.h>
@@ -50,15 +52,87 @@
#include <CPbk2SortOrderManager.h>
#include <Pbk2ContactNameFormatterFactory.h>
#include <MPbk2ContactNameFormatter.h>
-#include <CPbk2ApplicationServices.h>
+#include <CPbk2ApplicationServices.h>
#include <CPbk2StoreManager.h>
-#include <CPbk2StoreConfiguration.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 ========
@@ -69,12 +143,12 @@
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;
}
@@ -94,7 +168,7 @@
delete iMyCardContact;
delete iFieldProperties;
delete iSpecificFieldProperties;
-
+
iObservers.Reset();
if( iAppServices )
@@ -102,10 +176,11 @@
iAppServices->StoreManager().DeregisterStoreEvents(*this);
}
Release(iAppServices);
-
+
delete iCloseCallBack;
delete iCreateCallBack;
delete iDlgCloseCallBack;
+ delete iStoreCallBack;
CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::~CCCAppMyCard()"));
}
@@ -115,7 +190,8 @@
// ---------------------------------------------------------------------------
//
inline CCCAppMyCard::CCCAppMyCard( CCCAppMyCardPlugin& aPlugin )
-: iPlugin( aPlugin )
+: iPlugin( aPlugin ), iEvent( MMyCardObserver::EEventContactLoaded )
+
{
}
@@ -127,19 +203,17 @@
{
// 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 );
- iDlgCloseCallBack = new(ELeave) CAsyncCallBack(
+
+ 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 );
}
@@ -156,23 +230,23 @@
// 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(
@@ -182,12 +256,12 @@
iMyCardContact->ParentStore() );
}
- iPresentationContact = CPbk2PresentationContact::NewL(
+ iPresentationContact = CPbk2PresentationContact::NewL(
*iMyCardContact, *iSpecificFieldProperties );
-
+
CleanupStack::PopAndDestroy( pbk2StoreProperties );
}
-
+
return *iPresentationContact;
}
@@ -243,7 +317,7 @@
iObservers.AppendL( aObserver );
if( iMyCardContact )
{
- aObserver->MyCardEventL( MMyCardObserver::EEventContactLoaded );
+ aObserver->MyCardEventL( MMyCardObserver::EEventContactLoaded );
}
}
}
@@ -263,6 +337,44 @@
}
// ---------------------------------------------------------------------------
+// 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 )
+ {
+ 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::NotifyObservers
// ---------------------------------------------------------------------------
//
@@ -274,7 +386,7 @@
TRAPD( err, iObservers[i]->MyCardEventL( aEvent ) );
if( err )
{
- CCA_DP(KMyCardLogFile,
+ CCA_DP(KMyCardLogFile,
CCA_L("<-CCCAppMyCard::NotifyObservers notify error (%d)"), err );
}
}
@@ -286,23 +398,23 @@
//
void CCCAppMyCard::LoadContact()
{
- CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::LoadContact()"));
+ CCA_DP(KMyCardLogFile, CCA_L("->CCCAppMyCard::LoadContact()"));
if( !iFetchOperation && iMyCard )
{
- TRAPD( err, iFetchOperation =
+ 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?
+ // 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()"));
+
+ CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::LoadContact()"));
}
// ---------------------------------------------------------------------------
@@ -312,19 +424,35 @@
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 )
- {
+
+ 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 )
@@ -332,11 +460,11 @@
TRAPD( err, iOperation = phoneStoreExtension->OwnContactLinkL(*this) );
if( err )
{
- // TODO: how is this handled?
+ iPlugin.HandleError( err );
}
}
- }
- CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::StoreReady()"));
+ }
+ CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::StoreReady()"));
}
// ---------------------------------------------------------------------------
@@ -344,10 +472,10 @@
// ---------------------------------------------------------------------------
//
void CCCAppMyCard::StoreUnavailable(
- MVPbkContactStore& /*aContactStore*/,
+ MVPbkContactStore& /*aContactStore*/,
TInt /*aReason*/)
{
- CCA_DP(KMyCardLogFile, CCA_L(" CCCAppMyCard::StoreUnavailable()"));
+ CCA_DP(KMyCardLogFile, CCA_L(" CCCAppMyCard::StoreUnavailable()"));
}
// ---------------------------------------------------------------------------
@@ -355,23 +483,36 @@
// ---------------------------------------------------------------------------
//
void CCCAppMyCard::HandleStoreEventL(
- MVPbkContactStore& /*aContactStore*/,
+ MVPbkContactStore& /*aContactStore*/,
TVPbkContactStoreEvent aStoreEvent )
{
- CCA_DP(KMyCardLogFile,
- CCA_L("->CCCAppMyCard::HandleStoreEventL Event = %d"),
+ 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()") );
+ CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::HandleStoreEventL()") );
}
// ---------------------------------------------------------------------------
@@ -382,15 +523,15 @@
MVPbkContactOperationBase& /*aOperation*/,
MVPbkContactLink* aLink )
{
- CCA_DP(KMyCardLogFile,
+ CCA_DP(KMyCardLogFile,
CCA_L("->CCCAppMyCard::VPbkSingleContactLinkOperationComplete()") );
-
+
delete iMyCard;
iMyCard = aLink;
-
+
LoadContact();
- CCA_DP(KMyCardLogFile,
+ CCA_DP(KMyCardLogFile,
CCA_L("<-CCCAppMyCard::VPbkSingleContactLinkOperationComplete()") );
}
@@ -415,9 +556,9 @@
// launch contact editor
iCreateCallBack->Call();
}
- if( error )
+ if( error != KErrNone && error != KErrNotFound )
{
- // TODO handle error
+ iPlugin.HandleError( error );
}
CCA_DP(KMyCardLogFile,
@@ -433,6 +574,12 @@
CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
TRAPD( err, self->LaunchContactEditorL( TPbk2ContactEditorParams::ENewContact |
TPbk2ContactEditorParams::EOwnContact ) );
+
+ if( err != KErrNone )
+ {
+ self->iPlugin.HandleError( err );
+ }
+
return err;
}
@@ -476,6 +623,8 @@
CleanupStack::Pop( title );
iEditorEliminator = dlg;
dlg->ResetWhenDestroyed( &iEditorEliminator );
+
+ iDialogIsRunning = ETrue;
dlg->ExecuteLD();
}
@@ -523,6 +672,7 @@
}
delete aEditedContact; // ignore given contact
+ iDialogIsRunning = EFalse;
}
// ---------------------------------------------------------------------------
@@ -535,6 +685,7 @@
// Editing was cancelled, go back to phonebook
delete aEditedContact;
iCloseCallBack->Call();
+ iDialogIsRunning = EFalse;
}
// ---------------------------------------------------------------------------
@@ -543,6 +694,7 @@
//
void CCCAppMyCard::ContactEditingAborted()
{
+ iDialogIsRunning = EFalse;
// Editing was aborted -> move to pb2
}
@@ -587,6 +739,17 @@
}
// ---------------------------------------------------------------------------
+// CCCAppMyCard::OpenStoresL
+// ---------------------------------------------------------------------------
+//
+TInt CCCAppMyCard::OpenStoresL( TAny* aPtr )
+ {
+ CCCAppMyCard* self = static_cast<CCCAppMyCard*>( aPtr );
+ self->iAppServices->StoreManager().OpenStoresL();
+ return 0;
+ }
+
+// ---------------------------------------------------------------------------
// CCCAppMyCard::DoCloseCCaL
// ---------------------------------------------------------------------------
//
@@ -611,17 +774,13 @@
TPbk2ContactEditorParams::EOwnContact) );
if( err != KErrNone )
{
- //TODO handle errors
+ iPlugin.HandleError( err );
}
}
else if( aResult.iOpCode == MVPbkContactObserver::EContactDelete )
{
iCloseCallBack->Call();
- }
- else
- {
- //TODO handle errors
- }
+ }
CCA_DP(KMyCardLogFile, CCA_L("<-CCCAppMyCard::ContactOperationCompleted()"));
}
@@ -631,9 +790,12 @@
// ---------------------------------------------------------------------------
//
void CCCAppMyCard::ContactOperationFailed(
- TContactOp /*aOpCode*/, TInt /*aErrorCode*/, TBool /*aErrorNotified*/)
+ TContactOp aOpCode, TInt aErrorCode, TBool /*aErrorNotified*/ )
{
- // TODO handle error
+ if ( aErrorCode != KErrNone )
+ {
+ iPlugin.HandleError( aErrorCode );
+ }
}
// ---------------------------------------------------------------------------
@@ -657,7 +819,7 @@
delete iPresentationContact;
iPresentationContact = NULL;
- NotifyObservers( MMyCardObserver::EEventContactLoaded );
+ NotifyObservers( iEvent );
CCA_DP(KMyCardLogFile,
CCA_L("<-CCCAppMyCard::VPbkSingleContactOperationComplete()"));
@@ -681,7 +843,10 @@
delete iOperation;
iOperation = NULL;
- // TODO: How to handle loading error?
+ if( aError != KErrNone )
+ {
+ iPlugin.HandleError( aError );
+ }
CCA_DP(KMyCardLogFile,
CCA_L("<-CCCAppMyCard::VPbkSingleContactOperationFailed()") );