diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkFoldingContactView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkFoldingContactView.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,488 @@ +/* +* Copyright (c) 2006-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: A class for folding view that can be expanded to its subview +* +*/ + + +#include "CVPbkFoldingContactView.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TVPbkFoldingContactBookmark.h" +#include "CVPbkFoldingViewContact.h" + +namespace { + +#ifdef _DEBUG + enum TPanic + { + EPreCond_ConstructL + }; + + void Panic( TPanic aPanic ) + { + _LIT(KPanicCat, "CVPbkFoldingContactView"); + User::Panic( KPanicCat, aPanic ); + } +#endif // _DEBUG + +// CONSTANTS +const TInt KObserverArrayGranularity = 4; + +// Event sending functions for different amount of parameters + +// --------------------------------------------------------------------------- +// SendEventToObservers +// For observer functions that take MVPbkContactViewBase as a parameter +// --------------------------------------------------------------------------- +// +template +void SendEventToObservers(MVPbkContactViewBase& aView, + RPointerArray& iObservers, + NotifyFunc aNotifyFunc) + { + const TInt count = iObservers.Count(); + for (TInt i = 0; i < count; ++i) + { + MVPbkContactViewObserver* observer = iObservers[i]; + (observer->*aNotifyFunc)(aView); + } + } + +// --------------------------------------------------------------------------- +// SendEventToObservers +// For observer functions that take MVPbkContactViewBase, and two other +// parameters +// --------------------------------------------------------------------------- +// +template +void SendEventToObservers(MVPbkContactViewBase& aView, + RPointerArray& iObservers, + NotifyFunc aNotifyFunc, + ParamType1 aParam1, + ParamType2 aParam2) + { + const TInt count = iObservers.Count(); + for (TInt i = 0; i < count; ++i) + { + MVPbkContactViewObserver* observer = iObservers[i]; + (observer->*aNotifyFunc)(aView, aParam1, aParam2); + } + } + +// --------------------------------------------------------------------------- +// DoMatchContactStore +// --------------------------------------------------------------------------- +// +TBool DoMatchContactStore(CVPbkContactViewDefinition& aViewDef, + TVPbkContactStoreUriPtr::TVPbkContactStoreUriComponent aUriComponent, + const TDesC& aStoreUriComponentDes) + { + // Match store URI to the first view definition that is found starting + // from the aViewDef. If not found then check subviews from left to right + TBool result = EFalse; + TVPbkContactStoreUriPtr uriPtr(aViewDef.Uri()); + if (uriPtr.Compare(aStoreUriComponentDes, aUriComponent) == 0) + { + result = ETrue; + } + else + { + const TInt count = aViewDef.SubViewCount(); + for (TInt i = 0; i < count && !result; ++i) + { + result = DoMatchContactStore(aViewDef.SubViewAt(i), aUriComponent, + aStoreUriComponentDes); + } + } + return result; + } +} + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::CVPbkFoldingContactView +// --------------------------------------------------------------------------- +// +CVPbkFoldingContactView::CVPbkFoldingContactView( + const CVPbkContactManager& aContactManager) : + iContactManager(aContactManager), + iObservers( KObserverArrayGranularity ) + { + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ConstructL +// --------------------------------------------------------------------------- +// +inline void CVPbkFoldingContactView::ConstructL( + const CVPbkContactViewDefinition& aViewDefinition, + const MVPbkFieldTypeList& aSortOrder) + { + /// Folding view must have 1 sub view definition if it's used for + /// expanding. If there is no sub view then this folding can not be + /// exapanded and it's only used to show a named item. + __ASSERT_DEBUG( aViewDefinition.SubViewCount() <= 1, + Panic( EPreCond_ConstructL ) ); + + /// Save the one and only subview definition for later usage + iViewDefinition = CVPbkContactViewDefinition::NewL( aViewDefinition ); + /// Create the view contact + iFoldingContact = CVPbkFoldingViewContact::NewL(*this); + iSortOrder = CVPbkSortOrder::NewL(aSortOrder); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::NewLC +// --------------------------------------------------------------------------- +// +CVPbkFoldingContactView* CVPbkFoldingContactView::NewLC( + MVPbkContactViewObserver& aObserver, + const CVPbkContactViewDefinition& aViewDefinition, + const CVPbkContactManager& aContactManager, + const MVPbkFieldTypeList& aSortOrder) + { + CVPbkFoldingContactView* self = new(ELeave) CVPbkFoldingContactView(aContactManager); + CleanupStack::PushL(self); + self->ConstructL(aViewDefinition, aSortOrder); + self->AddObserverL(aObserver); + return self; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::~CVPbkFoldingContactView +// --------------------------------------------------------------------------- +// +CVPbkFoldingContactView::~CVPbkFoldingContactView() + { + delete iViewDefinition; + delete iSortOrder; + delete iFoldingContact; + iObservers.Close(); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::Name +// --------------------------------------------------------------------------- +// +const TDesC& CVPbkFoldingContactView::Name() const + { + return iViewDefinition->Name(); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::Type +// --------------------------------------------------------------------------- +// +TVPbkContactViewType CVPbkFoldingContactView::Type() const + { + return EVPbkFoldingView; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ChangeSortOrderL +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::ChangeSortOrderL(const MVPbkFieldTypeList& aSortOrder) + { + if (iObservers.Count() > 0) + { + CVPbkSortOrder* newSortOrder = CVPbkSortOrder::NewL(aSortOrder); + delete iSortOrder; + iSortOrder = newSortOrder; + + SendAsyncUnavailableAndReadyEventL(); + } + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::SortOrder +// --------------------------------------------------------------------------- +// +const MVPbkFieldTypeList& CVPbkFoldingContactView::SortOrder() const + { + return *iSortOrder; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::RefreshL +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::RefreshL() + { + SendAsyncUnavailableAndReadyEventL(); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ContactCountL +// --------------------------------------------------------------------------- +// +TInt CVPbkFoldingContactView::ContactCountL() const + { + // This is folding view => only this view is visible as a contact + return 1; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ContactAtL +// --------------------------------------------------------------------------- +// +const MVPbkViewContact& CVPbkFoldingContactView::ContactAtL(TInt aIndex) const + { + __ASSERT_ALWAYS( aIndex >= 0, + VPbkError::Panic( VPbkError::EInvalidContactIndex ) ); + if ( aIndex >= ContactCountL() ) + { + User::Leave( KErrArgument ); + } + + return *iFoldingContact; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::CreateLinkLC +// --------------------------------------------------------------------------- +// +MVPbkContactLink* CVPbkFoldingContactView::CreateLinkLC(TInt aIndex) const + { + __ASSERT_ALWAYS( aIndex >= 0, + VPbkError::Panic( VPbkError::EInvalidContactIndex ) ); + if ( aIndex >= ContactCountL() ) + { + User::Leave( KErrArgument ); + } + + return iFoldingContact->CreateLinkLC(); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::IndexOfLinkL +// --------------------------------------------------------------------------- +// +TInt CVPbkFoldingContactView::IndexOfLinkL( + const MVPbkContactLink& /*aContactLink*/) const + { + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::AddObserverL +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::AddObserverL( + MVPbkContactViewObserver& aObserver) + { + VPbkEngUtils::MAsyncCallback* notifyObserver = + VPbkEngUtils::CreateAsyncCallbackLC( + *this, + &CVPbkFoldingContactView::DoAddObserverL, + &CVPbkFoldingContactView::AddObserverError, + aObserver); + iAsyncOperation.CallbackL(notifyObserver); + CleanupStack::Pop(notifyObserver); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::DoAddObserverL +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::DoAddObserverL( + MVPbkContactViewObserver& aObserver) + { + TInt err( iObservers.InsertInAddressOrder( &aObserver ) ); + if ( err != KErrNone && err != KErrAlreadyExists ) + { + User::Leave( err ); + } + + // this view is always ready + aObserver.ContactViewReady(*this); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::AddObserverError +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::AddObserverError( + MVPbkContactViewObserver& aObserver, TInt aError) + { + aObserver.ContactViewError(*this, aError, EFalse); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::SendAsyncUnavailableAndReadyEventL +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::SendAsyncUnavailableAndReadyEventL() + { + // Send first unvavailable event... + VPbkEngUtils::MAsyncCallback* notifyObserver = + VPbkEngUtils::CreateAsyncCallbackLC( + *this, + &CVPbkFoldingContactView::DoSignalObserversViewUnavailable, + &CVPbkFoldingContactView::DoSignalObserversViewError, + *iObservers[0]);//Observer is actually not used by DoSignal* + iAsyncOperation.CallbackL(notifyObserver); + CleanupStack::Pop(notifyObserver); + + // ...then ready event. This is how views must behave. + notifyObserver = VPbkEngUtils::CreateAsyncCallbackLC( + *this, + &CVPbkFoldingContactView::DoSignalObserversViewReady, + &CVPbkFoldingContactView::DoSignalObserversViewError, + *iObservers[0]);//Observer is actually not used by DoSignal* + iAsyncOperation.CallbackL( notifyObserver ); + CleanupStack::Pop( notifyObserver ); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::DoSignalObserversViewReady +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::DoSignalObserversViewReady( + MVPbkContactViewObserver& /*aObserver*/) + { + SendEventToObservers(*this, iObservers, + &MVPbkContactViewObserver::ContactViewReady); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::DoSignalObserversViewUnavailable +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::DoSignalObserversViewUnavailable( + MVPbkContactViewObserver& /*aObserver*/) + { + SendEventToObservers( *this, iObservers, + &MVPbkContactViewObserver::ContactViewUnavailable ); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::DoSignalObserversViewError +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::DoSignalObserversViewError( + MVPbkContactViewObserver& /* aObserver */, + TInt aError ) + { + SendEventToObservers(*this, iObservers, + &MVPbkContactViewObserver::ContactViewError, aError, EFalse ); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::RemoveObserver +// --------------------------------------------------------------------------- +// +void CVPbkFoldingContactView::RemoveObserver( + MVPbkContactViewObserver& aObserver) + { + TInt index( iObservers.FindInAddressOrder( &aObserver ) ); + if (index != KErrNotFound) + { + iObservers.Remove(index); + } + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::MatchContactStore +// --------------------------------------------------------------------------- +// +TBool CVPbkFoldingContactView::MatchContactStore( + const TDesC& aContactStoreUri) const + { + return DoMatchContactStore(*iViewDefinition, + TVPbkContactStoreUriPtr::EContactStoreUriAllComponents, + aContactStoreUri); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::MatchContactStoreDomain +// --------------------------------------------------------------------------- +// +TBool CVPbkFoldingContactView::MatchContactStoreDomain( + const TDesC& aContactStoreDomain) const + { + return DoMatchContactStore(*iViewDefinition, + TVPbkContactStoreUriPtr::EContactStoreUriStoreType, + aContactStoreDomain); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::CreateBookmarkLC +// --------------------------------------------------------------------------- +// +MVPbkContactBookmark* CVPbkFoldingContactView::CreateBookmarkLC( + TInt aIndex ) const + { + __ASSERT_ALWAYS( aIndex >= 0, + VPbkError::Panic( VPbkError::EInvalidContactIndex ) ); + + return iFoldingContact->CreateBookmarkLC(); + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::IndexOfBookmarkL +// --------------------------------------------------------------------------- +// +TInt CVPbkFoldingContactView::IndexOfBookmarkL( + const MVPbkContactBookmark& aContactBookmark) const + { + const TVPbkFoldingContactBookmark* bookmark = + dynamic_cast(&aContactBookmark); + if (bookmark && iFoldingContact == &bookmark->Contact()) + { + // Folding view has always only one contact in index 0 + return 0; + } + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ViewFiltering +// --------------------------------------------------------------------------- +// +MVPbkContactViewFiltering* CVPbkFoldingContactView::ViewFiltering() + { + // Folding view doesn't support filtering yet. + return NULL; + } + +// --------------------------------------------------------------------------- +// CVPbkFoldingContactView::ExpandLC +// --------------------------------------------------------------------------- +// +MVPbkContactViewBase* CVPbkFoldingContactView::ExpandLC( + MVPbkContactViewObserver& aObserver, + const MVPbkFieldTypeList& aSortOrder) const + { + /// Folding view can be expanded if it has one sub view definition. + /// If it has more than one then the rest of subview definitions are + /// ignored. + if ( iViewDefinition->SubViewCount() >= 1 ) + { + // Create a view according to first subview definition. + return iContactManager.CreateContactViewLC( + aObserver, iViewDefinition->SubViewAt( 0 ), aSortOrder ); + } + return NULL; + } + +//End of file