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