phonebookengines_old/contactsmodel/cntsrv/src/CViewSubSessions.cpp
changeset 40 b46a585f6909
equal deleted inserted replaced
37:fd64c38c277d 40:b46a585f6909
       
     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 	//Always keep server side local view in memory saving mode, so we
       
   395 	//change the view contact object stored in iView into lightweight object
       
   396 	const_cast<CViewContact&>(contact).ChangeToLightweightObject();
       
   397 	
       
   398 	const TInt externalizedSize=iContact->ExternalizedSize();
       
   399 	TPckgBuf<TInt> pckg(externalizedSize);
       
   400 	aMessage.WriteL(1,pckg);
       
   401 
       
   402 	return reply;
       
   403 	}
       
   404 
       
   405 
       
   406 void CViewSubSessionBase::GetIncludedTypesL(const RMessage2& aMessage)
       
   407 	{
       
   408 	TPckgBuf<TContactViewPreferences> pckg(iView->ContactViewPreferences());
       
   409 	aMessage.WriteL(0,pckg);	
       
   410 	}
       
   411 
       
   412 
       
   413 void CViewSubSessionBase::DeleteFindContacts()
       
   414 	{
       
   415 	iContacts.ResetAndDestroy();
       
   416 	}
       
   417 
       
   418 
       
   419 #ifdef _DEBUG
       
   420 void CViewSubSessionBase::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
   421 #else
       
   422 void CViewSubSessionBase::HandleContactViewEvent(const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent)
       
   423 #endif
       
   424 	{
       
   425 	ASSERT(&aView==iView);
       
   426 	iQueue->QueueEvent(aEvent);
       
   427 	}
       
   428 
       
   429 
       
   430 /** 
       
   431 Match an array of search strings against the contacts in the view.
       
   432 
       
   433 The descriptor from the client contains a flag at the start to indicate if a
       
   434 prefix or substring search has been requested.
       
   435 
       
   436 @param aMessage.Ptr0() Size of contact data to read (to client).
       
   437 @param aMessage.Int1() Size of descriptor (from client).
       
   438 @param aMessage.Ptr2() Descriptor (from client).
       
   439 */
       
   440 void CViewSubSessionBase::ContactMatchingCriteriaExternalizedSizeL(const RMessage2& aMessage)
       
   441 	{
       
   442 	TPckgBuf<TInt> size;
       
   443 	aMessage.ReadL(1,size);
       
   444 	const TInt bufferSize = size();
       
   445 
       
   446 	// Restore buffer.
       
   447 	CBufFlat* buffer = CBufFlat::NewL(bufferSize);
       
   448 	CleanupStack::PushL(buffer);
       
   449 	buffer->ExpandL(0,bufferSize);
       
   450 	TPtr8 des(buffer->Ptr(0));
       
   451 	aMessage.ReadL(2,des);
       
   452 
       
   453 	// Internalize the data from the stream.
       
   454 	RBufReadStream readStream(*buffer);
       
   455 	CleanupClosePushL(readStream);
       
   456 
       
   457 	TBool prefixSearch = readStream.ReadUint32L(); 
       
   458 	const TInt numFindWords = readStream.ReadUint32L();
       
   459 	CPtrC16Array* findDesArray = new(ELeave) CPtrC16Array(numFindWords);
       
   460 	CleanupStack::PushL(findDesArray);
       
   461 
       
   462 	TInt findWordLength=0;
       
   463 	for (TInt i=0; i<numFindWords; ++i)
       
   464 		{
       
   465 		findWordLength = readStream.ReadUint32L();
       
   466 		HBufC* findword = HBufC::NewLC(readStream,findWordLength);
       
   467 		findDesArray->AppendL(*findword);
       
   468 		}
       
   469 
       
   470 	DeleteFindContacts();
       
   471 
       
   472 	if (prefixSearch)
       
   473 		iView->ContactsMatchingPrefixL(*findDesArray,iContacts);
       
   474 	else
       
   475 		iView->ContactsMatchingCriteriaL(*findDesArray,iContacts);
       
   476 
       
   477 	findDesArray->Reset();
       
   478 	
       
   479 	CleanupStack::PopAndDestroy(numFindWords);
       
   480 	CleanupStack::PopAndDestroy(3, buffer);
       
   481 
       
   482 	// Compute contacts externalized size.
       
   483 	const TInt contactsCount = iContacts.Count();
       
   484 	TInt contactsExternalizedSize=0;
       
   485 	contactsExternalizedSize+=sizeof(TInt32);
       
   486 	for (TInt jj=0;jj<contactsCount;++jj)
       
   487 		{
       
   488 		contactsExternalizedSize+=(iContacts)[jj]->ExternalizedSize();
       
   489 		}
       
   490 
       
   491 	TPckgBuf<TInt> pckg(contactsExternalizedSize);
       
   492 	aMessage.WriteL(0,pckg);
       
   493 	}
       
   494 
       
   495 
       
   496 /** 
       
   497 Write matching contacts back to client.
       
   498 
       
   499 @param aMessage.Ptr0() Descriptor to write array of matching contacts.
       
   500 */
       
   501 void CViewSubSessionBase::GetContactMatchingCriteriaL(const RMessage2& aMessage)
       
   502 	{
       
   503 	// Compute contacts externalized size.
       
   504 	const TInt contactsCount = iContacts.Count();
       
   505 	TInt contactsExternalizedSize=0;
       
   506 	contactsExternalizedSize+=sizeof(TInt32);
       
   507 	for (TInt jj=0;jj<contactsCount;++jj)
       
   508 		{
       
   509 		contactsExternalizedSize+=(iContacts)[jj]->ExternalizedSize();
       
   510 		}
       
   511 
       
   512 	HBufC8* buf=HBufC8::NewLC(contactsExternalizedSize);
       
   513 	TPtr8 bufPtr(buf->Des());
       
   514 	RDesWriteStream writeStream(bufPtr);
       
   515 	CleanupClosePushL(writeStream);
       
   516 
       
   517 	writeStream.WriteUint32L(contactsCount);
       
   518 	for (TInt ii=0;ii<contactsCount;++ii)
       
   519 		{
       
   520 		CViewContact* thisContact = (iContacts)[ii];
       
   521 		writeStream << *thisContact;
       
   522 		}
       
   523 
       
   524 	bufPtr.SetLength(contactsExternalizedSize);
       
   525 	aMessage.WriteL(0,*buf);
       
   526 
       
   527 	CleanupStack::PopAndDestroy(2, buf); //writeStream.Close(), buf
       
   528 
       
   529 	DeleteFindContacts();
       
   530 	}
       
   531 
       
   532 
       
   533 void CViewSubSessionBase::FindL(const RMessage2& aMessage) const
       
   534 	{
       
   535 	TPckgBuf<TContactItemId> pckg(iView->FindL(aMessage.Int0()));
       
   536 	aMessage.WriteL(1,pckg);
       
   537 	}
       
   538 
       
   539 
       
   540 TInt CViewSubSessionBase::GetAllFieldsLengthL(const RMessage2& aMessage)
       
   541 	{
       
   542 	TInt reply = KErrNone;
       
   543 	TInt index = aMessage.Int0();
       
   544 
       
   545 	__ASSERT_ALWAYS(index>=0,User::Leave(KErrUnderflow));
       
   546 
       
   547 	if(!(index<iView->CountL()))
       
   548 		{
       
   549 		// Index is out of bounds.
       
   550 		reply=KErrNotFound;
       
   551 		return reply;
       
   552 		}
       
   553 
       
   554 	TBuf<256> bufPtr;// = buf->Des();
       
   555 	aMessage.ReadL(1,bufPtr);
       
   556 
       
   557 	// Create sortable text from all fields of view contact at specified index.
       
   558 	delete iSortableText;
       
   559 	iSortableText=NULL;
       
   560 	HBufC* allfields=iView->AllFieldsLC(index,bufPtr);
       
   561 	CleanupStack::Pop(); // allfields
       
   562 	iSortableText=allfields;
       
   563 
       
   564 	TPckgBuf<TInt> pckg(iSortableText->Length());
       
   565 	aMessage.WriteL(2,pckg);
       
   566 
       
   567 	return reply;
       
   568 	}
       
   569 
       
   570 
       
   571 void  CViewSubSessionBase::GetAllFieldsTextL(const RMessage2& aMessage)
       
   572 	{
       
   573 	TPtrC8 narrowPtr((TUint8*)iSortableText->Ptr(),iSortableText->Size());
       
   574 	aMessage.WriteL(0,narrowPtr);
       
   575 	}
       
   576 
       
   577 
       
   578 void CViewSubSessionBase::RequestViewEvent(const RMessage2& aMessage)
       
   579 	{
       
   580 	iQueue->RequestEvent(aMessage);
       
   581 	}
       
   582 
       
   583 
       
   584 void CViewSubSessionBase::CancelRequestViewEvent()
       
   585 	{
       
   586 	iQueue->CancelEventRequest();
       
   587 	}
       
   588 
       
   589 
       
   590 /**
       
   591 Provides conversion between view indexes and contact IDs.
       
   592 
       
   593 @param aMessage.Int0() Buffer size (from client).
       
   594 @param aMessage.Ptr1() Descriptor containing indices (from client).
       
   595 @param aMessage.Ptr2() Descriptor containing contact IDs (to client).
       
   596 */
       
   597 void CViewSubSessionBase::GetContactIdsL(const RMessage2& aMessage)
       
   598 	{
       
   599 	TPckgBuf<TInt> size;
       
   600 	aMessage.ReadL(0,size);
       
   601 	const TInt bufferSize = size();
       
   602 	
       
   603 	CBufFlat* buffer = CBufFlat::NewL(bufferSize);
       
   604 	CleanupStack::PushL(buffer);
       
   605 	buffer->ExpandL(0,bufferSize);
       
   606 	TPtr8 des(buffer->Ptr(0));
       
   607 	aMessage.ReadL(1,des);
       
   608 
       
   609 	RBufReadStream readStream(*buffer);
       
   610 	CleanupClosePushL(readStream);
       
   611 	const TInt count = readStream.ReadUint32L(); 
       
   612 
       
   613 	CArrayFixFlat<TInt>* indexes = new(ELeave) CArrayFixFlat<TInt>(8);	
       
   614 	CleanupStack::PushL(indexes);
       
   615 
       
   616 	for (TInt i=0; i<count; ++i)
       
   617 		{
       
   618 		TInt index = readStream.ReadUint32L();
       
   619 		indexes->AppendL(index);
       
   620 		}
       
   621 
       
   622 	CContactIdArray* array = CContactIdArray::NewLC();
       
   623 	iView->GetContactIdsL(*indexes, *array);
       
   624 
       
   625 	HBufC8* buf=HBufC8::NewLC(bufferSize);
       
   626 	TPtr8 bufPtr(buf->Des());
       
   627 	RDesWriteStream writeStream(bufPtr);
       
   628 	CleanupClosePushL(writeStream);
       
   629 	writeStream << *array;
       
   630 	bufPtr.SetLength(bufferSize);
       
   631 	aMessage.WriteL(2,*buf);
       
   632 
       
   633 	CleanupStack::PopAndDestroy(6, buffer); // &writeStream, buf, array, indexes, &readStream, buffer
       
   634 	}
       
   635 
       
   636 
       
   637 void CViewSubSessionBase::SendPluginUidToServer(const RMessage2& aMessage)
       
   638 	{
       
   639 	TUid uid;
       
   640 	uid.iUid = aMessage.Int0();
       
   641 	iView->SetViewFindConfigPlugin(uid);
       
   642 	}
       
   643 
       
   644 
       
   645 /** 
       
   646 Filter server-side view based on filter supplied by client.  The IDs of matching
       
   647 contact items are externalized to the client-side.
       
   648 
       
   649 @param aMessage.Int0() Filter (from client).
       
   650 @param aMessage.Ptr1() Descriptor containing matching contact IDs (to client).
       
   651 */
       
   652 void CViewSubSessionBase::GetContactsMatchingFilterL(const RMessage2& aMessage)
       
   653 	{
       
   654 	const TInt filter(aMessage.Int0());
       
   655 	
       
   656 	RArray<TContactIdWithMapping> array;
       
   657 	CleanupClosePushL(array);
       
   658 	TContactIdWithMapping idMap;
       
   659 
       
   660 	// Filter view contacts.
       
   661 	const TInt viewCount(iView->CountL());
       
   662 	for (TInt i=0;i<viewCount;++i)
       
   663 		{
       
   664 		const CViewContact& contact = iView->ContactAtL(i);
       
   665 		if(contact.ContactMatchesFilter(filter))
       
   666 			{
       
   667 			idMap.iId=contact.Id();
       
   668 			idMap.iMapping=i;
       
   669 			User::LeaveIfError(array.Append(idMap));
       
   670 			}
       
   671 		}
       
   672 
       
   673 	// Externalize array to client.
       
   674 	const TInt count(array.Count());
       
   675 	const TInt maxBufSize = (1+(array.Count()*2))*sizeof(TInt);
       
   676 	HBufC8* buf=HBufC8::NewLC(maxBufSize);
       
   677 	TPtr8 bufPtr(buf->Des());
       
   678 	RDesWriteStream writeStream(bufPtr);
       
   679 	CleanupClosePushL(writeStream);
       
   680 	writeStream.WriteUint32L(count);
       
   681 	for (TInt j=0; j<count; ++j)
       
   682 		{
       
   683 		writeStream.WriteInt32L(array[j].iId);
       
   684 		writeStream.WriteInt32L(array[j].iMapping);
       
   685 		}
       
   686 	bufPtr.SetLength(maxBufSize);
       
   687 	aMessage.WriteL(1,*buf);
       
   688 	CleanupStack::PopAndDestroy(3,&array);
       
   689 	}
       
   690 
       
   691 
       
   692 void CViewSubSessionBase::GetSortPluginUidFromServerL(const RMessage2& aMessage)
       
   693 	{
       
   694 	TUid uid = iView->GetViewSortPluginImplUid();
       
   695 	TPckgBuf<TInt> pckg(uid.iUid);
       
   696 	aMessage.WriteL(0,pckg);
       
   697 	}
       
   698 
       
   699 
       
   700 CViewSubSession* CViewSubSession::NewL(CViewManager& aViewManager,const RMessage2& aMessage)
       
   701 	{
       
   702 	CViewSubSession* self=new(ELeave) CViewSubSession(aViewManager);
       
   703 	CleanupClosePushL (*self);
       
   704 	self->ConstructL(aMessage);
       
   705 	CleanupStack::Pop(); // self.
       
   706 	return self;
       
   707 	}
       
   708 
       
   709 
       
   710 /**
       
   711 Attempt to consume opcode.  If the opcode is not consumed then the base class
       
   712 ServiceL() is called.
       
   713 */
       
   714 TInt CViewSubSession::ServiceL(const RMessage2& aMessage)
       
   715 	{
       
   716 	switch (aMessage.Function())
       
   717 		{
       
   718 		case ECntViewSortOrderExternalizedSize:
       
   719 			ExternalizedSortOrderSizeL(aMessage);
       
   720 			break;
       
   721 		case ECntGetViewSortOrder:
       
   722 			GetSortOrderL(aMessage);
       
   723 			break;
       
   724 		default:
       
   725 			return CViewSubSessionBase::ServiceL(aMessage);
       
   726 		}
       
   727 	return 0;
       
   728 	}
       
   729 
       
   730 
       
   731 CViewSubSession::~CViewSubSession()
       
   732 	{
       
   733 	iViewManager.CloseView(View(),*this);
       
   734 	}
       
   735 
       
   736 
       
   737 CViewSubSession::CViewSubSession(CViewManager& aViewManager) : CViewSubSessionBase(aViewManager)
       
   738 	{
       
   739 	}
       
   740 
       
   741 
       
   742 void CViewSubSession::ConstructL(const RMessage2& aMessage) 
       
   743 	{
       
   744 	CViewSubSessionBase::ConstructL();
       
   745 
       
   746 	RContactViewSortOrder sortOrder;
       
   747 	CleanupClosePushL(sortOrder);
       
   748 	TContactViewPreferences contactsToInclude;
       
   749 
       
   750 	TUid sortPluginImplUid;
       
   751 	HBufC8* sortPluginName = UnpackageSortOrderAndPluginDetailsLC(aMessage,sortOrder,contactsToInclude,sortPluginImplUid);
       
   752 
       
   753 	iView = &iViewManager.OpenViewL(sortOrder,*this,contactsToInclude,sortPluginImplUid,*sortPluginName);
       
   754 
       
   755 	CleanupStack::PopAndDestroy(2, &sortOrder); // sortPluginName, sortOrder
       
   756 	}
       
   757 
       
   758 
       
   759 void CViewSubSession::UnpackageSortOrderL(const RMessage2& aMessage,RContactViewSortOrder& aSortOrder,TContactViewPreferences& aContactTypes) const
       
   760 	{
       
   761 	HBufC8* buf=HBufC8::NewLC(aMessage.Int0());
       
   762 
       
   763 	TPtr8 bufPtr(buf->Des());
       
   764 	aMessage.ReadL(1,bufPtr);
       
   765 	RDesReadStream readStream(bufPtr);
       
   766 	CleanupClosePushL(readStream);
       
   767 
       
   768 	readStream >> (TInt32&)aContactTypes;
       
   769 	readStream >> aSortOrder;
       
   770 
       
   771 	CleanupStack::PopAndDestroy(2); //readstream, buf.
       
   772 	}
       
   773 
       
   774 
       
   775 HBufC8* CViewSubSession::UnpackageSortOrderAndPluginDetailsLC(const RMessage2& aMessage,RContactViewSortOrder& aSortOrder,TContactViewPreferences& aContactTypes,TUid& aSortPluginImplUid) const
       
   776 	{
       
   777 	HBufC8* buf=HBufC8::NewLC(aMessage.Int0());
       
   778 
       
   779 	TPtr8 bufPtr(buf->Des());
       
   780 	TInt32 nameLen;
       
   781 	aMessage.ReadL(1,bufPtr);
       
   782 	RDesReadStream readStream(bufPtr);
       
   783 	CleanupClosePushL(readStream);
       
   784 
       
   785 	readStream >> (TInt32&)aContactTypes;
       
   786 	readStream >> aSortOrder;
       
   787 
       
   788 	// Extract sort plugin UID.
       
   789 	aSortPluginImplUid.iUid = readStream.ReadInt32L();
       
   790 
       
   791 	// Extract sort plugin name.
       
   792 	nameLen = readStream.ReadInt32L();
       
   793 	HBufC8* pluginNameBuf = HBufC8::NewLC(nameLen);
       
   794 	TPtr8	pluginNamePtr = pluginNameBuf->Des();
       
   795 	readStream.ReadL(pluginNamePtr, nameLen);
       
   796 	CleanupStack::Pop(pluginNameBuf);
       
   797 	CleanupStack::PopAndDestroy(2); //readstream, buf.
       
   798 
       
   799 	CleanupStack::PushL(pluginNameBuf);
       
   800 	return pluginNameBuf;
       
   801 	}
       
   802 
       
   803 
       
   804 CContactLocalView& CViewSubSession::View() const
       
   805 	{
       
   806 	return STATIC_CAST(CContactLocalView&,*iView);
       
   807 	}
       
   808 
       
   809 
       
   810 void CViewSubSession::ExternalizedSortOrderSizeL(const RMessage2& aMessage) const
       
   811 	{
       
   812 	TPckgBuf<TInt> pckg(View().SortOrder().ExternalizedSize());
       
   813 	aMessage.WriteL(0,pckg);
       
   814 	}
       
   815 
       
   816 
       
   817 void CViewSubSession::GetSortOrderL(const RMessage2& aMessage) const
       
   818 	{
       
   819 	const RContactViewSortOrder& sortOrder=View().SortOrder();
       
   820 	const TInt externalizedSize=sortOrder.ExternalizedSize();
       
   821 	HBufC8* buf=HBufC8::NewLC(externalizedSize);
       
   822 	TPtr8 bufPtr(buf->Des());
       
   823 	RDesWriteStream writeStream(bufPtr);
       
   824 	CleanupClosePushL(writeStream);
       
   825 	writeStream << sortOrder;
       
   826 	bufPtr.SetLength(externalizedSize);
       
   827 	aMessage.WriteL(0,*buf);
       
   828 	CleanupStack::PopAndDestroy(2); // writeStream, buf.
       
   829 	}
       
   830 
       
   831 
       
   832 CNamedViewSubSession* CNamedViewSubSession::NewL(CViewManager& aViewManager,const RMessage2& aMessage)
       
   833 	{
       
   834 	CNamedViewSubSession* self=new(ELeave) CNamedViewSubSession(aViewManager);
       
   835 	CleanupStack::PushL(self);
       
   836 	self->ConstructL(aMessage);
       
   837 	CleanupStack::Pop(); // self.
       
   838 	return self;
       
   839 	}
       
   840 
       
   841 
       
   842 /**
       
   843 Attempt to consume opcode.  If the opcode is not consumed then the base class
       
   844 ServiceL() is called.
       
   845 */
       
   846 TInt CNamedViewSubSession::ServiceL(const RMessage2& aMessage)
       
   847 	{
       
   848 	switch (aMessage.Function())
       
   849 		{
       
   850 		case ECntChangeViewSortOrder:
       
   851 			ChangeSortOrderL(aMessage);
       
   852 			break;
       
   853 		default:
       
   854 			return CViewSubSession::ServiceL(aMessage);
       
   855 		}
       
   856 	return 0;
       
   857 	}
       
   858 
       
   859 
       
   860 CNamedViewSubSession::~CNamedViewSubSession()
       
   861 	{
       
   862 	iViewManager.CloseNamedView(View(),*this);
       
   863 	}
       
   864 
       
   865 
       
   866 CNamedViewSubSession::CNamedViewSubSession(CViewManager& aViewManager) : CViewSubSession(aViewManager)
       
   867 	{
       
   868 	}
       
   869 
       
   870 
       
   871 void CNamedViewSubSession::ConstructL(const RMessage2& aMessage)
       
   872 	{
       
   873 	CViewSubSessionBase::ConstructL();
       
   874 
       
   875 	// Read sort order.
       
   876 	RContactViewSortOrder sortOrder;
       
   877 	CleanupClosePushL(sortOrder);
       
   878 	TContactViewPreferences contactsToInclude;
       
   879 	TUid sortPluginImplUid;
       
   880 	HBufC8* sortPluginName = UnpackageSortOrderAndPluginDetailsLC(aMessage,sortOrder,contactsToInclude,sortPluginImplUid);
       
   881 
       
   882 	// Create a descriptor of the correct length.
       
   883 	HBufC* nameBuf=HBufC::NewLC(aMessage.GetDesLengthL(2));
       
   884 	TPtr  wideNameBufPtr(nameBuf->Des());
       
   885 	// Extract the name of the view from the message.
       
   886 	aMessage.ReadL(2, wideNameBufPtr);
       
   887 
       
   888 	// Open view using name provided.
       
   889 	iView = &iViewManager.OpenNamedViewL(wideNameBufPtr,sortOrder,*this,contactsToInclude,sortPluginImplUid,*sortPluginName);
       
   890 
       
   891 	CleanupStack::PopAndDestroy(3,&sortOrder); // nameBuf, sortPluginName, sortOrder
       
   892 
       
   893 	sortOrder.Close();
       
   894 	}
       
   895 
       
   896 
       
   897 void CNamedViewSubSession::ChangeSortOrderL(const RMessage2& aMessage)
       
   898 	{
       
   899 	RContactViewSortOrder newSortOrder;
       
   900 	TContactViewPreferences contactsToInclude;
       
   901 	UnpackageSortOrderL(aMessage,newSortOrder,contactsToInclude);
       
   902 	View().ChangeSortOrderL(newSortOrder);
       
   903 	newSortOrder.Close();
       
   904 	}
       
   905 
       
   906 
       
   907 CContactNamedLocalView& CNamedViewSubSession::View() const
       
   908 	{
       
   909 	return STATIC_CAST(CContactNamedLocalView&,*iView);
       
   910 	}
       
   911 
       
   912 
       
   913 CViewManager* CViewManager::NewL(MLplPersistenceLayerFactory& aFactory,CCntDbManager& aManager)
       
   914 	{
       
   915 	CViewManager* self =new (ELeave) CViewManager(aFactory,aManager);
       
   916 	CleanupStack::PushL(self);
       
   917 	self->ConstructL();
       
   918 	CleanupStack::Pop(self);
       
   919 	return self;
       
   920 	}
       
   921 
       
   922 
       
   923 CContactLocalView& CViewManager::OpenViewL(const RContactViewSortOrder& aSortOrder,MContactViewObserver& aObserver,TContactViewPreferences aContactTypeToInclude, const TUid aSortPluginImplUid, const TDesC8& aSortPluginName)
       
   924 	{
       
   925 	// Check to see if there is already a view with the required sort order,
       
   926 	// preferences and sort plugin.
       
   927 	const TInt numViews=iLocalViews.Count();
       
   928 	for (TInt ii=0;ii<numViews;++ii)
       
   929 		{
       
   930 		CContactLocalView& thisView=*iLocalViews[ii].iLocalView; 
       
   931 		if ( thisView.SortOrder()==aSortOrder && thisView.ContactViewPreferences() == aContactTypeToInclude &&
       
   932 				iLocalViews[ii].iSortPluginImplUid == aSortPluginImplUid)
       
   933 			{
       
   934 			if(thisView.Error() == KErrNone)
       
   935 				{
       
   936 				// Found one with no sorting error, so share it.
       
   937 				thisView.OpenL(aObserver);
       
   938 				return thisView;
       
   939 				}
       
   940 			}
       
   941 		}
       
   942 
       
   943 	// No view found, so create a new one.
       
   944 	TViewHandle	viewHandle;
       
   945 	viewHandle.iSortPluginImplUid = aSortPluginImplUid;
       
   946 	
       
   947 	if (!iManager.StateMachineL().DatabaseReady())
       
   948 		{
       
   949 		User::Leave(KErrNotReady);
       
   950 		}
       
   951 
       
   952 	// Dummy CContactDatabase done for BC.  CContactLocalView does not use
       
   953 	// CContactDatabase.
       
   954 	CContactDatabase* dummy = NULL;
       
   955 
       
   956 	// If aSortPluginImplUid is KNullUid indicates no sort plugin.
       
   957 	if (aSortPluginName.Length() || (aSortPluginImplUid == KNullUid))
       
   958 		{
       
   959 		viewHandle.iLocalView=CContactLocalView::NewL(aObserver,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,aSortPluginName);
       
   960 		}
       
   961 	else
       
   962 		{
       
   963 		viewHandle.iLocalView=CContactLocalView::NewL(aObserver,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,KNullDesC8);
       
   964 		}
       
   965 
       
   966 	// Register this view as an observer of database events with the
       
   967 	// associated CCntDbManager.
       
   968 	iManager.RegisterDatabaseEventObserverL(*viewHandle.iLocalView);
       
   969 
       
   970 	TInt error = iLocalViews.Append(viewHandle);
       
   971 	if (error != KErrNone)
       
   972 		{
       
   973 		iManager.UnRegisterDatabaseEventObserver(*viewHandle.iLocalView);
       
   974 		viewHandle.iLocalView->Close(aObserver);
       
   975 		User::Leave(error);
       
   976 		}
       
   977 
       
   978 	return *viewHandle.iLocalView;
       
   979 	}
       
   980 
       
   981 	
       
   982 CContactNamedLocalView& CViewManager::OpenNamedViewL(const TDesC& aName,const RContactViewSortOrder& aSortOrder,MContactViewObserver& aObserver,TContactViewPreferences aContactTypeToInclude, const TUid aSortPluginImplUid, const TDesC8& aSortPluginName)
       
   983 	{
       
   984 	// Check to see if named view already exists.
       
   985 	const TInt numViews=iNamedLocalViews.Count();
       
   986 	for (TInt ii=0;ii<numViews;++ii)
       
   987 		{
       
   988 		CContactNamedLocalView& thisView=*iNamedLocalViews[ii];
       
   989 		if (aName.Compare(thisView.Name())==0 )
       
   990 			{
       
   991 			if(thisView.Error() == KErrNone)
       
   992 				{
       
   993 				// Found a name match, so share it.
       
   994 				thisView.OpenL(aObserver);
       
   995 				return thisView;
       
   996 				}
       
   997 			}
       
   998 		}
       
   999 
       
  1000 	// No name match found, so create a new one.
       
  1001 	CContactNamedLocalView* newNamedView = NULL;
       
  1002 
       
  1003 	// Dummy CContactDatabase done for BC.  CContactLocalView does not use
       
  1004 	// CContactDatabase.
       
  1005 	CContactDatabase* dummy = NULL;
       
  1006 
       
  1007 	// If aSortPluginImplUid is KNullUid indicates no sort plugin.
       
  1008 	if (aSortPluginName.Length() || (aSortPluginImplUid == KNullUid))
       
  1009 		{
       
  1010 		newNamedView=CContactNamedLocalView::NewL(aObserver,aName,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,aSortPluginName);
       
  1011 		}
       
  1012 	else
       
  1013 		{
       
  1014 		newNamedView=CContactNamedLocalView::NewL(aObserver,aName,*dummy,aSortOrder,aContactTypeToInclude,&iFactory,KNullDesC8);
       
  1015 		}
       
  1016 
       
  1017 	// Register this view as an observer of database events with the
       
  1018 	// associated CCntDbManager.
       
  1019 	iManager.RegisterDatabaseEventObserverL(*newNamedView);
       
  1020 
       
  1021 	TInt error = iNamedLocalViews.Append(newNamedView);
       
  1022 	if (error != KErrNone)
       
  1023 		{
       
  1024 		iManager.UnRegisterDatabaseEventObserver(*newNamedView);
       
  1025 		newNamedView->Close(aObserver);
       
  1026 		User::Leave(error);
       
  1027 		}
       
  1028 
       
  1029 	return *newNamedView;
       
  1030 	}
       
  1031 
       
  1032 
       
  1033 void CViewManager::CloseView(const CContactLocalView& aView,MContactViewObserver& aObserver)
       
  1034 	{
       
  1035 	const TInt count = iLocalViews.Count();
       
  1036 
       
  1037 	// Be tolerant to view not being found, since a leave may have occured
       
  1038 	// before the CViewSubSession derived object has had a chance to call
       
  1039 	// OpenViewL().
       
  1040 	for (TInt index = 0; index < count; index++)
       
  1041 		{
       
  1042 		// Found it?
       
  1043 		if (iLocalViews[index].iLocalView == &aView)
       
  1044 			{
       
  1045 			if(iLocalViews[index].iLocalView->Close(aObserver))
       
  1046 				{
       
  1047 				// Removed last reference to the Local View so un-Register this
       
  1048 				// view as an observer of database events with the associated 
       
  1049 				// CCntDbManager.
       
  1050 				iManager.UnRegisterDatabaseEventObserver(*iLocalViews[index].iLocalView);
       
  1051 				iLocalViews.Remove(index);
       
  1052 				}
       
  1053 			break;
       
  1054 			}
       
  1055 		}
       
  1056 	}
       
  1057 
       
  1058 
       
  1059 void CViewManager::CloseNamedView(const CContactNamedLocalView& aView,MContactViewObserver& aObserver)
       
  1060 	{
       
  1061 	TInt index = iNamedLocalViews.Find(&aView);
       
  1062 
       
  1063 	// Be tolerant to view not being found, since a leave may have occured
       
  1064 	// before the CNamedViewSubSession derived object has had a chance to call
       
  1065 	// OpenViewL().
       
  1066 	if (index != KErrNotFound)
       
  1067 		{
       
  1068 		if (iNamedLocalViews[index]->Close(aObserver))
       
  1069 			{
       
  1070 			// Removed last reference to the Local View so un-Register this view
       
  1071 			// as an observer of database events with the associated
       
  1072 			// CCntDbManager.
       
  1073 			iManager.UnRegisterDatabaseEventObserver(*iNamedLocalViews[index]);
       
  1074 			iNamedLocalViews.Remove(index);
       
  1075 			}
       
  1076 		}
       
  1077 	}
       
  1078 
       
  1079 
       
  1080 CViewManager::CViewManager(MLplPersistenceLayerFactory& aFactory,CCntDbManager& aManager) :
       
  1081 	iFactory(aFactory),
       
  1082 	iManager(aManager)
       
  1083 	{
       
  1084 	}
       
  1085 
       
  1086 
       
  1087 CViewManager::~CViewManager()
       
  1088 	{
       
  1089 	iLocalViews.Close();
       
  1090 	iNamedLocalViews.Close();
       
  1091 	}
       
  1092 
       
  1093 
       
  1094 void CViewManager::ConstructL()
       
  1095 	{
       
  1096 	}
       
  1097 
       
  1098 
       
  1099 #if defined(_DEBUG)
       
  1100 void CViewManager::GetDefinitionsOfExistingViewsL(RPointerArray<CContactDefaultViewDefinition>& aViewDefs)
       
  1101 	{
       
  1102 	__ASSERT_DEBUG(aViewDefs.Count() == 0, User::Leave(KErrArgument));
       
  1103 
       
  1104 	TInt i;
       
  1105 	CContactDefaultViewDefinition* viewDef;
       
  1106 	
       
  1107 	// Anonymous views.
       
  1108 	for (i = 0; i < iLocalViews.Count(); i++)
       
  1109 		{
       
  1110 		CContactLocalView* view = iLocalViews[i].iLocalView;
       
  1111 		viewDef = CContactDefaultViewDefinition::NewLC(CContactDefaultViewDefinition::ERemoteView,
       
  1112 														KNullDesC, view->SortOrderL(), 
       
  1113 														view->ContactViewPreferences(), 
       
  1114 														KNullDesC8/*pluginName*/);
       
  1115 		aViewDefs.AppendL(viewDef);
       
  1116 		CleanupStack::Pop(viewDef);
       
  1117 		}
       
  1118 	
       
  1119 	// Named views.
       
  1120 	for (i = 0; i < iNamedLocalViews.Count(); i++)
       
  1121 		{
       
  1122 		CContactNamedLocalView* view = iNamedLocalViews[i];
       
  1123 		viewDef = CContactDefaultViewDefinition::NewLC(CContactDefaultViewDefinition::ENamedRemoteView,
       
  1124 														view->Name(), view->SortOrderL(), 
       
  1125 														view->ContactViewPreferences(), 
       
  1126 														KNullDesC8/*pluginName*/);
       
  1127 		aViewDefs.AppendL(viewDef);
       
  1128 		CleanupStack::Pop(viewDef);		
       
  1129 		}
       
  1130 	}
       
  1131 #else
       
  1132 void CViewManager::GetDefinitionsOfExistingViewsL(RPointerArray<CContactDefaultViewDefinition>& )
       
  1133 	{
       
  1134 	}
       
  1135 #endif // _DEBUG