phonebookengines/contactsmodel/cntview/SubView.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
--- /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 <cntview.h>
+#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<KMaxBoundaryMatchLength+2> 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<KMaxBoundaryMatchLength+2> lowBoundary(aLowBoundary);
+	CContactViewRangeBase::TCriteria lowCriteria(DecodeBoundary(lowBoundary));
+	TBuf<KMaxBoundaryMatchLength+2> 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();
+	}