diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/Application/src/CPbk2ContactInfoAppView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/Application/src/CPbk2ContactInfoAppView.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,1240 @@ +/* +* Copyright (c) 2005-2007 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: Phonebook 2 contact info application view. +* +*/ + +// INCLUDE FILES +#include "CPbk2ContactInfoAppView.h" + +// Phonebook 2 +#include "CPbk2AppUi.h" +#include "CPbk2Document.h" +#include "CPbk2StartupMonitor.h" +#include "CPbk2ViewExplorer.h" +#include "CPbk2ViewActivationTransaction.h" +#include "Pbk2InternalCommands.hrh" +#include "CPbk2ViewLoader.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include +#include +#include + +// Debugging headers +#include +#include +#include + +/// Unnamed namespace for local definitions +namespace { + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPreCond_HandleCommandL = 1, + EPanicPreCond_HandleCommandKeyL, + EPanicPostCond_ConstructL, + EPanicPreCond_DynInitMenuPaneL, + EPanicPreCond_ContactChangedL, + EPanicPreCond_SetNavigatorViewL, + EPanicPreCond_GetViewSpecificMenuFilteringFlagsL, + EPanicPreCond_NULLPointer, + EPanicPreCond_ViewLoaded, + EPanicLogic_LoadContactL + }; + +void Panic(TPanicCode aReason) + { + _LIT( KPanicText, "CPbk2ContactInfoAppView" ); + User::Panic( KPanicText, aReason ); + } +#endif // _DEBUG + +} /// namespace + + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::CPbk2ContactInfoAppView +// -------------------------------------------------------------------------- +// +inline CPbk2ContactInfoAppView::CPbk2ContactInfoAppView + ( CVPbkContactManager& aContactManager ) : + iContactManager( aContactManager ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::~CPbk2ContactInfoAppView +// -------------------------------------------------------------------------- +// +CPbk2ContactInfoAppView::~CPbk2ContactInfoAppView() + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::~CPbk2ContactInfoAppView()"), this); + + delete iViewLoader; + delete iControlState; + delete iViewActivationTransaction; + delete iNavigation; + delete iContactLoader; + iStoreList.Reset(); + iStoreList.Close(); + + if (iContainer) + { + AppUi()->RemoveFromViewStack(*this, iContainer); + delete iContainer; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::NewL +// -------------------------------------------------------------------------- +// +CPbk2ContactInfoAppView* CPbk2ContactInfoAppView::NewL + ( CVPbkContactManager& aContactManager ) + { + CPbk2ContactInfoAppView* self = + new ( ELeave ) CPbk2ContactInfoAppView( aContactManager ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ConstructL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactInfoAppView::ConstructL() + { + // Init base class + PBK2_PROFILE_START(Pbk2Profile::EContactInfoViewBaseConstruct); + CAknView::BaseConstructL(R_PHONEBOOK2_CONTACTINFO_APPVIEW); + PBK2_PROFILE_END(Pbk2Profile::EContactInfoViewBaseConstruct); + + iCommandHandler = Pbk2AppUi()->ApplicationServices().CommandHandlerL(); + iStoreConfiguration = &Pbk2AppUi()->ApplicationServices(). + StoreConfiguration(); + + __ASSERT_DEBUG(iCommandHandler, + Panic(EPanicPostCond_ConstructL)); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleCommandL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleCommandL + (TInt aCommandId) + { + __ASSERT_DEBUG(iControl, + Panic(EPanicPreCond_HandleCommandL)); + + // If this view has already been deactivated, just return + if ( Pbk2AppUi()->ActiveView()->Id() != Phonebook2::KPbk2ContactInfoViewUid ) + { + return; + } + + if (EAknCmdHideInBackground == aCommandId) + { + // Gets a pointer to Nameslist extension view + CAknView* pNamesListExtensionView = + static_cast (Pbk2AppUi()->View( + Phonebook2::KPbk2NamesListViewUid)); + + // if Nameslist extension view does exists, + // pass EAknCmdHideInBackground to the view, in order to close the CCA. + if (pNamesListExtensionView) + { + pNamesListExtensionView->HandleCommandL(aCommandId); + } + } + + switch (aCommandId) + { + case EAknSoftkeyBack: // FALLTHROUGH + case EPbk2CmdOpenPreviousView: + { + // Set the focused contact according to control state -> NULL + ReturnToPreviousViewL( NULL ); + break; + } + default: + { + // No command handling in this class, forward to Commands + if ( !iCommandHandler->HandleCommandL + ( aCommandId, *iControl, this ) ) + { + iControl->ProcessCommandL(aCommandId); + // Command was not handled in Pbk2Commands, + // forward it to AppUi + AppUi()->HandleCommandL(aCommandId); + if ( aCommandId == EAknCmdHideInBackground ) + { + DoDeactivate(); + } + } + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::DynInitMenuPaneL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::DynInitMenuPaneL + (TInt aResourceId, CEikMenuPane* aMenuPane) + { + __ASSERT_DEBUG(iControl, + Panic(EPanicPreCond_DynInitMenuPaneL)); + + // Ask the control do control specific filtering + iControl->DynInitMenuPaneL(aResourceId, aMenuPane); + + // Phonebook 2 menu filtering happens in Commands + iCommandHandler->DynInitMenuPaneL( + aResourceId, aMenuPane, *this, *iControl); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::Id +// -------------------------------------------------------------------------- +// +TUid CPbk2ContactInfoAppView::Id() const + { + return Phonebook2::KPbk2ContactInfoViewUid; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleStatusPaneSizeChange +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleStatusPaneSizeChange() + { + // Resize the container to fill the client rectangle + if (iContainer) + { + iContainer->SetRect(ClientRect()); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::DoActivateL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::DoActivateL + ( const TVwsViewId& aPrevViewId, + TUid aCustomMessageId, const TDesC8& aCustomMessage ) + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::DoActivateL()"), this); + + //NOTE: this view can be used as external, + // DoActivateL can be called for active view + + // UpdateViewGraphL only for pbk2 views, + if ( Pbk2AppUi()->Pbk2ViewExplorer()->IsPhonebook2View(aPrevViewId) ) + { + UpdateViewGraphL( aPrevViewId ); + } + else if ( iContainer ) + { + // if the view activated as an external, reset it state + delete iControlState; + iControlState = NULL; + } + + iCommandHandler->RemoveMenuCommandObserver( *this ); + iCommandHandler->AddMenuCommandObserver( *this ); + + iStoreConfiguration->RemoveObserver( *this ); + iStoreConfiguration->AddObserverL( *this ); + + // Update application-wide state. UI control updates the title pane. + delete iViewActivationTransaction; + iViewActivationTransaction = NULL; + TUint flags (Phonebook2::EUpdateContextPane); + if ( !iContainer ) + { + // don't update navipane if it's already active + flags |= Phonebook2::EUpdateNaviPane; + } + iViewActivationTransaction = + Pbk2AppUi()->Pbk2ViewExplorer()->HandleViewActivationLC + ( Id(), aPrevViewId, NULL, NULL, + flags ); + CleanupStack::Pop(); // iViewActivationTransaction + + if (aCustomMessageId == CPbk2ViewState::Uid() || + aCustomMessageId == TUid::Uid(KPbkViewStateUid)) + { + // Handles both new and legacy view state parameters + UpdateViewStateL(aCustomMessageId, aCustomMessage); + } + else + { + // No UI state specified, restore in previous state + if (!iControlState) + { + // No previous state + User::Leave(KErrArgument); + } + } + + if ( !iControlState->FocusedContact() ) + { + User::Leave( KErrArgument ); + } + + //navigator is created for each DoActiveL, depends on input parameters + //navigator is created for each DoActiveL, depends on input parameters + ConstructNavigatorL(); + + //if the view is active, its control is reused, only navigator is updated + CreateControlsL(); + AttachAIWProvidersL(); + + LoadContactViewL( aPrevViewId ); + iPreviousViewId = aPrevViewId; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::DoDeactivate +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::DoDeactivate() + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::DoDeactivate()"), this); + + delete iViewLoader; + iViewLoader = NULL; + + iCommandHandler->RemoveMenuCommandObserver( *this ); + + iStoreConfiguration->RemoveObserver( *this ); + + delete iViewActivationTransaction; + iViewActivationTransaction = NULL; + delete iNavigation; + iNavigation = NULL; + + // Trash the old states + delete iControlState; + iControlState = NULL; + + // Reset store list + iStoreList.Reset(); + + if (iContainer) + { + iContainer->Control()->HideThumbnail(); + + // Remove view and its control from the view stack + AppUi()->RemoveFromViewStack(*this, iContainer); + + // Store current state, safe to ignore. There's no real harm, + // if theres no stored state when activating this view again + TRAP_IGNORE(StoreStateL()); + + // Destroy the container control + delete iContainer; + iContainer = NULL; + iControl = NULL; + } + + delete iContactLoader; + iContactLoader = NULL; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleForegroundEventL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleForegroundEventL( TBool aForeground ) + { + CPbk2AppView::HandleForegroundEventL(aForeground); + + // If this view is gaining foreground, then make sure that thumbnail + // gets drawn + if (aForeground && iContainer && iContainer->Control()) + { + if ( iContainer->Control()->IsVisible() ) + { + iContainer->Control()->ShowThumbnail(); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ViewStateLC +// -------------------------------------------------------------------------- +// +CPbk2ViewState* CPbk2ContactInfoAppView::ViewStateLC() const + { + __ASSERT_DEBUG( iControl ,Panic(EPanicPreCond_NULLPointer)); + + CPbk2ViewState* state = iControl->ControlStateL(); + CleanupStack::PushL(state); + return state; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleCommandKeyL +// -------------------------------------------------------------------------- +// +TBool CPbk2ContactInfoAppView::HandleCommandKeyL + (const TKeyEvent& aKeyEvent, TEventCode aType) + { + __ASSERT_DEBUG(iContainer && iNavigation, + Panic(EPanicPreCond_HandleCommandKeyL)); + + // Pass the key event to the strategy + TBool ret = iNavigation->HandleCommandKeyL( aKeyEvent, aType ); + + if ( !ret && aType == EEventKey ) + { + switch ( aKeyEvent.iCode ) + { + case EKeyEnter: // FALLTHROUGH + case EKeyOK: + { + LaunchPopupMenuL( R_PHONEBOOK2_CONTACTINFO_CONTEXTBAR ); + ret = ETrue; + break; + } + case EKeyBackspace: // Clear key + { + HandleCommandL(EPbk2CmdDeleteMe); + ret = ETrue; + break; + } + case EKeyPhoneSend: + { + // If focused field is either url or email field + // the proper context menu should be launched. + if ( IsFocusedFieldTypeL( R_PHONEBOOK2_URL_SELECTOR ) + || IsFocusedFieldTypeL( R_PHONEBOOK2_EMAIL_SELECTOR ) ) + { + LaunchPopupMenuL( R_PHONEBOOK2_CONTACTINFO_CONTEXTBAR ); + } + else + { + // Use the EPbk2CmdCall id to identify that + // call is being launched with send key + HandleCommandL( EPbk2CmdCall ); + } + ret = ETrue; + break; + } + case EKeyPoC: + { + // Use the EPbk2CmdPoC id to identify that + // call is being launched with PoC key + HandleCommandL( EPbk2CmdPoC ); + ret = ETrue; + break; + } + default: + { + break; + } + } + } + return ret; + } + + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::GetViewSpecificMenuFilteringFlagsL +// -------------------------------------------------------------------------- +// +TInt CPbk2ContactInfoAppView::GetViewSpecificMenuFilteringFlagsL() const + { + __ASSERT_DEBUG( iControl, + Panic( EPanicPreCond_GetViewSpecificMenuFilteringFlagsL ) ); + + return iControl->GetMenuFilteringFlagsL(); + } + + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::PrepareForContactChangeL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::PrepareForContactChangeL() + { + StoreStateL(); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ContactChangedL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ContactChangedL( MVPbkStoreContact* aContact ) + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::ContactChangedL() begin"), this); + + if ( !iContainer ) + { + // It is possible that this method get called before + // the container and control get constructed. + // In that case, ignore the given contact by deleting + // it and do not continue the contact changed process. + delete aContact; + + // iViewActivationTransaction should not be deleted here + // since it is not tied to this ContactChangedL request + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::ContactChangedL() controls not ready"), + this); + } + else + { + __ASSERT_DEBUG(iViewActivationTransaction, + Panic(EPanicPreCond_ContactChangedL)); + __ASSERT_DEBUG(iNavigation, Panic(EPanicPreCond_ContactChangedL)); + + // Update controls + if (aContact) + { + CleanupDeletePushL(aContact); + iContainer->Control()->UpdateL(aContact); + CleanupStack::Pop(aContact); // ownership was taken + } + + if ( iControlState->FocusedContact() ) + { + if ( !iControlState->FocusedContact()->RefersTo( *aContact ) ) + { + iContainer->Control()->SetFocusedFieldIndex( KErrNotFound ); + iControlState->SetFocusedFieldIndex( KErrNotFound ); + } + } + + SetEmptyTextL( R_QTN_PHOB_NO_ITEMS ); + + iContainer->Control()->RestoreControlStateL(iControlState); + + // Commit application-wide state changes + iViewActivationTransaction->Commit(); + + // notifies startup monitor of view activation + if (Pbk2AppUi()->Pbk2StartupMonitor()) + { + Pbk2AppUi()->Pbk2StartupMonitor()->NotifyViewActivationL(Id()); + } + } + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::ContactChangedL() end"), this); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ContactChangeFailed +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ContactChangeFailed() + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView(%x)::ContactChangeFailed()"), this); + + TInt err = KErrNone; + + TRAP( err, SetEmptyTextL( R_QTN_PHOB_NO_ITEMS ) ); + if ( err != KErrNone ) + { + CEikonEnv::Static()->HandleError( err ); + } + + // Rollback + if ( iViewActivationTransaction ) + { + // Rollback by force + TRAP( err, iViewActivationTransaction->RollbackL() ); + delete iViewActivationTransaction; + iViewActivationTransaction = NULL; + + if ( err != KErrNone ) + { + CEikonEnv::Static()->HandleError( err ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::Contact +// -------------------------------------------------------------------------- +// +const MVPbkStoreContact* CPbk2ContactInfoAppView::Contact() const + { + const MVPbkStoreContact* result = NULL; + if (iControl) + { + result = iControl->FocusedStoreContact(); + } + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleControlEventL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleControlEventL + ( MPbk2ContactUiControl& /*aControl*/, + const TPbk2ControlEvent& aEvent ) + { + switch (aEvent.iEventType) + { + case TPbk2ControlEvent::EContactDoubleTapped: + { + LaunchPopupMenuL( R_PHONEBOOK2_CONTACTINFO_CONTEXTBAR ); + break; + } + + case TPbk2ControlEvent::EReady: + { + UpdateCbasL(); + break; + } + + default: + { + // Do nothing + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ConfigurationChanged +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ConfigurationChanged() + { + if (iPreviousViewId.iViewUid != KNullUid) + { + TRAPD(err, LoadContactViewL(iPreviousViewId)); + if (err != KErrNone) + { + CCoeEnv::Static()->HandleError(err); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ConfigurationChangedComplete +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ConfigurationChangedComplete() + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::PreCommandExecutionL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::PreCommandExecutionL + ( const MPbk2Command& /*aCommand*/ ) + { + if (iContainer && iContainer->Control()) + { + iContainer->Control()->HideThumbnail(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::PostCommandExecutionL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::PostCommandExecutionL + ( const MPbk2Command& /*aCommand*/ ) + { + if (iContainer && iContainer->Control()) + { + iContainer->Control()->ShowThumbnail(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::CreateControlsL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactInfoAppView::CreateControlsL() + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactInfoAppView::CreateControlsL()")); + + // if the view is active, recreate control, in order + // to use new iNavigation and delete old storecontact + + if ( iContainer && iControl ) + { + iContainer->DestroyControl(); + iControl = NULL; + } + + if (!iContainer) + { + // Create the container and control + CContainer* container = CContainer::NewLC(this, this, *this); + + container->SetHelpContext( TCoeHelpContext( ApplicationUid(), + KHLP_CCA_DETAILS )); + + // Add this view and container to the view stack + AppUi()->AddToViewStackL(*this, container); + CleanupStack::Pop(container); + iContainer = container; + } + + if ( !iControl ) + { + CPbk2ContactInfoControl* control = CPbk2ContactInfoControl::NewL + ( iContainer, iContactManager, + Pbk2AppUi()->ApplicationServices().NameFormatter(), + Pbk2AppUi()->ApplicationServices().FieldProperties(), + Pbk2AppUi()->ApplicationServices().StoreProperties(), + iNavigation ); + TRect r = ClientRect(); + iContainer->SetControl(control, r); // takes ownership + control->AddObserverL(*this); + + iControl = control; + + // Assign pointer event inspector + iPointerInspector = + AknLayoutUtils::PenEnabled() ? control : NULL; + + iContainer->ActivateL(); + iContainer->Control()->MakeVisible( ETrue ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleNavigationEvent +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleNavigationEvent + ( const TEventType& aEventType ) + { + if ( aEventType == MPbk2NavigationObserver::EContactDeleted ) + { + // Contact was deleted which means that we must go back to previous + // view. The previous view must know the contact to focus and it + // obviously can not be the deleted contact. The navigator works + // in a same logic as the focus in the previous view. It knows the + // the contact after deletion. + TRAPD( err, + { + MVPbkContactLink* curContact = CurrentContactInNavigatorLC(); + CleanupStack::Pop(); // curContact + // Give ownership of curContact + ReturnToPreviousViewL( curContact ); + }); + if ( err != KErrNone ) + { + CCoeEnv::Static()->HandleError( err ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ViewLoaded +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ViewLoaded( MVPbkContactViewBase& aView ) + { + __ASSERT_DEBUG(iContactLoader && iControlState, + Panic(EPanicPreCond_ViewLoaded)); + + if ( &aView == iContactView ) + { + TRAPD( error, HandleViewLoadedL() ); + if ( error != KErrNone ) + { + ViewError( aView, error ); + } + } + delete iViewLoader; + iViewLoader = NULL; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ViewError +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ViewError + ( MVPbkContactViewBase& aView, TInt /*aError*/ ) + { + delete iViewLoader; + iViewLoader = NULL; + + if ( &aView == iContactView ) + { + TRAPD( error, iViewActivationTransaction->RollbackL() ); + if ( error != KErrNone ) + { + CCoeEnv::Static()->HandleError(error); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::UpdateViewStateL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactInfoAppView::UpdateViewStateL + ( const TUid aCustomMessageId, + const TDesC8& aCustomMessage ) + { + CPbk2ViewState* viewState = NULL; + if (aCustomMessageId == TUid::Uid(KPbkViewStateUid)) + { + // handle legacy view state + CPbk2ViewStateTransformer* transformer = + CPbk2ViewStateTransformer::NewLC( iContactManager ); + viewState = transformer-> + TransformLegacyViewStateToPbk2ViewStateLC( aCustomMessage ); + CleanupStack::Pop(); + CleanupStack::PopAndDestroy(transformer); + } + else if (aCustomMessageId == CPbk2ViewState::Uid()) + { + // Read the desired UI state from aCustomMessage + viewState = CPbk2ViewState::NewL(aCustomMessage); + } + else + { + // a parameter must be passed to this view + User::Leave(KErrNotSupported); + } + + if (iControlState) + { + // Merge parameter view state with the stored state + if ( viewState->FocusedContact() && + !viewState->FocusedContact()->IsSame + ( *iControlState->FocusedContact() )) + { + iControlState->SetFocusedContact( + viewState->TakeFocusedContact()); + iControlState->SetFocusedFieldIndex(KErrNotFound); + iControlState->SetTopFieldIndex(KErrNotFound); + } + if (viewState->FocusedFieldIndex() >= 0) + { + iControlState->SetFocusedFieldIndex( + viewState->FocusedFieldIndex()); + } + if (viewState->TopFieldIndex() >= 0) + { + iControlState->SetTopFieldIndex( + viewState->TopFieldIndex()); + } + if ( viewState->ParentContact() ) + { + iControlState->SetParentContact( + viewState->TakeParentContact()); + } + // Delete parameter view state + delete viewState; + } + else + { + // No stored state, use the parameter supplied one + iControlState = viewState; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::SetNavigatorViewL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::SetNavigatorViewL() + { + __ASSERT_DEBUG(iNavigation, + Panic(EPanicPreCond_SetNavigatorViewL)); + + // Set default navigation + iNavigation->SetScrollViewL( iContactView, EFalse ); + + // Inspect if the parent contact is set and if the parent + // contact is expandable. In that case set the navigation + // view to the expandable view. + const MVPbkContactLink* parentLink = iControlState->ParentContact(); + if ( parentLink ) + { + // Find parent index in the contact view + const TInt parentIndex = + iContactView->IndexOfLinkL( *parentLink ); + // Get the view contact by view index + const MVPbkViewContact& viewContact = + iContactView->ContactAtL( parentIndex ); + + // Expand the scroll view from the view contact + MVPbkExpandable* expandable = viewContact.Expandable(); + if ( expandable ) + { + MVPbkContactViewBase* scrollView = expandable->ExpandLC + ( *iNavigation, Pbk2AppUi()->ApplicationServices(). + SortOrderManager().SortOrder() ); + CleanupStack::Pop(); // scrollView + + // Set the navigation scroll view, transfer ownership + iNavigation->SetScrollViewL( scrollView, ETrue ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::StoreStateL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::StoreStateL() + { + CPbk2ViewState* state = ViewStateLC(); + CleanupStack::Pop(state); + + // state should be always created, but valid state + // has focusedContact + if ( state && state->FocusedContact() ) + { + delete iControlState; + iControlState = state; + } + else + { + delete state; + state = NULL; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::IsFocusedFieldTypeL +// -------------------------------------------------------------------------- +// +TBool CPbk2ContactInfoAppView::IsFocusedFieldTypeL( TInt aSelectorResId ) + { + TPbk2StoreContactAnalyzer analyzer( iContactManager, NULL ); + const MVPbkBaseContactField* field = iContainer->Control()->FocusedField(); + + if ( field ) + { + return analyzer.IsFieldTypeIncludedL( *field, aSelectorResId ); + } + else + { + return EFalse; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::UpdateCbasL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::UpdateCbasL() + { + if ( iControl ) + { + // Set cba command set "Options - Context Menu - Back" + Cba()->SetCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_BACK_CONTEXT ); + Cba()->DrawDeferred(); + // Set context menu + MenuBar()->SetContextMenuTitleResourceId + ( R_PHONEBOOK2_CONTACTINFO_CONTEXTBAR ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::AttachAIWProvidersL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactInfoAppView::AttachAIWProvidersL() + { + iCommandHandler->RegisterAiwInterestL + ( KAiwCmdCall, R_PHONEBOOK2_CALL_MENU, + R_PHONEBOOK2_CALLUI_AIW_INTEREST, ETrue ); + + iCommandHandler->RegisterAiwInterestL + (KAiwCmdCall, R_PHONEBOOK2_CALL_CONTEXT_MENU, + R_PHONEBOOK2_CALLUI_AIW_INTEREST, EFalse); + + iCommandHandler->RegisterAiwInterestL + ( KAiwCmdPoC, R_PHONEBOOK2_POC_MENU, + R_PHONEBOOK2_POCUI_AIW_INTEREST, ETrue ); + + iCommandHandler->RegisterAiwInterestL + (KAiwCmdPoC, R_PHONEBOOK2_POC_CONTEXT_MENU, + R_PHONEBOOK2_POCUI_AIW_INTEREST, EFalse); + + iCommandHandler->RegisterAiwInterestL + (KAiwCmdInfoView, R_PHONEBOOK2_SIND_INFOVIEW_MENU, + R_PHONEBOOK2_SIND_INFOVIEW_AIW_INTEREST, EFalse); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleLongTapEventL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleLongTapEventL + ( const TPoint& /*aPenEventLocation*/, + const TPoint& /*aPenEventScreenLocation*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::CurrentContactInNavigatorLC +// -------------------------------------------------------------------------- +// +MVPbkContactLink* CPbk2ContactInfoAppView::CurrentContactInNavigatorLC() + { + if ( iNavigation ) + { + return iNavigation->CurrentContactLC(); + } + else + { + MVPbkContactLink* link = NULL; + // LC semantics also in NULL case. + CleanupStack::PushL( link ); + return link; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ReturnToPreviousViewL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ReturnToPreviousViewL + ( MVPbkContactLink* aFocusedContact ) const + { + // Ownership of aFocusedContact is taken by this function + CleanupDeletePushL( aFocusedContact ); + + CPbk2ViewState* state = ViewStateLC(); + CleanupStack::Pop( state ); + + // aFocusedContact contact overwrites the focused contact from control's + // state. + if ( aFocusedContact ) + { + // state takes the ownership if aFocusedContact + state->SetFocusedContact( aFocusedContact ); + CleanupStack::Pop(); // aFocusedContact + } + else + { + CleanupStack::PopAndDestroy(); // aFocusedContact + } + + CleanupStack::PushL( state ); + + Pbk2AppUi()->Pbk2ViewExplorer()->ActivatePreviousViewL( state ); + CleanupStack::PopAndDestroy( state ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::LoadContactViewL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::LoadContactViewL + ( const TVwsViewId& aPrevViewId ) + { + delete iViewLoader; + iViewLoader = NULL; + + if ( Pbk2AppUi()->Pbk2ViewExplorer()-> + IsPhonebook2View( aPrevViewId ) && + ( aPrevViewId.iViewUid == TUid::Uid + ( EPbk2GroupMembersListViewId ) ) ) + { + iContactView = Phonebook2::Pbk2AppUi()->ApplicationServices(). + ViewSupplier().AllGroupsViewL(); + } + else + { + iContactView = Phonebook2::Pbk2AppUi()->ApplicationServices(). + ViewSupplier().AllContactsViewL(); + } + + iViewLoader = CPbk2ViewLoader::NewL( *iContactView, *this ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::HandleViewLoadedL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::HandleViewLoadedL() + { + SetNavigatorViewL(); + LoadContactL(); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::LoadContactL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::LoadContactL() + { + const MVPbkContactLink* link = iControlState->FocusedContact(); + __ASSERT_DEBUG( link, Panic( EPanicLogic_LoadContactL ) ); + __ASSERT_DEBUG( iContactLoader, Panic( EPanicLogic_LoadContactL ) ); + + //ChangeContact can delete iControlState, invalidating link + //therefore copy link + MVPbkContactLink* inputParameterContact = link->CloneLC(); + // Load the contact from view state, this is asynchronous + iContactLoader->ChangeContactL( *inputParameterContact ); + CleanupStack::PopAndDestroy(); //inputParameterContact + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::ConstructNavigatorL +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::ConstructNavigatorL() + { + iStoreList.Reset(); + CVPbkContactStoreUriArray* uriList = + Pbk2AppUi()->ApplicationServices().StoreConfiguration(). + CurrentConfigurationL(); + CleanupStack::PushL( uriList ); + MVPbkContactStoreList& fullStoreList = + iContactManager.ContactStoresL(); + for (TInt i = 0; i < uriList->Count(); ++i) + { + // Add all the contact stores to the store list + TVPbkContactStoreUriPtr uri = (*uriList)[i]; + MVPbkContactStore* store = fullStoreList.Find(uri); + iStoreList.AppendL(store); + } + CleanupStack::PopAndDestroy( uriList ); + + /// Create contact loader and contact info scroll navigator + delete iContactLoader; + iContactLoader = NULL; + iContactLoader = CPbk2MemoryEntryContactLoader::NewL( *this ); + + MVPbkContactStore& storeFromState = + iControlState->FocusedContact()->ContactStore(); + TBool storeNotInConfiguration = EFalse; + if ( iStoreList.Find( &storeFromState ) == KErrNotFound ) + { + storeNotInConfiguration = ETrue; + // Do not add store into list, opening of this lone + // store is not navigator's responsibility + } + + delete iNavigation; + iNavigation = NULL; + + if ( !storeNotInConfiguration ) + { + iNavigation = Pbk2NavigatorFactory::CreateContactNavigatorL + ( Id(), *this, *iContactLoader, iStoreList.Array(), + R_QTN_PHOB_NAVI_POS_INDICATOR_CONTACT_INFO_VIEW ); + } + else + { + // Store was not in configuration --> contact to be shown is not + // included in the scroll view --> no point to use sideways + // navigation strategy + iNavigation = Pbk2NavigatorFactory::CreateVoidNavigatorL + ( Id(), *this, *iContactLoader, iStoreList.Array() ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::UpdateViewGraphL +// Sets previous view node. Previous node should be set dynamically +// because it could be some extension view. +// Default is names list view. +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::UpdateViewGraphL + ( const TVwsViewId& aPrevViewId ) + { + CPbk2ViewGraph& viewGraph = static_cast + ( Pbk2AppUi()->Pbk2ViewExplorer() )->ViewGraph(); + CPbk2ViewNode* prevNode = + viewGraph.FindNodeWithViewId( aPrevViewId.iViewUid ); + if ( prevNode ) + { + CPbk2ViewNode* thisNode = viewGraph.FindNodeWithViewId( Id() ); + if ( thisNode ) + { + thisNode->SetPreviousNode( prevNode ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactInfoAppView::SetEmptyTextL +// Sets empty text for contact info list box from given resource id. +// -------------------------------------------------------------------------- +// +void CPbk2ContactInfoAppView::SetEmptyTextL( + TInt aResourceId ) + { + HBufC* emptyText = StringLoader::LoadLC( aResourceId ); + iContainer->Control()->SetTextL( *emptyText ); + CleanupStack::PopAndDestroy( emptyText ); + } + + +// End of File