phonebookengines/contactsmodel/cntview/SubView.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <cntview.h>
       
    17 #include "CNTSTD.H"
       
    18 
       
    19 
       
    20 //#define CNTVIEW_API_PROFILING
       
    21 // To see the diferences between class versions check the in source documentation of TContactViewEvent
       
    22 const TUint KClassVersion1 = 1;
       
    23 const TUint KClassVersion2 = 2;
       
    24 
       
    25 //
       
    26 // CContactSubView.
       
    27 //
       
    28 
       
    29 CContactSubView::CContactSubView(const CContactDatabase& aDb,CContactViewBase& aView)
       
    30 	: CContactViewBase(aDb),iView(aView), iClassVersion(KClassVersion1)
       
    31 	{
       
    32 	}
       
    33 
       
    34 CContactSubView::CContactSubView(const CContactDatabase& aDb,const CContactSubView& aView)
       
    35 	: CContactViewBase(aDb),iView(aView.iView)
       
    36 	{
       
    37 	}
       
    38 
       
    39 CContactSubView::~CContactSubView()
       
    40 	{
       
    41 	iView.Close(*this);
       
    42 	delete iRange;
       
    43 	iRange=NULL;
       
    44 	}
       
    45 
       
    46 EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aBoundary)
       
    47 /** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's
       
    48 criteria.
       
    49 
       
    50 When adding/deleting contacts in the view, MContactViewObserver observer will receive 
       
    51 TContactViewEvent events with iInt parameter set to KErrNone.
       
    52 
       
    53 @param aObserver An observer that receives notifications when this view is 
       
    54 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
    55 event when the view is ready. An attempt to use the view before this notification 
       
    56 causes a panic.
       
    57 @param aDb The database containing the contact items.
       
    58 @param aView The underlying view.
       
    59 @param aBoundary A string containing the sub view criteria. Possible values 
       
    60 are: <, >, <=, or >=, followed by a character.
       
    61 @return The newly constructed sub view object. */
       
    62 	{
       
    63 #ifdef CNTVIEW_API_PROFILING
       
    64 	RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n"));
       
    65 #endif
       
    66 	CContactSubView* self=new(ELeave) CContactSubView(aDb,aView);
       
    67 	CleanupStack::PushL(self);
       
    68 	self->ConstructL(aObserver,aBoundary);
       
    69 	CleanupStack::Pop(self); 
       
    70 	return self;
       
    71 	}
       
    72 
       
    73 EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aLowBoundary,const TDesC& aHighBoundary)
       
    74 /** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's 
       
    75 upper and lower boundary criteria.
       
    76 
       
    77 When adding/deleting contacts in the view, MContactViewObserver observer will receive 
       
    78 TContactViewEvent events with iInt parameter set to KErrNone.
       
    79 
       
    80 @param aObserver An observer that receives notifications when this view is 
       
    81 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
    82 event when the view is ready. An attempt to use the view before this notification 
       
    83 causes a panic.
       
    84 @param aDb The database containing the contact items.
       
    85 @param aView The underlying view.
       
    86 @param aLowBoundary A string containing the sub view's lower boundary criteria. 
       
    87 Possible values are: > or >=, followed by a character.
       
    88 @param aHighBoundary A string containing the sub view's upper boundary criteria. 
       
    89 Possible values are: < or <=, followed by a character.
       
    90 @return The newly constructed sub view object. */
       
    91 	{
       
    92 #ifdef CNTVIEW_API_PROFILING
       
    93 	RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n"));
       
    94 #endif
       
    95 	CContactSubView* self=new(ELeave) CContactSubView(aDb,aView);
       
    96 	CleanupStack::PushL(self);
       
    97 	self->ConstructL(aObserver,aLowBoundary,aHighBoundary);
       
    98 	CleanupStack::Pop(self); 
       
    99 	return self;
       
   100 	}
       
   101 
       
   102 EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aBoundary)
       
   103 /** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's 
       
   104 criteria.
       
   105 
       
   106 When adding/deleting contacts in the view, MContactViewObserver observer will receive 
       
   107 TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item
       
   108 
       
   109 @param aObserver An observer that receives notifications when this view is 
       
   110 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   111 event when the view is ready. An attempt to use the view before this notification 
       
   112 causes a panic.
       
   113 @param aDb The database containing the contact items.
       
   114 @param aView The underlying view.
       
   115 @param aBoundary A string containing the sub view criteria. Possible values 
       
   116 are: <, >, <=, or >=, followed by a character.
       
   117 @return The newly constructed sub view object. */
       
   118 	{
       
   119 #ifdef CNTVIEW_API_PROFILING
       
   120 	RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n"));
       
   121 #endif
       
   122 	CContactSubView* self=new(ELeave) CContactSubView(aDb,aView);
       
   123 	CleanupStack::PushL(self);
       
   124 	self->ConstructL(aObserver,aBoundary);
       
   125 	self->iClassVersion = KClassVersion2;
       
   126 	CleanupStack::Pop(self); 
       
   127 	return self;
       
   128 	}
       
   129 
       
   130 EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary)
       
   131 /** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's
       
   132 upper and lower boundary criteria.
       
   133 
       
   134 When adding/deleting contacts in the view, MContactViewObserver observer will receive 
       
   135 TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item
       
   136 
       
   137 @param aObserver An observer that receives notifications when this view is 
       
   138 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   139 event when the view is ready. An attempt to use the view before this notification 
       
   140 causes a panic.
       
   141 @param aDb The database containing the contact items.
       
   142 @param aView The underlying view.
       
   143 @param aLowBoundary A string containing the sub view's lower boundary criteria. 
       
   144 Possible values are: > or >=, followed by a character.
       
   145 @param aHighBoundary A string containing the sub view's upper boundary criteria. 
       
   146 Possible values are: < or <=, followed by a character.
       
   147 @return The newly constructed sub view object. */
       
   148 	{
       
   149 #ifdef CNTVIEW_API_PROFILING
       
   150 	RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n"));
       
   151 #endif
       
   152 	CContactSubView* self=new(ELeave) CContactSubView(aDb,aView);
       
   153 	CleanupStack::PushL(self);
       
   154 	self->ConstructL(aObserver,aLowBoundary,aHighBoundary);
       
   155 	self->iClassVersion = KClassVersion2;
       
   156 	CleanupStack::Pop(self);
       
   157 	return self;
       
   158 	}
       
   159 
       
   160 /**
       
   161  * This is a reserved virtual exported function that is used for BC proofing 
       
   162  * against present and future additions of new exported virtual functions.
       
   163  @return Any return values of the helper methods called from this function or NULL.
       
   164  */
       
   165 TAny* CContactSubView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams)
       
   166 	{
       
   167 	return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams);
       
   168 	}
       
   169 
       
   170 void CContactSubView::CommonConstructL(MContactViewObserver& aObserver)
       
   171 	{
       
   172 	CContactViewBase::ConstructL();
       
   173 	OpenL(aObserver);
       
   174 	iView.OpenL(*this);
       
   175 	}
       
   176 
       
   177 void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aBoundary)
       
   178 	{
       
   179 	CommonConstructL(aObserver);
       
   180 	TBuf<KMaxBoundaryMatchLength+2> boundary(aBoundary);
       
   181 	CContactViewRangeBase::TCriteria criteria(DecodeBoundary(boundary));
       
   182 	switch (criteria)
       
   183 		{
       
   184 		case CContactViewRangeBase::ELessThan:
       
   185 		case CContactViewRangeBase::ELessThanOrEqualTo:
       
   186 			iRange=NULL;
       
   187 			iRange=CContactViewLowRange::NewL(iView,boundary,criteria);
       
   188 			break;
       
   189 		case CContactViewRangeBase::EGreaterThan:
       
   190 		case CContactViewRangeBase::EGreaterThanOrEqualTo:
       
   191 			iRange=NULL;
       
   192 			iRange=CContactViewHighRange::NewL(iView,boundary,criteria);
       
   193 			break;
       
   194 		default:
       
   195 			ASSERT(EFalse);
       
   196 		}
       
   197 	}
       
   198 
       
   199 void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary)
       
   200 	{
       
   201 	CommonConstructL(aObserver);
       
   202 	TBuf<KMaxBoundaryMatchLength+2> lowBoundary(aLowBoundary);
       
   203 	CContactViewRangeBase::TCriteria lowCriteria(DecodeBoundary(lowBoundary));
       
   204 	TBuf<KMaxBoundaryMatchLength+2> highBoundary(aHighBoundary);
       
   205 	CContactViewRangeBase::TCriteria highCriteria(DecodeBoundary(highBoundary));
       
   206 	iRange=NULL;
       
   207 	iRange=CContactViewRange::NewL(iView,lowBoundary,lowCriteria,highBoundary,highCriteria);
       
   208 	}
       
   209 
       
   210 
       
   211 CContactViewRangeBase::TCriteria CContactSubView::DecodeBoundary(TDes& aBoundary) const
       
   212 	{
       
   213 	CContactViewRangeBase::TCriteria criteria(CContactViewRangeBase::ELessThan);
       
   214 
       
   215 	switch (aBoundary[0])
       
   216 		{
       
   217 		case '<':
       
   218 			criteria=CContactViewRangeBase::ELessThan;
       
   219 			break;
       
   220 		case '>':
       
   221 			criteria=CContactViewRangeBase::EGreaterThan;
       
   222 			break;
       
   223 		default:
       
   224 			__ASSERT_DEBUG(EFalse,Panic(ECntPanicNoViewIndexMatchCriteria));
       
   225 		}
       
   226 
       
   227 	aBoundary.Delete(0,1);	// Delete first char.
       
   228 
       
   229 	if (aBoundary[0]=='=')
       
   230 		{
       
   231 		switch (criteria)
       
   232 			{
       
   233 			case CContactViewRangeBase::ELessThan:
       
   234 				criteria=CContactViewRangeBase::ELessThanOrEqualTo;
       
   235 				break;
       
   236 			case CContactViewRangeBase::EGreaterThan:
       
   237 				criteria=CContactViewRangeBase::EGreaterThanOrEqualTo;
       
   238 				break;
       
   239 			}
       
   240 		aBoundary.Delete(0,1);	// Delete first char.
       
   241 		}
       
   242 
       
   243 	return criteria;
       
   244 	}
       
   245 
       
   246 TContactItemId CContactSubView::AtL(TInt aIndex) const
       
   247 /** Gets the contact item ID at the specified index into the sub view.
       
   248 
       
   249 In release builds, zero is returned if the sub view's upper and lower boundaries 
       
   250 have not been set, (in debug builds, a panic occurs).
       
   251 
       
   252 @param aIndex Index into the sub view of a contact item ID. 
       
   253 @leave KErrNotFound aIndex is outside the bounds of the sub view's array.
       
   254 @return The contact item ID. */
       
   255 	{
       
   256 	if (iRange->IndicesValid())
       
   257 		{
       
   258 		if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex()))
       
   259 			{
       
   260 			//Out of Bounds 
       
   261 			User::Leave(KErrNotFound);
       
   262 			}	
       
   263 		return iView.AtL(MapToUnderlyingViewIndex(aIndex));
       
   264 		}
       
   265 	__ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView));
       
   266 	return 0;
       
   267 	}
       
   268 
       
   269 const CViewContact& CContactSubView::ContactAtL(TInt aIndex) const
       
   270 /** Gets the contact item at the specified index into the sub view.
       
   271 
       
   272 A NULL contact item is returned if the sub view's upper and lower boundaries 
       
   273 have not been set (in debug builds, a panic occurs).
       
   274 
       
   275 @param aIndex Index into the sub view of the required item.
       
   276 @leave KErrNotFound aIndex is outside the bounds of the sub view's array.
       
   277 @return The contact item. */
       
   278 	{
       
   279 	if (iRange->IndicesValid())
       
   280 		{
       
   281 		if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex()))
       
   282 			{
       
   283 			//Out of Bounds 
       
   284 			User::Leave(KErrNotFound);
       
   285 			}	
       
   286 		return iView.ContactAtL(MapToUnderlyingViewIndex(aIndex));
       
   287 		}
       
   288 	__ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView));
       
   289 	// the following code is never executed and is purely to stop the compiler warnings
       
   290 	const CViewContact* nullContact=NULL;
       
   291 	return *nullContact;
       
   292 	}
       
   293 
       
   294 TInt CContactSubView::CountL() const
       
   295 /** Gets the number of contact item IDs in the sub view.
       
   296 
       
   297 Zero is returned if the sub view's upper and lower boundaries have not been 
       
   298 set.
       
   299 
       
   300 @return The number of contact item IDs in the sub view. */
       
   301 	{
       
   302 	if (iRange->IndicesValid())
       
   303 		{
       
   304 		return iRange->HighIndex()-iRange->LowIndex()+1;
       
   305 		}
       
   306 	return 0;
       
   307 	}
       
   308 
       
   309 TInt CContactSubView::FindL(TContactItemId aId) const
       
   310 /** Finds the index into the sub view of the specified contact item.
       
   311 
       
   312 @param aId The contact item ID to search for. 
       
   313 @return The index of the first matching item in the sub view or KErrNotFound 
       
   314 if the sub view's upper and lower boundaries have not been set or if the item 
       
   315 is not in the sub view. */
       
   316 	{
       
   317 	const TInt index=iView.FindL(aId);
       
   318 	if (iRange->IndicesValid() && index>=iRange->LowIndex() && index<=iRange->HighIndex())
       
   319 		{
       
   320 		return MapToSubViewIndex(index);
       
   321 		}
       
   322 	return KErrNotFound;
       
   323 	}
       
   324 
       
   325 HBufC* CContactSubView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const
       
   326 /** Returns a descriptor containing the contents of all fields for an item in the 
       
   327 sub view.
       
   328 
       
   329 NULL is returned if the sub view's upper and lower boundaries have not been 
       
   330 set (in debug builds, a panic occurs).
       
   331 
       
   332 @param aIndex The index into the sub view of the contact item.
       
   333 @param aSeparator The string to use to separate the fields.
       
   334 @return Pointer to the contact item descriptor. */
       
   335 	{
       
   336 	if (iRange->IndicesValid())
       
   337 		{
       
   338 		return iView.AllFieldsLC(MapToUnderlyingViewIndex(aIndex),aSeparator);
       
   339 		}
       
   340 	__ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView));
       
   341 	return NULL;
       
   342 	}
       
   343 
       
   344 const RContactViewSortOrder& CContactSubView::SortOrderL() const
       
   345 /** Gets the underlying view's sort order.
       
   346 
       
   347 @return The sort order. */
       
   348 	{
       
   349 	return iView.SortOrderL();
       
   350 	}
       
   351 
       
   352 TContactViewPreferences CContactSubView::ContactViewPreferences()
       
   353 /** Gets the underlying view's view preferences.
       
   354 
       
   355 @return The view preferences. */
       
   356 	{
       
   357 	return iView.ContactViewPreferences();
       
   358 	}
       
   359 
       
   360 #ifdef _DEBUG
       
   361 void CContactSubView::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
   362 #else
       
   363 void CContactSubView::HandleContactViewEvent(const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent)
       
   364 #endif
       
   365 	{
       
   366 	ASSERT(&aView==&iView);
       
   367 	TBool notifyObservers=ETrue;
       
   368 	TContactViewEvent event=aEvent;
       
   369 	switch (event.iEventType)
       
   370 		{
       
   371 		case TContactViewEvent::EUnavailable:
       
   372 		case TContactViewEvent::ESortError:
       
   373 		case TContactViewEvent::EServerError:
       
   374 			iState=ENotReady;
       
   375 			break;
       
   376 		case TContactViewEvent::EReady:
       
   377 		case TContactViewEvent::ESortOrderChanged:
       
   378 			{
       
   379 			TRAPD(err,iRange->SetL());
       
   380 			if (err)
       
   381 				{
       
   382 				event.iEventType=TContactViewEvent::EIndexingError;
       
   383 				event.iInt=err;
       
   384 				}
       
   385 			else
       
   386 				{
       
   387 				iState=EReady;
       
   388 				}
       
   389 			}
       
   390 			break;
       
   391 		case TContactViewEvent::EItemAdded:
       
   392 		case TContactViewEvent::EItemRemoved:
       
   393 //			notifyObservers=iRange->Update(event);
       
   394 			TRAPD(err,iRange->SetL());
       
   395 			if (err)
       
   396 				{
       
   397 				event.iEventType=TContactViewEvent::EIndexingError;
       
   398 				event.iInt=err;
       
   399 				}
       
   400 			else
       
   401 				{
       
   402 				//get the contact index within subview
       
   403 				if(iClassVersion == KClassVersion2)
       
   404 					{
       
   405 					if(iRange->LowIndex() == KErrNotFound)
       
   406 						{
       
   407 						notifyObservers = EFalse;
       
   408 						}
       
   409 					else
       
   410 						{
       
   411 						event.iInt -= iRange->LowIndex();
       
   412 						}
       
   413 					}
       
   414 				else
       
   415 					{
       
   416 					event.iInt = KErrNone;
       
   417 					}
       
   418 				}	
       
   419 			break;
       
   420 		case TContactViewEvent::EGroupChanged:
       
   421 			break;
       
   422 		default:
       
   423 			ASSERT(EFalse);
       
   424 		}
       
   425 
       
   426 	if (notifyObservers)
       
   427 		{
       
   428 		NotifyObservers(event);
       
   429 		}
       
   430 	}
       
   431 
       
   432 TInt CContactSubView::MapToUnderlyingViewIndex(TInt aSubViewIndex) const
       
   433 	{
       
   434 	ASSERT(iRange->IndicesValid());
       
   435 	return aSubViewIndex+iRange->LowIndex();
       
   436 	}
       
   437 
       
   438 TInt CContactSubView::MapToSubViewIndex(TInt aUnderlyingViewIndex) const
       
   439 	{
       
   440 	ASSERT(iRange->IndicesValid());
       
   441 	return aUnderlyingViewIndex-iRange->LowIndex();
       
   442 	}