phonebookengines/contactsmodel/cntsrv/src/CViewSubSessions.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     1 // Copyright (c) 2005-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19  @released
       
    20 */
       
    21 
       
    22 
       
    23 #include "cntviewprivate.h"
       
    24 #include "CViewSubSessions.h"
       
    25 #include "CCntIpcCodes.h"
       
    26 #include "CCntDbManager.h"
       
    27 #include "CCntServer.h"
       
    28 #include <cntviewstore.h>
       
    29 #include "CCntLogger.h"
       
    30 #include "CCntStateMachine.h"
       
    31 
       
    32 
       
    33 extern void DebugLogViewNotification(const TDesC& aMethod, const TContactViewEvent& aEvent);
       
    34 
       
    35 
       
    36 CViewSubSessionQueue::CViewSubSessionQueue()
       
    37 	{
       
    38 	}
       
    39 
       
    40 
       
    41 CViewSubSessionQueue::~CViewSubSessionQueue()
       
    42 	{
       
    43 	iEvents.Close();
       
    44 	}
       
    45 
       
    46 
       
    47 void CViewSubSessionQueue::QueueEvent(const TContactViewEvent& aEvent)
       
    48 	{
       
    49 	const TInt KInvalidValueForRemoteView = -1;
       
    50 
       
    51 	TBool haveToAddEventInQueue = ETrue;
       
    52 
       
    53  	if (iRequestPending)
       
    54  		{
       
    55 		if(aEvent.iEventType == TContactViewEvent::EItemAdded)
       
    56 			{
       
    57 			// is this first event sent? If yes and if the event is an 
       
    58 			// EItemAdded event send first a fake event. 
       
    59 			// This is because all EItemAdded should be sorted before send them
       
    60 
       
    61 			TContactViewEvent event;
       
    62 			event.iEventType = TContactViewEvent::EItemAdded;
       
    63 			event.iContactId = KInvalidValueForRemoteView;
       
    64 			event.iInt = KInvalidValueForRemoteView;
       
    65 			SendEventL(event);
       
    66 			}
       
    67 		else
       
    68 			{
       
    69 			SendEventL(aEvent);
       
    70 			haveToAddEventInQueue = EFalse;
       
    71 			}
       
    72  		}
       
    73 
       
    74 	if (haveToAddEventInQueue  && !iQueueError)
       
    75 		{
       
    76 		// There are two requirements for this queue of events:
       
    77 		// 1. The iInt values for events in the Q at any given point in time
       
    78 		//    should match the index of the underlying localview array. i.e If the addition/removal
       
    79 		//    of a contact has caused the position of other contacts items to change in the underlying localview
       
    80 		//    then previous events sent by them in this Q will have old iInt values and these need to be corrected.
       
    81 		
       
    82 		// 2. When the client gets these events in order, it should have a valid view after every event,
       
    83 		//    ie. if we have 2 additions, at positions 0 and 1, 
       
    84 		//    we cannot send the event for addition at position 1 before the addition at position 0.
       
    85 		//	
       
    86 		// These requirements are fulfilled using the following algorithm.
       
    87 		// Events are inserted in the queue using following two condition
       
    88 		// 1. EItemAdded -
       
    89 		//    1.1 Find if an existing EItemAdded events iInt is greater or equal with incoming events iInt.
       
    90 		//        if found,insert event before the found one and increment the iInt of the rest event by 1
       
    91 		//    1.2 if no match is found with same iInt, modify its iInt value with incoming events iInt, 
       
    92 		//        then append to the event queue.
       
    93 		//	  1.3 If no EItemAdded events are in queue, append this one to Queue.
       
    94 		// 2. EItemRemoved -
       
    95 		//    2.1 Find if an existing EItemAdded events iInt matches with incoming EItemRemoved events iInt.
       
    96 		//        if found, then remove that EItemAdded event from the Queue and decrement rest of the 
       
    97 		//        events iInt by 1.
       
    98 		//    2.2 if no match is found with same iInt, then insert the event before next greater iInt event
       
    99 		//        and then decerement the iInt value of rest of the event by 1.
       
   100 		//	  2.3 if no events greater than this  then append this one to Queue.
       
   101 		
       
   102 		TContactViewEvent event;
       
   103 		event.iEventType = aEvent.iEventType;
       
   104 		event.iContactId = aEvent.iContactId;
       
   105 		event.iInt = aEvent.iInt;		
       
   106 		TInt eventsCount = iEvents.Count();		
       
   107 		TUint pos=0;		
       
   108 		if( event.iEventType == TContactViewEvent::EItemAdded )
       
   109 			{	
       
   110 			TInt lastItemRemovedPosition = KErrNotFound;
       
   111 			//first check if this add event is not generated by a contact item change
       
   112 			for( pos=0; pos<eventsCount; ++pos ) 
       
   113 				{
       
   114 				if( iEvents[pos].iContactId == aEvent.iContactId && 
       
   115 							iEvents[pos].iEventType == TContactViewEvent::EItemRemoved )
       
   116 					{
       
   117 					lastItemRemovedPosition = pos;
       
   118 					}
       
   119 				}
       
   120 			if( lastItemRemovedPosition != KErrNotFound ) 
       
   121 				{
       
   122 				++lastItemRemovedPosition;
       
   123 				if(lastItemRemovedPosition < eventsCount)
       
   124 					{
       
   125 					for( pos = lastItemRemovedPosition-1; pos < eventsCount;++pos ) 
       
   126 						{
       
   127 						if(iEvents[pos].iInt >= aEvent.iInt && 
       
   128 								iEvents[pos].iContactId != aEvent.iContactId)
       
   129 							{
       
   130 							if( iEvents[pos].iEventType == TContactViewEvent::EItemRemoved || iEvents[pos].iEventType == TContactViewEvent::EItemAdded)  
       
   131 								{
       
   132 								iEvents[pos].iInt++;
       
   133 								}
       
   134 							}
       
   135 						}
       
   136 					iQueueError = iEvents.Insert(aEvent, lastItemRemovedPosition);		
       
   137 					}
       
   138 				else
       
   139 					{
       
   140 					iQueueError = iEvents.Append(aEvent);	
       
   141 					}
       
   142 				}
       
   143 			else
       
   144 				{				
       
   145 				TBool haveToAppendEvent = ETrue; 			
       
   146 				for( pos=0; pos<eventsCount; ++pos ) 
       
   147 					{
       
   148 					if(iEvents[pos].iEventType == TContactViewEvent::EItemAdded)
       
   149 						{
       
   150 						if(iEvents[pos].iInt >= event.iInt)
       
   151 							{
       
   152 							iQueueError = iEvents.Insert(event, pos);
       
   153 							eventsCount=iEvents.Count();
       
   154 							for(TUint loop=pos+1; loop<eventsCount; ++loop)
       
   155 								{
       
   156 								if( iEvents[pos].iEventType == TContactViewEvent::EItemRemoved || iEvents[pos].iEventType == TContactViewEvent::EItemAdded)
       
   157 									{
       
   158 									iEvents[loop].iInt++;
       
   159 									}
       
   160 								}						
       
   161 							haveToAppendEvent = EFalse;										
       
   162 							break;
       
   163 							}				
       
   164 						}
       
   165 					}
       
   166 				if( haveToAppendEvent )
       
   167 					{
       
   168 					iQueueError = iEvents.Append(event);
       
   169 				 	}
       
   170 				}
       
   171 			}
       
   172 		else 
       
   173 			{
       
   174 			iQueueError = iEvents.Append(event);	
       
   175 			}
       
   176 		DEBUG_PRINTVN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] CViewSubSessionQueue::QueueEvent(): ->Q:"), event);
       
   177 		}
       
   178 	}
       
   179 
       
   180 
       
   181 void CViewSubSessionQueue::RequestEvent(const RMessage2& aMessage)
       
   182 	{
       
   183 	__ASSERT_DEBUG(!iRequestPending,User::Leave(KErrAlreadyExists)); // can only leave in debug mode
       
   184 	if (!iRequestPending)
       
   185 		{
       
   186 		iMessage=aMessage;
       
   187 		iRequestPending=ETrue;
       
   188 		if (iQueueError)
       
   189 			{
       
   190 			TContactViewEvent errorEvent(TContactViewEvent::EServerError,iQueueError);
       
   191 			iQueueError=KErrNone;
       
   192 			SendEventL(errorEvent);
       
   193 			}
       
   194 		else if (iEvents.Count()>0)
       
   195 			{
       
   196 			SendEventL(iEvents[0]);
       
   197 			iEvents.Remove(0);
       
   198 			}
       
   199 		}
       
   200 	}
       
   201 
       
   202 
       
   203 void CViewSubSessionQueue::CancelEventRequest()
       
   204 	{
       
   205 	if (iRequestPending)
       
   206 		{
       
   207 		iMessage.Complete(KErrCancel);
       
   208 		iRequestPending=EFalse;
       
   209 		}
       
   210 	}
       
   211 
       
   212 /**
       
   213 Send contact view event.
       
   214 
       
   215 @leave KErrNotFound In debug mode only, if there is a queue error.
       
   216 @leave KErrNotReady In debug mode only, if there is already an existing request still pending.
       
   217 @leave KErrBadDescriptor If there is a error writing aEvent to the RMessage2 to be sent.
       
   218 */
       
   219 void CViewSubSessionQueue::SendEventL(const TContactViewEvent& aEvent)
       
   220 	{
       
   221 	__ASSERT_DEBUG(!iQueueError,User::Leave(KErrNotFound));
       
   222 
       
   223 	if (!iRequestPending)
       
   224 		{
       
   225 		return;
       
   226 		}
       
   227 
       
   228    DEBUG_PRINTVN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] CViewSubSessionQueue::SendEventL(): Q->:"), aEvent);
       
   229 
       
   230 	TRAPD(err,iMessage.WriteL(KSlot0,TPckgC<TContactViewEvent>(aEvent)));
       
   231 	if (err)
       
   232 		{
       
   233 		iRequestPending=EFalse;
       
   234 		User::Leave(KErrBadDescriptor);//iMessage is completed in CCntSession::ServiceError()
       
   235 		}
       
   236 	else
       
   237 		{
       
   238 		iMessage.Complete(KErrNone);
       
   239 		}
       
   240 
       
   241 	iRequestPending=EFalse;
       
   242 	}
       
   243 
       
   244 
       
   245 /**
       
   246 Called if derived class ServiceL()'s do not consume the opcode.
       
   247 */
       
   248 TInt CViewSubSessionBase::ServiceL(const RMessage2& aMessage)
       
   249 	{
       
   250 	TInt reply(KErrNone);
       
   251 	switch (aMessage.Function())
       
   252 		{
       
   253 		case ECntViewCount:
       
   254 			CountL(aMessage);
       
   255 			break;
       
   256 		case ECntViewAt:
       
   257 			reply=AtL(aMessage);
       
   258 			break;
       
   259 		case ECntViewContactAtLength:
       
   260 			reply=ContactAtLengthL(aMessage);
       
   261 			break;
       
   262 		case ECntViewContactAt:
       
   263 			ContactAtL(aMessage);
       
   264 			break;
       
   265 		case ECntViewFind:
       
   266 			FindL(aMessage);
       
   267 			break;
       
   268 		case ECntAllFieldsLength:
       
   269 			reply=GetAllFieldsLengthL(aMessage);
       
   270 			break;
       
   271 		case ECntAllFieldsText:
       
   272 			GetAllFieldsTextL(aMessage);
       
   273 			break;
       
   274 		case ECntContactMatchingCriteriaExternalizedSize:
       
   275 			ContactMatchingCriteriaExternalizedSizeL(aMessage);
       
   276 			break;
       
   277 		case ECntGetContactMatchingCriteria:
       
   278 			GetContactMatchingCriteriaL(aMessage);
       
   279 			break;
       
   280 		case ECntGetIncludedTypes:
       
   281 			GetIncludedTypesL(aMessage);
       
   282 			break;
       
   283 		case ECntRequestViewEvent:
       
   284 			RequestViewEvent(aMessage);
       
   285 			reply=KErrNoComplete;
       
   286 			break;
       
   287 		case ECntCancelRequestViewEvent:
       
   288 			CancelRequestViewEvent();
       
   289 			break;
       
   290 		case ECntGetContactIds:
       
   291 			GetContactIdsL(aMessage);
       
   292 			break;
       
   293 		case ECntSendPluginUidToServer:
       
   294 			SendPluginUidToServer(aMessage);
       
   295 			break;
       
   296 		case ECntGetContactsMatchingFilter:
       
   297 			GetContactsMatchingFilterL(aMessage);
       
   298 			break;
       
   299 		case ECntGetSortPluginUidFromServer:
       
   300 			GetSortPluginUidFromServerL(aMessage);
       
   301 			break;
       
   302 		default:
       
   303 			User::Leave(KErrNotFound);
       
   304 			break;
       
   305 		}
       
   306 	return reply;
       
   307 	}
       
   308 
       
   309 
       
   310 CViewSubSessionBase::~CViewSubSessionBase()
       
   311 	{
       
   312 	delete iQueue;
       
   313 	delete iSortableText;
       
   314 	delete iContact;
       
   315 	DeleteFindContacts();
       
   316 	}
       
   317 
       
   318 
       
   319 CViewSubSessionBase::CViewSubSessionBase(CViewManager& aViewManager) : iViewManager(aViewManager),iContact(0)
       
   320 	{
       
   321 	}
       
   322 
       
   323 
       
   324 void CViewSubSessionBase::ConstructL()
       
   325 	{
       
   326 	iQueue = new(ELeave) CViewSubSessionQueue();
       
   327 	}
       
   328 
       
   329 
       
   330 void CViewSubSessionBase::CountL(const RMessage2& aMessage) const
       
   331 	{
       
   332 	TPckgBuf<TInt> pckg(iView->CountL());
       
   333 	aMessage.WriteL(0,pckg);
       
   334 	}
       
   335 
       
   336 
       
   337 TInt CViewSubSessionBase::AtL(const RMessage2& aMessage) const
       
   338 	{
       
   339 	TInt reply = KErrNone;
       
   340 	const TInt index=aMessage.Int0();
       
   341 	__ASSERT_ALWAYS(index>=0,User::Leave(KErrUnderflow));
       
   342 	if(!(index<iView->CountL()))
       
   343 		{
       
   344 		// Index is out of bounds.
       
   345 		reply=KErrNotFound;
       
   346 		return reply;
       
   347 		}
       
   348 	TPckgBuf<TContactItemId> pckg(iView->AtL(index));
       
   349 	aMessage.WriteL(1,pckg);
       
   350 	return reply;
       
   351 	}
       
   352 
       
   353 
       
   354 void CViewSubSessionBase::ContactAtL(const RMessage2& aMessage) const
       
   355 	{
       
   356 	const TInt externalizedSize=iContact->ExternalizedSize();
       
   357 	HBufC8* buf=HBufC8::NewLC(externalizedSize);
       
   358 	TPtr8 bufPtr(buf->Des());
       
   359 	RDesWriteStream writeStream(bufPtr);
       
   360 	CleanupClosePushL(writeStream);
       
   361 	writeStream << *iContact;
       
   362 	bufPtr.SetLength(externalizedSize);
       
   363 	aMessage.WriteL(0,*buf);
       
   364 	CleanupStack::PopAndDestroy(2); // writeStream, buf.
       
   365 	}
       
   366 
       
   367 
       
   368 /** 
       
   369 Return the size of the externalized contact data.
       
   370 
       
   371 @param aMessage.Int0() Index.
       
   372 @param aMessage.Ptr1() Package buffer to return size.
       
   373 */
       
   374 TInt CViewSubSessionBase::ContactAtLengthL(const RMessage2& aMessage) 
       
   375 	{
       
   376 	TInt reply=KErrNone;
       
   377 	TInt index = aMessage.Int0();
       
   378 
       
   379 	__ASSERT_ALWAYS(index>=0,User::Leave(KErrUnderflow));
       
   380 
       
   381 	if(!(index<iView->CountL()))
       
   382 		{
       
   383 		// Index is out of bounds.
       
   384 		reply=KErrNotFound;
       
   385 		return reply;
       
   386 		}
       
   387 
       
   388 	const CViewContact& contact=iView->ContactAtL(index);
       
   389 
       
   390 	delete iContact;
       
   391 	iContact=NULL;
       
   392 	iContact = CViewContact::NewL(contact);
       
   393 	
       
   394 	const TInt externalizedSize=iContact->ExternalizedSize();
       
   395 	TPckgBuf<TInt> pckg(externalizedSize);
       
   396 	aMessage.WriteL(1,pckg);
       
   397 
       
   398 	return reply;
       
   399 	}
       
   400 
       
   401 
       
   402 void CViewSubSessionBase::GetIncludedTypesL(const RMessage2& aMessage)
       
   403 	{
       
   404 	TPckgBuf<TContactViewPreferences> pckg(iView->ContactViewPreferences());
       
   405 	aMessage.WriteL(0,pckg);	
       
   406 	}
       
   407 
       
   408 
       
   409 void CViewSubSessionBase::DeleteFindContacts()
       
   410 	{
       
   411 	iContacts.ResetAndDestroy();
       
   412 	}
       
   413 
       
   414 
       
   415 #ifdef _DEBUG
       
   416 void CViewSubSessionBase::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
   417 #else
       
   418 void CViewSubSessionBase::HandleContactViewEvent(const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent)
       
   419 #endif
       
   420 	{
       
   421 	ASSERT(&aView==iView);
       
   422 	iQueue->QueueEvent(aEvent);
       
   423 	}
       
   424 
       
   425 
       
   426 /** 
       
   427 Match an array of search strings against the contacts in the view.
       
   428 
       
   429 The descriptor from the client contains a flag at the start to indicate if a
       
   430 prefix or substring search has been requested.
       
   431 
       
   432 @param aMessage.Ptr0() Size of contact data to read (to client).
       
   433 @param aMessage.Int1() Size of descriptor (from client).
       
   434 @param aMessage.Ptr2() Descriptor (from client).
       
   435 */
       
   436 void CViewSubSessionBase::ContactMatchingCriteriaExternalizedSizeL(const RMessage2& aMessage)
       
   437 	{
       
   438 	TPckgBuf<TInt> size;
       
   439 	aMessage.ReadL(1,size);
       
   440 	const TInt bufferSize = size();
       
   441 
       
   442 	// Restore buffer.
       
   443 	CBufFlat* buffer = CBufFlat::NewL(bufferSize);
       
   444 	CleanupStack::PushL(buffer);
       
   445 	buffer->ExpandL(0,bufferSize);
       
   446 	TPtr8 des(buffer->Ptr(0));
       
   447 	aMessage.ReadL(2,des);
       
   448 
       
   449 	// Internalize the data from the stream.
       
   450 	RBufReadStream readStream(*buffer);
       
   451 	CleanupClosePushL(readStream);
       
   452 
       
   453 	TBool prefixSearch = readStream.ReadUint32L(); 
       
   454 	const TInt numFindWords = readStream.ReadUint32L();
       
   455 	CPtrC16Array* findDesArray = new(ELeave) CPtrC16Array(numFindWords);
       
   456 	CleanupStack::PushL(findDesArray);
       
   457 
       
   458 	TInt findWordLength=0;
       
   459 	for (TInt i=0; i<numFindWords; ++i)
       
   460 		{
       
   461 		findWordLength = readStream.ReadUint32L();
       
   462 		HBufC* findword = HBufC::NewLC(readStream,findWordLength);
       
   463 		findDesArray->AppendL(*findword);
       
   464 		}
       
   465 
       
   466 	DeleteFindContacts();
       
   467 
       
   468 	if (prefixSearch)
       
   469 		iView->ContactsMatchingPrefixL(*findDesArray,iContacts);
       
   470 	else
       
   471 		iView->ContactsMatchingCriteriaL(*findDesArray,iContacts);
       
   472 
       
   473 	findDesArray->Reset();
       
   474 	
       
   475 	CleanupStack::PopAndDestroy(numFindWords);
       
   476 	CleanupStack::PopAndDestroy(3, buffer);
       
   477 
       
   478 	// Compute contacts externalized size.
       
   479 	const TInt contactsCount = iContacts.Count();
       
   480 	TInt contactsExternalizedSize=0;
       
   481 	contactsExternalizedSize+=sizeof(TInt32);
       
   482 	for (TInt jj=0;jj<contactsCount;++jj)
       
   483 		{
       
   484 		contactsExternalizedSize+=(iContacts)[jj]->ExternalizedSize();
       
   485 		}
       
   486 
       
   487 	TPckgBuf<TInt> pckg(contactsExternalizedSize);
       
   488 	aMessage.WriteL(0,pckg);
       
   489 	}
       
   490 
       
   491 
       
   492 /** 
       
   493 Write matching contacts back to client.
       
   494 
       
   495 @param aMessage.Ptr0() Descriptor to write array of matching contacts.
       
   496 */
       
   497 void CViewSubSessionBase::GetContactMatchingCriteriaL(const RMessage2& aMessage)
       
   498 	{
       
   499 	// Compute contacts externalized size.
       
   500 	const TInt contactsCount = iContacts.Count();
       
   501 	TInt contactsExternalizedSize=0;
       
   502 	contactsExternalizedSize+=sizeof(TInt32);
       
   503 	for (TInt jj=0;jj<contactsCount;++jj)
       
   504 		{
       
   505 		contactsExternalizedSize+=(iContacts)[jj]->ExternalizedSize();
       
   506 		}
       
   507 
       
   508 	HBufC8* buf=HBufC8::NewLC(contactsExternalizedSize);
       
   509 	TPtr8 bufPtr(buf->Des());
       
   510 	RDesWriteStream writeStream(bufPtr);
       
   511 	CleanupClosePushL(writeStream);
       
   512 
       
   513 	writeStream.WriteUint32L(contactsCount);
       
   514 	for (TInt ii=0;ii<contactsCount;++ii)
       
   515 		{
       
   516 		CViewContact* thisContact = (iContacts)[ii];
       
   517 		writeStream << *thisContact;
       
   518 		}
       
   519 
       
   520 	bufPtr.SetLength(contactsExternalizedSize);
       
   521 	aMessage.WriteL(0,*buf);
       
   522 
       
   523 	CleanupStack::PopAndDestroy(2, buf); //writeStream.Close(), buf
       
   524 
       
   525 	DeleteFindContacts();
       
   526 	}
       
   527 
       
   528 
       
   529 void CViewSubSessionBase::FindL(const RMessage2& aMessage) const
       
   530 	{
       
   531 	TPckgBuf<TContactItemId> pckg(iView->FindL(aMessage.Int0()));
       
   532 	aMessage.WriteL(1,pckg);
       
   533 	}
       
   534 
       
   535 
       
   536 TInt CViewSubSessionBase::GetAllFieldsLengthL(const RMessage2& aMessage)
       
   537 	{
       
   538 	TInt reply = KErrNone;
       
   539 	TInt index = aMessage.Int0();
       
   540 
       
   541 	__ASSERT_ALWAYS(index>=0,User::Leave(KErrUnderflow));
       
   542 
       
   543 	if(!(index<iView->CountL()))
       
   544 		{
       
   545 		// Index is out of bounds.
       
   546 		reply=KErrNotFound;
       
   547 		return reply;
       
   548 		}
       
   549 
       
   550 	TBuf<256> bufPtr;// = buf->Des();
       
   551 	aMessage.ReadL(1,bufPtr);
       
   552 
       
   553 	// Create sortable text from all fields of view contact at specified index.
       
   554 	delete iSortableText;
       
   555 	iSortableText=NULL;
       
   556 	HBufC* allfields=iView->AllFieldsLC(index,bufPtr);
       
   557 	CleanupStack::Pop(); // allfields
       
   558 	iSortableText=allfields;
       
   559 
       
   560 	TPckgBuf<TInt> pckg(iSortableText->Length());
       
   561 	aMessage.WriteL(2,pckg);
       
   562 
       
   563 	return reply;
       
   564 	}
       
   565 
       
   566 
       
   567 void  CViewSubSessionBase::GetAllFieldsTextL(const RMessage2& aMessage)
       
   568 	{
       
   569 	TPtrC8 narrowPtr((TUint8*)iSortableText->Ptr(),iSortableText->Size());
       
   570 	aMessage.WriteL(0,narrowPtr);
       
   571 	}
       
   572 
       
   573 
       
   574 void CViewSubSessionBase::RequestViewEvent(const RMessage2& aMessage)
       
   575 	{
       
   576 	iQueue->RequestEvent(aMessage);
       
   577 	}
       
   578 
       
   579 
       
   580 void CViewSubSessionBase::CancelRequestViewEvent()
       
   581 	{
       
   582 	iQueue->CancelEventRequest();
       
   583 	}
       
   584 
       
   585 
       
   586 /**
       
   587 Provides conversion between view indexes and contact IDs.
       
   588 
       
   589 @param aMessage.Int0() Buffer size (from client).
       
   590 @param aMessage.Ptr1() Descriptor containing indices (from client).
       
   591 @param aMessage.Ptr2() Descriptor containing contact IDs (to client).
       
   592 */
       
   593 void CViewSubSessionBase::GetContactIdsL(const RMessage2& aMessage)
       
   594 	{
       
   595 	TPckgBuf<TInt> size;
       
   596 	aMessage.ReadL(0,size);
       
   597 	const TInt bufferSize = size();
       
   598 	
       
   599 	CBufFlat* buffer = CBufFlat::NewL(bufferSize);
       
   600 	CleanupStack::PushL(buffer);
       
   601 	buffer->ExpandL(0,bufferSize);
       
   602 	TPtr8 des(buffer->Ptr(0));
       
   603 	aMessage.ReadL(1,des);
       
   604 
       
   605 	RBufReadStream readStream(*buffer);
       
   606 	CleanupClosePushL(readStream);
       
   607 	const TInt count = readStream.ReadUint32L(); 
       
   608 
       
   609 	CArrayFixFlat<TInt>* indexes = new(ELeave) CArrayFixFlat<TInt>(8);	
       
   610 	CleanupStack::PushL(indexes);
       
   611 
       
   612 	for (TInt i=0; i<count; ++i)
       
   613 		{
       
   614 		TInt index = readStream.ReadUint32L();
       
   615 		indexes->AppendL(index);
       
   616 		}
       
   617 
       
   618 	CContactIdArray* array = CContactIdArray::NewLC();
       
   619 	iView->GetContactIdsL(*indexes, *array);
       
   620 
       
   621 	HBufC8* buf=HBufC8::NewLC(bufferSize);
       
   622 	TPtr8 bufPtr(buf->Des());
       
   623 	RDesWriteStream writeStream(bufPtr);
       
   624 	CleanupClosePushL(writeStream);
       
   625 	writeStream << *array;
       
   626 	bufPtr.SetLength(bufferSize);
       
   627 	aMessage.WriteL(2,*buf);
       
   628 
       
   629 	CleanupStack::PopAndDestroy(6, buffer); // &writeStream, buf, array, indexes, &readStream, buffer
       
   630 	}
       
   631 
       
   632 
       
   633 void CViewSubSessionBase::SendPluginUidToServer(const RMessage2& aMessage)
       
   634 	{
       
   635 	TUid uid;
       
   636 	uid.iUid = aMessage.Int0();
       
   637 	iView->SetViewFindConfigPlugin(uid);
       
   638 	}
       
   639 
       
   640 
       
   641 /** 
       
   642 Filter server-side view based on filter supplied by client.  The IDs of matching
       
   643 contact items are externalized to the client-side.
       
   644 
       
   645 @param aMessage.Int0() Filter (from client).
       
   646 @param aMessage.Ptr1() Descriptor containing matching contact IDs (to client).
       
   647 */
       
   648 void CViewSubSessionBase::GetContactsMatchingFilterL(const RMessage2& aMessage)
       
   649 	{
       
   650 	const TInt filter(aMessage.Int0());
       
   651 	
       
   652 	RArray<TContactIdWithMapping> array;
       
   653 	CleanupClosePushL(array);
       
   654 	TContactIdWithMapping idMap;
       
   655 
       
   656 	// Filter view contacts.
       
   657 	const TInt viewCount(iView->CountL());
       
   658 	for (TInt i=0;i<viewCount;++i)
       
   659 		{
       
   660 		const CViewContact& contact = iView->ContactAtL(i);
       
   661 		if(contact.ContactMatchesFilter(filter))
       
   662 			{
       
   663 			idMap.iId=contact.Id();
       
   664 			idMap.iMapping=i;
       
   665 			User::LeaveIfError(array.Append(idMap));
       
   666 			}
       
   667 		}
       
   668 
       
   669 	// Externalize array to client.
       
   670 	const TInt count(array.Count());
       
   671 	const TInt maxBufSize = (1+(array.Count()*2))*sizeof(TInt);
       
   672 	HBufC8* buf=HBufC8::NewLC(maxBufSize);
       
   673 	TPtr8 bufPtr(buf->Des());
       
   674 	RDesWriteStream writeStream(bufPtr);
       
   675 	CleanupClosePushL(writeStream);
       
   676 	writeStream.WriteUint32L(count);
       
   677 	for (TInt j=0; j<count; ++j)
       
   678 		{
       
   679 		writeStream.WriteInt32L(array[j].iId);
       
   680 		writeStream.WriteInt32L(array[j].iMapping);
       
   681 		}
       
   682 	bufPtr.SetLength(maxBufSize);
       
   683 	aMessage.WriteL(1,*buf);
       
   684 	CleanupStack::PopAndDestroy(3,&array);
       
   685 	}
       
   686 
       
   687 
       
   688 void CViewSubSessionBase::GetSortPluginUidFromServerL(const RMessage2& aMessage)
       
   689 	{
       
   690 	TUid uid = iView->GetViewSortPluginImplUid();
       
   691 	TPckgBuf<TInt> pckg(uid.iUid);
       
   692 	aMessage.WriteL(0,pckg);
       
   693 	}
       
   694 
       
   695 
       
   696 CViewSubSession* CViewSubSession::NewL(CViewManager& aViewManager,const RMessage2& aMessage)
       
   697 	{
       
   698 	CViewSubSession* self=new(ELeave) CViewSubSession(aViewManager);
       
   699 	CleanupClosePushL (*self);
       
   700 	self->ConstructL(aMessage);
       
   701 	CleanupStack::Pop(); // self.
       
   702 	return self;
       
   703 	}
       
   704 
       
   705 
       
   706 /**
       
   707 Attempt to consume opcode.  If the opcode is not consumed then the base class
       
   708 ServiceL() is called.
       
   709 */
       
   710 TInt CViewSubSession::ServiceL(const RMessage2& aMessage)
       
   711 	{
       
   712 	switch (aMessage.Function())
       
   713 		{
       
   714 		case ECntViewSortOrderExternalizedSize:
       
   715 			ExternalizedSortOrderSizeL(aMessage);
       
   716 			break;
       
   717 		case ECntGetViewSortOrder:
       
   718 			GetSortOrderL(aMessage);
       
   719 			break;
       
   720 		default:
       
   721 			return CViewSubSessionBase::ServiceL(aMessage);
       
   722 		}
       
   723 	return 0;
       
   724 	}
       
   725 
       
   726 
       
   727 CViewSubSession::~CViewSubSession()
       
   728 	{
       
   729 	iViewManager.CloseView(View(),*this);
       
   730 	}
       
   731 
       
   732 
       
   733 CViewSubSession::CViewSubSession(CViewManager& aViewManager) : CViewSubSessionBase(aViewManager)
       
   734 	{
       
   735 	}
       
   736 
       
   737 
       
   738 void CViewSubSession::ConstructL(const RMessage2& aMessage) 
       
   739 	{
       
   740 	CViewSubSessionBase::ConstructL();
       
   741 
       
   742 	RContactViewSortOrder sortOrder;
       
   743 	CleanupClosePushL(sortOrder);
       
   744 	TContactViewPreferences contactsToInclude;
       
   745 
       
   746 	TUid sortPluginImplUid;
       
   747 	HBufC8* sortPluginName = UnpackageSortOrderAndPluginDetailsLC(aMessage,sortOrder,contactsToInclude,sortPluginImplUid);
       
   748 
       
   749 	iView = &iViewManager.OpenViewL(sortOrder,*this,contactsToInclude,sortPluginImplUid,*sortPluginName);
       
   750 
       
   751 	CleanupStack::PopAndDestroy(2, &sortOrder); // sortPluginName, sortOrder
       
   752 	}
       
   753 
       
   754 
       
   755 void CViewSubSession::UnpackageSortOrderL(const RMessage2& aMessage,RContactViewSortOrder& aSortOrder,TContactViewPreferences& aContactTypes) const
       
   756 	{
       
   757 	HBufC8* buf=HBufC8::NewLC(aMessage.Int0());
       
   758 
       
   759 	TPtr8 bufPtr(buf->Des());
       
   760 	aMessage.ReadL(1,bufPtr);
       
   761 	RDesReadStream readStream(bufPtr);
       
   762 	CleanupClosePushL(readStream);
       
   763 
       
   764 	readStream >> (TInt32&)aContactTypes;
       
   765 	readStream >> aSortOrder;
       
   766 
       
   767 	CleanupStack::PopAndDestroy(2); //readstream, buf.
       
   768 	}
       
   769 
       
   770 
       
   771 HBufC8* CViewSubSession::UnpackageSortOrderAndPluginDetailsLC(const RMessage2& aMessage,RContactViewSortOrder& aSortOrder,TContactViewPreferences& aContactTypes,TUid& aSortPluginImplUid) const
       
   772 	{
       
   773 	HBufC8* buf=HBufC8::NewLC(aMessage.Int0());
       
   774 
       
   775 	TPtr8 bufPtr(buf->Des());
       
   776 	TInt32 nameLen;
       
   777 	aMessage.ReadL(1,bufPtr);
       
   778 	RDesReadStream readStream(bufPtr);
       
   779 	CleanupClosePushL(readStream);
       
   780 
       
   781 	readStream >> (TInt32&)aContactTypes;
       
   782 	readStream >> aSortOrder;
       
   783 
       
   784 	// Extract sort plugin UID.
       
   785 	aSortPluginImplUid.iUid = readStream.ReadInt32L();
       
   786 
       
   787 	// Extract sort plugin name.
       
   788 	nameLen = readStream.ReadInt32L();
       
   789 	HBufC8* pluginNameBuf = HBufC8::NewLC(nameLen);
       
   790 	TPtr8	pluginNamePtr = pluginNameBuf->Des();
       
   791 	readStream.ReadL(pluginNamePtr, nameLen);
       
   792 	CleanupStack::Pop(pluginNameBuf);
       
   793 	CleanupStack::PopAndDestroy(2); //readstream, buf.
       
   794 
       
   795 	CleanupStack::PushL(pluginNameBuf);
       
   796 	return pluginNameBuf;
       
   797 	}
       
   798 
       
   799 
       
   800 CContactLocalView& CViewSubSession::View() const
       
   801 	{
       
   802 	return STATIC_CAST(CContactLocalView&,*iView);
       
   803 	}
       
   804 
       
   805 
       
   806 void CViewSubSession::ExternalizedSortOrderSizeL(const RMessage2& aMessage) const
       
   807 	{
       
   808 	TPckgBuf<TInt> pckg(View().SortOrder().ExternalizedSize());
       
   809 	aMessage.WriteL(0,pckg);
       
   810 	}
       
   811 
       
   812 
       
   813 void CViewSubSession::GetSortOrderL(const RMessage2& aMessage) const
       
   814 	{
       
   815 	const RContactViewSortOrder& sortOrder=View().SortOrder();
       
   816 	const TInt externalizedSize=sortOrder.ExternalizedSize();
       
   817 	HBufC8* buf=HBufC8::NewLC(externalizedSize);
       
   818 	TPtr8 bufPtr(buf->Des());
       
   819 	RDesWriteStream writeStream(bufPtr);
       
   820 	CleanupClosePushL(writeStream);
       
   821 	writeStream << sortOrder;
       
   822 	bufPtr.SetLength(externalizedSize);
       
   823 	aMessage.WriteL(0,*buf);
       
   824 	CleanupStack::PopAndDestroy(2); // writeStream, buf.
       
   825 	}
       
   826 
       
   827 
       
   828 CNamedViewSubSession* CNamedViewSubSession::NewL(CViewManager& aViewManager,const RMessage2& aMessage)
       
   829 	{
       
   830 	CNamedViewSubSession* self=new(ELeave) CNamedViewSubSession(aViewManager);
       
   831 	CleanupClosePushL(*self); // CObject: Close will call the destructor.
       
   832 	self->ConstructL(aMessage);
       
   833 	CleanupStack::Pop(); // self.
       
   834 	return self;
       
   835 	}
       
   836 
       
   837 
       
   838 /**
       
   839 Attempt to consume opcode.  If the opcode is not consumed then the base class
       
   840 ServiceL() is called.
       
   841 */
       
   842 TInt CNamedViewSubSession::ServiceL(const RMessage2& aMessage)
       
   843 	{
       
   844 	switch (aMessage.Function())
       
   845 		{
       
   846 		case ECntChangeViewSortOrder:
       
   847 			ChangeSortOrderL(aMessage);
       
   848 			break;
       
   849 		default:
       
   850 			return CViewSubSession::ServiceL(aMessage);
       
   851 		}
       
   852 	return 0;
       
   853 	}
       
   854 
       
   855 
       
   856 CNamedViewSubSession::~CNamedViewSubSession()
       
   857 	{
       
   858 	iViewManager.CloseNamedView(View(),*this);
       
   859 	}
       
   860 
       
   861 
       
   862 CNamedViewSubSession::CNamedViewSubSession(CViewManager& aViewManager) : CViewSubSession(aViewManager)
       
   863 	{
       
   864 	}
       
   865 
       
   866 
       
   867 void CNamedViewSubSession::ConstructL(const RMessage2& aMessage)
       
   868 	{
       
   869 	CViewSubSessionBase::ConstructL();
       
   870 
       
   871 	// Read sort order.
       
   872 	RContactViewSortOrder sortOrder;
       
   873 	CleanupClosePushL(sortOrder);
       
   874 	TContactViewPreferences contactsToInclude;
       
   875 	TUid sortPluginImplUid;
       
   876 	HBufC8* sortPluginName = UnpackageSortOrderAndPluginDetailsLC(aMessage,sortOrder,contactsToInclude,sortPluginImplUid);
       
   877 
       
   878 	// Create a descriptor of the correct length.
       
   879 	HBufC* nameBuf=HBufC::NewLC(aMessage.GetDesLengthL(2));
       
   880 	TPtr  wideNameBufPtr(nameBuf->Des());
       
   881 	// Extract the name of the view from the message.
       
   882 	aMessage.ReadL(2, wideNameBufPtr);
       
   883 
       
   884 	// Open view using name provided.
       
   885 	iView = &iViewManager.OpenNamedViewL(wideNameBufPtr,sortOrder,*this,contactsToInclude,sortPluginImplUid,*sortPluginName);
       
   886 
       
   887 	CleanupStack::PopAndDestroy(3,&sortOrder); // nameBuf, sortPluginName, sortOrder
       
   888 
       
   889 	sortOrder.Close();
       
   890 	}
       
   891 
       
   892 
       
   893 void CNamedViewSubSession::ChangeSortOrderL(const RMessage2& aMessage)
       
   894 	{
       
   895 	RContactViewSortOrder newSortOrder;
       
   896 	TContactViewPreferences contactsToInclude;
       
   897 	UnpackageSortOrderL(aMessage,newSortOrder,contactsToInclude);
       
   898 	View().ChangeSortOrderL(newSortOrder);
       
   899 	newSortOrder.Close();
       
   900 	}
       
   901 
       
   902 
       
   903 CContactNamedLocalView& CNamedViewSubSession::View() const
       
   904 	{
       
   905 	return STATIC_CAST(CContactNamedLocalView&,*iView);
       
   906 	}
       
   907 
       
   908 
       
   909 CViewManager* CViewManager::NewL(MLplPersistenceLayerFactory& aFactory,CCntDbManager& aManager)
       
   910 	{
       
   911 	CViewManager* self =new (ELeave) CViewManager(aFactory,aManager);
       
   912 	CleanupStack::PushL(self);
       
   913 	self->ConstructL();
       
   914 	CleanupStack::Pop(self);
       
   915 	return self;
       
   916 	}
       
   917 
       
   918 
       
   919 CContactLocalView& CViewManager::OpenViewL(const RContactViewSortOrder& aSortOrder,MContactViewObserver& aObserver,TContactViewPreferences aContactTypeToInclude, const TUid aSortPluginImplUid, const TDesC8& aSortPluginName)
       
   920 	{
       
   921 	// Check to see if there is already a view with the required sort order,
       
   922 	// preferences and sort plugin.
       
   923 	const TInt numViews=iLocalViews.Count();
       
   924 	for (TInt ii=0;ii<numViews;++ii)
       
   925 		{
       
   926 		CContactLocalView& thisView=*iLocalViews[ii].iLocalView; 
       
   927 		if ( thisView.SortOrder()==aSortOrder && thisView.ContactViewPreferences() == aContactTypeToInclude &&
       
   928 				iLocalViews[ii].iSortPluginImplUid == aSortPluginImplUid)
       
   929 			{
       
   930 			if(thisView.Error() == KErrNone)
       
   931 				{
       
   932 				// Found one with no sorting error, so share it.
       
   933 				thisView.OpenL(aObserver);
       
   934 				return thisView;
       
   935 				}
       
   936 			}
       
   937 		}
       
   938 
       
   939 	// No view found, so create a new one.
       
   940 	TViewHandle	viewHandle;
       
   941 	viewHandle.iSortPluginImplUid = aSortPluginImplUid;
       
   942 	
       
   943 	if (!iManager.StateMachineL().DatabaseReady())
       
   944 		{
       
   945 		User::Leave(KErrNotReady);
       
   946 		}
       
   947 
       
   948 	// Dummy CContactDatabase done for BC.  CContactLocalView does not use
       
   949 	// CContactDatabase.
       
   950 	CContactDatabase* dummy = NULL;
       
   951 
       
   952 	// If aSortPluginImplUid is KNullUid indicates no sort plugin.
       
   953 	if (aSortPluginName.Length() || (aSortPluginImplUid == KNullUid))
       
   954 		{
       
   955 		viewHandle.iLocalView=CContactLocalView::NewL(aObserver,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,aSortPluginName);
       
   956 		}
       
   957 	else
       
   958 		{
       
   959 		viewHandle.iLocalView=CContactLocalView::NewL(aObserver,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,KNullDesC8);
       
   960 		}
       
   961 
       
   962 	// Register this view as an observer of database events with the
       
   963 	// associated CCntDbManager.
       
   964 	iManager.RegisterDatabaseEventObserverL(*viewHandle.iLocalView);
       
   965 
       
   966 	TInt error = iLocalViews.Append(viewHandle);
       
   967 	if (error != KErrNone)
       
   968 		{
       
   969 		iManager.UnRegisterDatabaseEventObserver(*viewHandle.iLocalView);
       
   970 		viewHandle.iLocalView->Close(aObserver);
       
   971 		User::Leave(error);
       
   972 		}
       
   973 
       
   974 	return *viewHandle.iLocalView;
       
   975 	}
       
   976 
       
   977 	
       
   978 CContactNamedLocalView& CViewManager::OpenNamedViewL(const TDesC& aName,const RContactViewSortOrder& aSortOrder,MContactViewObserver& aObserver,TContactViewPreferences aContactTypeToInclude, const TUid aSortPluginImplUid, const TDesC8& aSortPluginName)
       
   979 	{
       
   980 	// Check to see if named view already exists.
       
   981 	const TInt numViews=iNamedLocalViews.Count();
       
   982 	for (TInt ii=0;ii<numViews;++ii)
       
   983 		{
       
   984 		CContactNamedLocalView& thisView=*iNamedLocalViews[ii];
       
   985 		if (aName.Compare(thisView.Name())==0 )
       
   986 			{
       
   987 			if(thisView.Error() == KErrNone)
       
   988 				{
       
   989 				// Found a name match, so share it.
       
   990 				thisView.OpenL(aObserver);
       
   991 				return thisView;
       
   992 				}
       
   993 			}
       
   994 		}
       
   995 
       
   996 	// No name match found, so create a new one.
       
   997 	CContactNamedLocalView* newNamedView = NULL;
       
   998 
       
   999 	// Dummy CContactDatabase done for BC.  CContactLocalView does not use
       
  1000 	// CContactDatabase.
       
  1001 	CContactDatabase* dummy = NULL;
       
  1002 
       
  1003 	// If aSortPluginImplUid is KNullUid indicates no sort plugin.
       
  1004 	if (aSortPluginName.Length() || (aSortPluginImplUid == KNullUid))
       
  1005 		{
       
  1006 		newNamedView=CContactNamedLocalView::NewL(aObserver,aName,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,aSortPluginName);
       
  1007 		}
       
  1008 	else
       
  1009 		{
       
  1010 		newNamedView=CContactNamedLocalView::NewL(aObserver,aName,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,KNullDesC8);
       
  1011 		}
       
  1012 
       
  1013 	// Register this view as an observer of database events with the
       
  1014 	// associated CCntDbManager.
       
  1015 	iManager.RegisterDatabaseEventObserverL(*newNamedView);
       
  1016 
       
  1017 	TInt error = iNamedLocalViews.Append(newNamedView);
       
  1018 	if (error != KErrNone)
       
  1019 		{
       
  1020 		iManager.UnRegisterDatabaseEventObserver(*newNamedView);
       
  1021 		newNamedView->Close(aObserver);
       
  1022 		User::Leave(error);
       
  1023 		}
       
  1024 
       
  1025 	return *newNamedView;
       
  1026 	}
       
  1027 
       
  1028 
       
  1029 void CViewManager::CloseView(const CContactLocalView& aView,MContactViewObserver& aObserver)
       
  1030 	{
       
  1031 	const TInt count = iLocalViews.Count();
       
  1032 
       
  1033 	// Be tolerant to view not being found, since a leave may have occured
       
  1034 	// before the CViewSubSession derived object has had a chance to call
       
  1035 	// OpenViewL().
       
  1036 	for (TInt index = 0; index < count; index++)
       
  1037 		{
       
  1038 		// Found it?
       
  1039 		if (iLocalViews[index].iLocalView == &aView)
       
  1040 			{
       
  1041 			if(iLocalViews[index].iLocalView->Close(aObserver))
       
  1042 				{
       
  1043 				// Removed last reference to the Local View so un-Register this
       
  1044 				// view as an observer of database events with the associated 
       
  1045 				// CCntDbManager.
       
  1046 				iManager.UnRegisterDatabaseEventObserver(*iLocalViews[index].iLocalView);
       
  1047 				iLocalViews.Remove(index);
       
  1048 				}
       
  1049 			break;
       
  1050 			}
       
  1051 		}
       
  1052 	}
       
  1053 
       
  1054 
       
  1055 void CViewManager::CloseNamedView(const CContactNamedLocalView& aView,MContactViewObserver& aObserver)
       
  1056 	{
       
  1057 	TInt index = iNamedLocalViews.Find(&aView);
       
  1058 
       
  1059 	// Be tolerant to view not being found, since a leave may have occured
       
  1060 	// before the CNamedViewSubSession derived object has had a chance to call
       
  1061 	// OpenViewL().
       
  1062 	if (index != KErrNotFound)
       
  1063 		{
       
  1064 		if (iNamedLocalViews[index]->Close(aObserver))
       
  1065 			{
       
  1066 			// Removed last reference to the Local View so un-Register this view
       
  1067 			// as an observer of database events with the associated
       
  1068 			// CCntDbManager.
       
  1069 			iManager.UnRegisterDatabaseEventObserver(*iNamedLocalViews[index]);
       
  1070 			iNamedLocalViews.Remove(index);
       
  1071 			}
       
  1072 		}
       
  1073 	}
       
  1074 
       
  1075 
       
  1076 CViewManager::CViewManager(MLplPersistenceLayerFactory& aFactory,CCntDbManager& aManager) :
       
  1077 	iFactory(aFactory),
       
  1078 	iManager(aManager)
       
  1079 	{
       
  1080 	}
       
  1081 
       
  1082 
       
  1083 CViewManager::~CViewManager()
       
  1084 	{
       
  1085 	iLocalViews.Close();
       
  1086 	iNamedLocalViews.Close();
       
  1087 	}
       
  1088 
       
  1089 
       
  1090 void CViewManager::ConstructL()
       
  1091 	{
       
  1092 	}
       
  1093 
       
  1094 
       
  1095 #if defined(_DEBUG)
       
  1096 void CViewManager::GetDefinitionsOfExistingViewsL(RPointerArray<CContactDefaultViewDefinition>& aViewDefs)
       
  1097 	{
       
  1098 	__ASSERT_DEBUG(aViewDefs.Count() == 0, User::Leave(KErrArgument));
       
  1099 
       
  1100 	TInt i;
       
  1101 	CContactDefaultViewDefinition* viewDef;
       
  1102 	
       
  1103 	// Anonymous views.
       
  1104 	for (i = 0; i < iLocalViews.Count(); i++)
       
  1105 		{
       
  1106 		CContactLocalView* view = iLocalViews[i].iLocalView;
       
  1107 		viewDef = CContactDefaultViewDefinition::NewLC(CContactDefaultViewDefinition::ERemoteView,
       
  1108 														KNullDesC, view->SortOrderL(), 
       
  1109 														view->ContactViewPreferences(), 
       
  1110 														KNullDesC8/*pluginName*/);
       
  1111 		aViewDefs.AppendL(viewDef);
       
  1112 		CleanupStack::Pop(viewDef);
       
  1113 		}
       
  1114 	
       
  1115 	// Named views.
       
  1116 	for (i = 0; i < iNamedLocalViews.Count(); i++)
       
  1117 		{
       
  1118 		CContactNamedLocalView* view = iNamedLocalViews[i];
       
  1119 		viewDef = CContactDefaultViewDefinition::NewLC(CContactDefaultViewDefinition::ENamedRemoteView,
       
  1120 														view->Name(), view->SortOrderL(), 
       
  1121 														view->ContactViewPreferences(), 
       
  1122 														KNullDesC8/*pluginName*/);
       
  1123 		aViewDefs.AppendL(viewDef);
       
  1124 		CleanupStack::Pop(viewDef);		
       
  1125 		}
       
  1126 	}
       
  1127 #else
       
  1128 void CViewManager::GetDefinitionsOfExistingViewsL(RPointerArray<CContactDefaultViewDefinition>& )
       
  1129 	{
       
  1130 	}
       
  1131 #endif // _DEBUG