diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/CommonUI/src/CPbk2NavigationBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/CommonUI/src/CPbk2NavigationBase.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,470 @@ +/* +* 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 navigator base. +* +*/ + + +#include "CPbk2NavigationBase.h" + +// Phonebook 2 +#include +#include + +// Virtual Phonebook +#include +#include +#include + +// System Includes +#include + +// Debugging headers +#include + + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CPbk2NavigationBase +// -------------------------------------------------------------------------- +// +CPbk2NavigationBase::CPbk2NavigationBase + ( MPbk2NavigationObserver& aObserver, + MPbk2ContactNavigationLoader& aNavigationLoader, + TArray aStoreList ): + iNavigationObserver( aObserver ), + iNavigationLoader( aNavigationLoader ), + iStoreList( aStoreList ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::~CPbk2NavigationBase +// -------------------------------------------------------------------------- +// +CPbk2NavigationBase::~CPbk2NavigationBase() + { + RemoveViewObserver(); + delete iOwnedView; + + CloseStores(); + + delete iIdleNotifier; + delete iDeletedContactInfo; + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::BaseConstructL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::BaseConstructL() + { + iDeletedContactInfo = new( ELeave ) CDeletedContactInfo( *this ); + + const TInt storeCount = iStoreList.Count(); + for (TInt i = 0; i < storeCount; ++i) + { + MVPbkContactStore& store = *iStoreList[i]; + // Asynchronous call to open a store + store.OpenL( *this ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::SetScrollViewL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::SetScrollViewL + ( MVPbkContactViewBase* aScrollView, TBool aOwnershipTransfered ) + { + // If there was a scroll view set, remove observer and delete it + if ( iScrollView ) + { + iScrollView->RemoveObserver( *this ); + delete iOwnedView; + iOwnedView = NULL; + } + + iScrollView = NULL; + + // Set new scroll view and add observer + if ( aScrollView ) + { + iScrollView = aScrollView; + if ( aOwnershipTransfered ) + { + iOwnedView = aScrollView; + } + iScrollView->AddObserverL( *this ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CurrentContactLC +// -------------------------------------------------------------------------- +// +MVPbkContactLink* CPbk2NavigationBase::CurrentContactLC() const + { + MVPbkContactLink* link = iDeletedContactInfo->FocusedContactOrNullLC(); + if ( !link ) + { + CleanupStack::Pop( link ); + link = iNavigationLoader.ContactLinkLC(); + } + return link; + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::ContactViewReady +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::ContactViewReady + ( MVPbkContactViewBase& /*aView*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::ContactViewUnavailable +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::ContactViewUnavailable + ( MVPbkContactViewBase& /*aView*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::ContactAddedToView +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::ContactAddedToView + ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/, + const MVPbkContactLink& /*aContactLink*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2VoidNavigation::ContactRemovedFromView +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::ContactRemovedFromView + ( MVPbkContactViewBase& aView, TInt aIndex, + const MVPbkContactLink& aContactLink ) + { + TRAPD( res, HandleContactRemovedFromViewL( aView, + aIndex, aContactLink ) ); + if ( res != KErrNone ) + { + CCoeEnv::Static()->HandleError( res ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::ContactViewError +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::ContactViewError + ( MVPbkContactViewBase& /*aView*/, TInt /*aError*/, + TBool /*aErrorNotified*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::StoreReady +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::StoreReady + ( MVPbkContactStore& /*aContactStore*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::StoreUnavailable +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::StoreUnavailable + ( MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::HandleStoreEventL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::HandleStoreEventL + ( MVPbkContactStore& aContactStore, + TVPbkContactStoreEvent aStoreEvent ) + { + iDeletedContactInfo->HandleStoreEventL( aContactStore, aStoreEvent ); + + switch ( aStoreEvent.iEventType ) + { + case TVPbkContactStoreEvent::EContactChanged: + { + MVPbkContactLink* currentContact = + iNavigationLoader.ContactLinkLC(); + + if ( currentContact && aStoreEvent.iContactLink && + currentContact->IsSame( *aStoreEvent.iContactLink ) ) + { + // Reload current contact + iNavigationLoader.ChangeContactL( *currentContact ); + } + CleanupStack::PopAndDestroy(); // currentContact + break; + } + case TVPbkContactStoreEvent::EGroupDeleted: // FALLTHROUGH + case TVPbkContactStoreEvent::EContactDeleted: + { + // Start the call back after we have got event from both + // store and view. But if we do not have iScrollView then only + // store event is enough. + if ( iDeletedContactInfo->DeletedAndRemoved() || !iScrollView ) + { + StartIdleCallBackL(); + } + break; + } + default: + { + // Do nothing + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::HandleContactRemovedFromViewL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::HandleContactRemovedFromViewL( + MVPbkContactViewBase& aView, + TInt aIndex, + const MVPbkContactLink& aContactLink ) + { + iDeletedContactInfo->HandleContactRemovedFromViewL( aView, + aIndex, aContactLink ); + + if ( iDeletedContactInfo->DeletedAndRemoved() ) + { + StartIdleCallBackL(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CloseStores +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::CloseStores() + { + for ( TInt i = 0; i < iStoreList.Count(); ++i ) + { + MVPbkContactStore& store = *iStoreList[i]; + store.Close( *this ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::RemoveViewObserver +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::RemoveViewObserver() + { + if ( iScrollView ) + { + iScrollView->RemoveObserver( *this ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::StartIdleCallBackL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::StartIdleCallBackL() + { + // The viewed contact was deleted, signal the + // observer asynchronously that the contact was deleted + if ( !iIdleNotifier ) + { + iIdleNotifier = CIdle::NewL( CActive::EPriorityStandard ); + } + else + { + iIdleNotifier->Cancel(); + } + iIdleNotifier->Start + ( TCallBack( &IdleNotifierCallBack, this ) ); + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::IdleNotifierCallBack +// -------------------------------------------------------------------------- +// +TInt CPbk2NavigationBase::IdleNotifierCallBack( TAny* aSelf ) + { + static_cast( aSelf )->HandleIdleNotify(); + return EFalse; + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::HandleIdleNotify +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::HandleIdleNotify() + { + iNavigationObserver.HandleNavigationEvent + ( MPbk2NavigationObserver::EContactDeleted ); + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::CDeletedContactInfo +// -------------------------------------------------------------------------- +// +CPbk2NavigationBase::CDeletedContactInfo::CDeletedContactInfo( + CPbk2NavigationBase& aNavigationBase ) + : iNavigationBase ( aNavigationBase ), + iRemovedContactIndex( KErrNotFound ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::~CDeletedContactInfo +// -------------------------------------------------------------------------- +// +CPbk2NavigationBase::CDeletedContactInfo::~CDeletedContactInfo() + { + delete iDeletedContact; + delete iRemovedContact; + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::HandleContactRemovedFromViewL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::CDeletedContactInfo::HandleContactRemovedFromViewL( + MVPbkContactViewBase& /*aView*/, + TInt aIndex, + const MVPbkContactLink& aContactLink ) + { + /// Handle delete event but not if we already have the information + /// that the current contact was deleted. + if ( !DeletedAndRemoved() ) + { + MVPbkContactLink* curContact = + iNavigationBase.NavigationLoader().ContactLinkLC(); + + // Save the removed contact if it's the current contact + if ( curContact && curContact->IsSame( aContactLink ) ) + { + delete iRemovedContact; + iRemovedContact = curContact; + CleanupStack::Pop(); // curContact + iRemovedContactIndex = aIndex; + } + else + { + CleanupStack::PopAndDestroy(); // curContact + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::HandleStoreEventL +// -------------------------------------------------------------------------- +// +void CPbk2NavigationBase::CDeletedContactInfo::HandleStoreEventL( + MVPbkContactStore& /*aContactStore*/, + TVPbkContactStoreEvent aStoreEvent ) + { + /// Handle delete event but not if we already have the information + /// that the current contact was deleted. + if ( !DeletedAndRemoved() && + (aStoreEvent.iEventType == TVPbkContactStoreEvent::EContactDeleted + || aStoreEvent.iEventType == TVPbkContactStoreEvent::EGroupDeleted)) + { + // Save the deleted contact if it's the current contact. + MVPbkContactLink* curContact = + iNavigationBase.NavigationLoader().ContactLinkLC(); + if ( curContact && aStoreEvent.iContactLink && + curContact->IsSame( *aStoreEvent.iContactLink ) ) + { + delete iDeletedContact; + iDeletedContact = curContact; + CleanupStack::Pop(); // curContact + } + else + { + CleanupStack::PopAndDestroy(); // curContact + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::DeletedAndRemoved +// -------------------------------------------------------------------------- +// +TBool CPbk2NavigationBase::CDeletedContactInfo::DeletedAndRemoved() const + { + TBool res = EFalse; + if ( iDeletedContact && iRemovedContact && + iRemovedContact->IsSame( *iDeletedContact ) ) + { + res = ETrue; + } + return res; + } + +// -------------------------------------------------------------------------- +// CPbk2NavigationBase::CDeletedContactInfo::FocusedContactOrNullLC +// -------------------------------------------------------------------------- +// +MVPbkContactLink* + CPbk2NavigationBase::CDeletedContactInfo::FocusedContactOrNullLC() + { + MVPbkContactLink* res = NULL; + MVPbkContactViewBase* view = iNavigationBase.ScrollView(); + + if ( DeletedAndRemoved() && view ) + { + TInt index = iRemovedContactIndex; + if ( index >= 0 ) + { + const TInt lastIndex = view->ContactCountL() - 1; + if ( index > lastIndex ) + { + index = lastIndex; + } + + // Returns a link to the contact that is in the same position + // as the removed one or in the last position. + if ( index >= 0 ) + { + res = view->CreateLinkLC( index ); + } + } + } + + if ( !res ) + { + // LC -semantics, push also NULL to cleanup stack + CleanupStack::PushL( res ); + } + + return res; + } +// End of File