diff -r 000000000000 -r e686773b3f54 phonebookengines/contactsmodel/cntview/SubView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/contactsmodel/cntview/SubView.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,442 @@ +// Copyright (c) 2001-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: +// + +#include +#include "CNTSTD.H" + + +//#define CNTVIEW_API_PROFILING +// To see the diferences between class versions check the in source documentation of TContactViewEvent +const TUint KClassVersion1 = 1; +const TUint KClassVersion2 = 2; + +// +// CContactSubView. +// + +CContactSubView::CContactSubView(const CContactDatabase& aDb,CContactViewBase& aView) + : CContactViewBase(aDb),iView(aView), iClassVersion(KClassVersion1) + { + } + +CContactSubView::CContactSubView(const CContactDatabase& aDb,const CContactSubView& aView) + : CContactViewBase(aDb),iView(aView.iView) + { + } + +CContactSubView::~CContactSubView() + { + iView.Close(*this); + delete iRange; + iRange=NULL; + } + +EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aBoundary) +/** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's +criteria. + +When adding/deleting contacts in the view, MContactViewObserver observer will receive +TContactViewEvent events with iInt parameter set to KErrNone. + +@param aObserver An observer that receives notifications when this view is +ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady +event when the view is ready. An attempt to use the view before this notification +causes a panic. +@param aDb The database containing the contact items. +@param aView The underlying view. +@param aBoundary A string containing the sub view criteria. Possible values +are: <, >, <=, or >=, followed by a character. +@return The newly constructed sub view object. */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); +#endif + CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); + CleanupStack::PushL(self); + self->ConstructL(aObserver,aBoundary); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aLowBoundary,const TDesC& aHighBoundary) +/** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's +upper and lower boundary criteria. + +When adding/deleting contacts in the view, MContactViewObserver observer will receive +TContactViewEvent events with iInt parameter set to KErrNone. + +@param aObserver An observer that receives notifications when this view is +ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady +event when the view is ready. An attempt to use the view before this notification +causes a panic. +@param aDb The database containing the contact items. +@param aView The underlying view. +@param aLowBoundary A string containing the sub view's lower boundary criteria. +Possible values are: > or >=, followed by a character. +@param aHighBoundary A string containing the sub view's upper boundary criteria. +Possible values are: < or <=, followed by a character. +@return The newly constructed sub view object. */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); +#endif + CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); + CleanupStack::PushL(self); + self->ConstructL(aObserver,aLowBoundary,aHighBoundary); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aBoundary) +/** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's +criteria. + +When adding/deleting contacts in the view, MContactViewObserver observer will receive +TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item + +@param aObserver An observer that receives notifications when this view is +ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady +event when the view is ready. An attempt to use the view before this notification +causes a panic. +@param aDb The database containing the contact items. +@param aView The underlying view. +@param aBoundary A string containing the sub view criteria. Possible values +are: <, >, <=, or >=, followed by a character. +@return The newly constructed sub view object. */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); +#endif + CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); + CleanupStack::PushL(self); + self->ConstructL(aObserver,aBoundary); + self->iClassVersion = KClassVersion2; + CleanupStack::Pop(self); + return self; + } + +EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary) +/** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's +upper and lower boundary criteria. + +When adding/deleting contacts in the view, MContactViewObserver observer will receive +TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item + +@param aObserver An observer that receives notifications when this view is +ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady +event when the view is ready. An attempt to use the view before this notification +causes a panic. +@param aDb The database containing the contact items. +@param aView The underlying view. +@param aLowBoundary A string containing the sub view's lower boundary criteria. +Possible values are: > or >=, followed by a character. +@param aHighBoundary A string containing the sub view's upper boundary criteria. +Possible values are: < or <=, followed by a character. +@return The newly constructed sub view object. */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); +#endif + CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); + CleanupStack::PushL(self); + self->ConstructL(aObserver,aLowBoundary,aHighBoundary); + self->iClassVersion = KClassVersion2; + CleanupStack::Pop(self); + return self; + } + +/** + * This is a reserved virtual exported function that is used for BC proofing + * against present and future additions of new exported virtual functions. + @return Any return values of the helper methods called from this function or NULL. + */ +TAny* CContactSubView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams) + { + return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams); + } + +void CContactSubView::CommonConstructL(MContactViewObserver& aObserver) + { + CContactViewBase::ConstructL(); + OpenL(aObserver); + iView.OpenL(*this); + } + +void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aBoundary) + { + CommonConstructL(aObserver); + TBuf boundary(aBoundary); + CContactViewRangeBase::TCriteria criteria(DecodeBoundary(boundary)); + switch (criteria) + { + case CContactViewRangeBase::ELessThan: + case CContactViewRangeBase::ELessThanOrEqualTo: + iRange=NULL; + iRange=CContactViewLowRange::NewL(iView,boundary,criteria); + break; + case CContactViewRangeBase::EGreaterThan: + case CContactViewRangeBase::EGreaterThanOrEqualTo: + iRange=NULL; + iRange=CContactViewHighRange::NewL(iView,boundary,criteria); + break; + default: + ASSERT(EFalse); + } + } + +void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary) + { + CommonConstructL(aObserver); + TBuf lowBoundary(aLowBoundary); + CContactViewRangeBase::TCriteria lowCriteria(DecodeBoundary(lowBoundary)); + TBuf highBoundary(aHighBoundary); + CContactViewRangeBase::TCriteria highCriteria(DecodeBoundary(highBoundary)); + iRange=NULL; + iRange=CContactViewRange::NewL(iView,lowBoundary,lowCriteria,highBoundary,highCriteria); + } + + +CContactViewRangeBase::TCriteria CContactSubView::DecodeBoundary(TDes& aBoundary) const + { + CContactViewRangeBase::TCriteria criteria(CContactViewRangeBase::ELessThan); + + switch (aBoundary[0]) + { + case '<': + criteria=CContactViewRangeBase::ELessThan; + break; + case '>': + criteria=CContactViewRangeBase::EGreaterThan; + break; + default: + __ASSERT_DEBUG(EFalse,Panic(ECntPanicNoViewIndexMatchCriteria)); + } + + aBoundary.Delete(0,1); // Delete first char. + + if (aBoundary[0]=='=') + { + switch (criteria) + { + case CContactViewRangeBase::ELessThan: + criteria=CContactViewRangeBase::ELessThanOrEqualTo; + break; + case CContactViewRangeBase::EGreaterThan: + criteria=CContactViewRangeBase::EGreaterThanOrEqualTo; + break; + } + aBoundary.Delete(0,1); // Delete first char. + } + + return criteria; + } + +TContactItemId CContactSubView::AtL(TInt aIndex) const +/** Gets the contact item ID at the specified index into the sub view. + +In release builds, zero is returned if the sub view's upper and lower boundaries +have not been set, (in debug builds, a panic occurs). + +@param aIndex Index into the sub view of a contact item ID. +@leave KErrNotFound aIndex is outside the bounds of the sub view's array. +@return The contact item ID. */ + { + if (iRange->IndicesValid()) + { + if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex())) + { + //Out of Bounds + User::Leave(KErrNotFound); + } + return iView.AtL(MapToUnderlyingViewIndex(aIndex)); + } + __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); + return 0; + } + +const CViewContact& CContactSubView::ContactAtL(TInt aIndex) const +/** Gets the contact item at the specified index into the sub view. + +A NULL contact item is returned if the sub view's upper and lower boundaries +have not been set (in debug builds, a panic occurs). + +@param aIndex Index into the sub view of the required item. +@leave KErrNotFound aIndex is outside the bounds of the sub view's array. +@return The contact item. */ + { + if (iRange->IndicesValid()) + { + if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex())) + { + //Out of Bounds + User::Leave(KErrNotFound); + } + return iView.ContactAtL(MapToUnderlyingViewIndex(aIndex)); + } + __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); + // the following code is never executed and is purely to stop the compiler warnings + const CViewContact* nullContact=NULL; + return *nullContact; + } + +TInt CContactSubView::CountL() const +/** Gets the number of contact item IDs in the sub view. + +Zero is returned if the sub view's upper and lower boundaries have not been +set. + +@return The number of contact item IDs in the sub view. */ + { + if (iRange->IndicesValid()) + { + return iRange->HighIndex()-iRange->LowIndex()+1; + } + return 0; + } + +TInt CContactSubView::FindL(TContactItemId aId) const +/** Finds the index into the sub view of the specified contact item. + +@param aId The contact item ID to search for. +@return The index of the first matching item in the sub view or KErrNotFound +if the sub view's upper and lower boundaries have not been set or if the item +is not in the sub view. */ + { + const TInt index=iView.FindL(aId); + if (iRange->IndicesValid() && index>=iRange->LowIndex() && index<=iRange->HighIndex()) + { + return MapToSubViewIndex(index); + } + return KErrNotFound; + } + +HBufC* CContactSubView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const +/** Returns a descriptor containing the contents of all fields for an item in the +sub view. + +NULL is returned if the sub view's upper and lower boundaries have not been +set (in debug builds, a panic occurs). + +@param aIndex The index into the sub view of the contact item. +@param aSeparator The string to use to separate the fields. +@return Pointer to the contact item descriptor. */ + { + if (iRange->IndicesValid()) + { + return iView.AllFieldsLC(MapToUnderlyingViewIndex(aIndex),aSeparator); + } + __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); + return NULL; + } + +const RContactViewSortOrder& CContactSubView::SortOrderL() const +/** Gets the underlying view's sort order. + +@return The sort order. */ + { + return iView.SortOrderL(); + } + +TContactViewPreferences CContactSubView::ContactViewPreferences() +/** Gets the underlying view's view preferences. + +@return The view preferences. */ + { + return iView.ContactViewPreferences(); + } + +#ifdef _DEBUG +void CContactSubView::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent) +#else +void CContactSubView::HandleContactViewEvent(const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent) +#endif + { + ASSERT(&aView==&iView); + TBool notifyObservers=ETrue; + TContactViewEvent event=aEvent; + switch (event.iEventType) + { + case TContactViewEvent::EUnavailable: + case TContactViewEvent::ESortError: + case TContactViewEvent::EServerError: + iState=ENotReady; + break; + case TContactViewEvent::EReady: + case TContactViewEvent::ESortOrderChanged: + { + TRAPD(err,iRange->SetL()); + if (err) + { + event.iEventType=TContactViewEvent::EIndexingError; + event.iInt=err; + } + else + { + iState=EReady; + } + } + break; + case TContactViewEvent::EItemAdded: + case TContactViewEvent::EItemRemoved: +// notifyObservers=iRange->Update(event); + TRAPD(err,iRange->SetL()); + if (err) + { + event.iEventType=TContactViewEvent::EIndexingError; + event.iInt=err; + } + else + { + //get the contact index within subview + if(iClassVersion == KClassVersion2) + { + if(iRange->LowIndex() == KErrNotFound) + { + notifyObservers = EFalse; + } + else + { + event.iInt -= iRange->LowIndex(); + } + } + else + { + event.iInt = KErrNone; + } + } + break; + case TContactViewEvent::EGroupChanged: + break; + default: + ASSERT(EFalse); + } + + if (notifyObservers) + { + NotifyObservers(event); + } + } + +TInt CContactSubView::MapToUnderlyingViewIndex(TInt aSubViewIndex) const + { + ASSERT(iRange->IndicesValid()); + return aSubViewIndex+iRange->LowIndex(); + } + +TInt CContactSubView::MapToSubViewIndex(TInt aUnderlyingViewIndex) const + { + ASSERT(iRange->IndicesValid()); + return aUnderlyingViewIndex-iRange->LowIndex(); + }