plugins/contacts/symbian/contactsmodel/cntplsql/src/clplanalyserproxy.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 
       
    25 
       
    26 #include "clplanalyserproxy.h"
       
    27 #include <cntitem.h>
       
    28 #include <cntfldst.h>
       
    29 
       
    30 /**
       
    31 CLplAnalyserProxy constructor.
       
    32 */
       
    33 CLplAnalyserProxy::CLplAnalyserProxy(MIniFileManager& aIniManager, MContactDbObserverV2& aCntDbObserver, MLplPersistenceBroker& aBroker, MLplTransactionManager& aTranMan, MLplContactProperties& aProperties)
       
    34 	:
       
    35 	CLplGenericProxy(aBroker, aTranMan),
       
    36 	iCntDbObserver(aCntDbObserver),
       
    37 	iIniManager(aIniManager),
       
    38 	iProperties(aProperties)
       
    39 	{
       
    40 	}
       
    41 
       
    42 
       
    43 /**
       
    44 Create a new Contact item.
       
    45 */
       
    46 TContactItemId CLplAnalyserProxy::CreateL(CContactItem& aItem, TUint aSessionId)
       
    47 	{
       
    48 	#if defined(__PROFILE_DEBUG__)
       
    49 		RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::CreateL"));
       
    50 	#endif 
       
    51 
       
    52 	// Delegate creation to generic proxy.
       
    53 	TContactItemId cntId = CLplGenericProxy::CreateL(aItem, aSessionId); 
       
    54 
       
    55 	// Notify observer of the change.
       
    56 	switch(aItem.Type().iUid)
       
    57 		{
       
    58 		case KUidContactCardTemplateValue:
       
    59 			{
       
    60 			NotifyObserverL(EContactDbObserverEventTemplateAdded, aItem.Id());	
       
    61 			}
       
    62 			break;
       
    63 		case KUidContactGroupValue:
       
    64 			{
       
    65 			NotifyObserverL(EContactDbObserverEventGroupAdded, aItem.Id());	
       
    66 			}
       
    67 			break;
       
    68 		case KUidContactCardValue:
       
    69 		case KUidContactOwnCardValue:
       
    70 		case KUidContactICCEntryValue:
       
    71 			{
       
    72 			NotifyObserverL(EContactDbObserverEventContactAdded, aItem.Id());	
       
    73 			}
       
    74 			break;
       
    75 		default:
       
    76 			break;
       
    77 		};		
       
    78 
       
    79 	return(cntId);
       
    80 	}
       
    81 
       
    82 
       
    83 /**
       
    84 Update an existing Contact item (or parts of it as specified by the view
       
    85 definition).
       
    86 */
       
    87 void CLplAnalyserProxy::UpdateL(CContactItem& aItem, TUint aSessionId, TBool aSpeeDailUpdate)
       
    88 	{
       
    89 	// Delegate update to generic proxy.
       
    90 	CLplGenericProxy::UpdateL(aItem, aSessionId);
       
    91 
       
    92 	// Notify observer of the change.
       
    93 	switch(aItem.Type().iUid)
       
    94 		{
       
    95 		case KUidContactTemplateValue:
       
    96 		case KUidContactCardTemplateValue:
       
    97 			{
       
    98 			NotifyObserverL(EContactDbObserverEventTemplateChanged, aItem.Id());	
       
    99 			}
       
   100 			break;
       
   101 		case KUidContactOwnCardValue:
       
   102 			{
       
   103 			NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItem.Id());	
       
   104 			// If an item with a speed dial is updated then update the speed
       
   105 			// dials.
       
   106 			(void)CheckSpeedDialUpdatesL(aItem);
       
   107 			}
       
   108 			break;
       
   109 		case KUidContactGroupValue:
       
   110 			{
       
   111 			// send basic group change event..
       
   112             NotifyObserverL(EContactDbObserverEventGroupChanged, aItem.Id(), 0,
       
   113                 EContactDbObserverEventV2Null, 0);
       
   114 			
       
   115             // ... and extended group change event
       
   116             CContactGroup& groupItem = static_cast<CContactGroup&>(aItem);
       
   117             bool groupMemberListUpdated = false;
       
   118 			if (groupItem.iAddedContactIds != NULL && groupItem.iAddedContactIds->Count() > 0)
       
   119 			    {
       
   120 			    //some contacts were added
       
   121 			    groupMemberListUpdated = true;
       
   122 			    for (int i = 0; i < groupItem.iAddedContactIds->Count(); i++)
       
   123 			        {
       
   124 	                NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0,
       
   125 	                    EContactDbObserverEventV2ContactAddedToGroup, groupItem.iAddedContactIds->operator[](i));			        
       
   126 			        }
       
   127 			    }
       
   128 			if (groupItem.iRemovedContactIds != NULL && groupItem.iRemovedContactIds->Count() > 0)
       
   129 	            {
       
   130 	            //some contacts were removed
       
   131 	            groupMemberListUpdated = true;
       
   132                 for (int i = 0; i < groupItem.iRemovedContactIds->Count(); i++)
       
   133                     {
       
   134 	                NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0,
       
   135 	                    EContactDbObserverEventV2ContactRemovedFromGroup, groupItem.iRemovedContactIds->operator[](i));                    
       
   136 	                }
       
   137 	            }
       
   138             if (!groupMemberListUpdated)
       
   139                 {
       
   140                 NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0,
       
   141                         EContactDbObserverEventV2GroupChanged, 0);
       
   142                 }			
       
   143 			}
       
   144 			break;
       
   145 		case KUidContactCardValue:
       
   146 		case KUidContactICCEntryValue:
       
   147 			{
       
   148 			// If an item with a speed dial is updated then update the speed
       
   149 			// dials.
       
   150 			if (!CheckSpeedDialUpdatesL(aItem) || !aSpeeDailUpdate)
       
   151 				{
       
   152 				NotifyObserverL(EContactDbObserverEventContactChanged, aItem.Id());				
       
   153     			}
       
   154 			}
       
   155 			break;
       
   156 		default:
       
   157 			break;
       
   158 		};
       
   159 	}
       
   160 
       
   161 
       
   162 /**
       
   163 Delete a Contact item.
       
   164 */
       
   165 CContactItem* CLplAnalyserProxy::DeleteLC(TContactItemId  aItemId, TUint aSessionId, TCntSendEventAction aEventType)
       
   166 	{
       
   167 	// Delegate delete to generic proxy.
       
   168 	CContactItem* item = CLplGenericProxy::DeleteLC(aItemId, aSessionId, aEventType); 
       
   169 
       
   170 	// Notify observer of the change.
       
   171 	switch(item->Type().iUid)
       
   172 		{
       
   173 		case KUidContactCardTemplateValue:
       
   174 			{
       
   175 			NotifyObserverL(EContactDbObserverEventTemplateDeleted, item->Id());
       
   176 			// If the prefered template is deleted then do the appropriate
       
   177 			// follow up actions.
       
   178 			CheckPrefTemplateDeleteL(aItemId);
       
   179 			}
       
   180 			break;
       
   181 		case KUidContactOwnCardValue:
       
   182 			{						
       
   183 			if (aEventType == ESendEvent)
       
   184  			    {
       
   185 			    NotifyObserverL(EContactDbObserverEventOwnCardDeleted, item->Id());	
       
   186  			    }							
       
   187  			else if (aEventType == ESendUnknownChangesEvent)
       
   188  				{
       
   189  				NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId);
       
   190  				}
       
   191  				
       
   192 			// If an item with a speed dial is deleted then update the speed
       
   193 			// dials.
       
   194 			CheckSpeedDialDeletesL(aItemId);
       
   195 			// Resets the Own Card ID to be KNullContactId.
       
   196 			iProperties.SetOwnCardIdL(KNullContactId);
       
   197 			}
       
   198 			break;
       
   199 		case KUidContactGroupValue:
       
   200 			{
       
   201 			NotifyObserverL(EContactDbObserverEventGroupDeleted, item->Id());	
       
   202 			}
       
   203 			break;
       
   204 		case KUidContactCardValue:
       
   205 		case KUidContactICCEntryValue:
       
   206 			{
       
   207 			// If an item with a speed dial is deleted then update the speed
       
   208 			// dials.
       
   209 			(void)CheckSpeedDialDeletesL(aItemId);
       
   210 			if (aEventType == ESendEvent)
       
   211  			    {
       
   212 			    NotifyObserverL(EContactDbObserverEventContactDeleted, item->Id());
       
   213  			    }							
       
   214  			else if (aEventType == ESendUnknownChangesEvent)
       
   215  				{
       
   216  				NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId);
       
   217  				}					
       
   218 			}
       
   219 			break;
       
   220 		default:
       
   221 			break;
       
   222 		};
       
   223 
       
   224 	// Check if we deleted the current item (managed by initialisation file
       
   225 	// manager).
       
   226 	iIniManager.DeleteNotifyL(aItemId);
       
   227 
       
   228 	return(item);
       
   229 	}
       
   230 
       
   231 
       
   232 /**
       
   233 Change the type of an existing Contact item.
       
   234 */
       
   235 void CLplAnalyserProxy::ChangeTypeL(TContactItemId aItemId, TUid aNewType)
       
   236 	{
       
   237 	// Delegate type change to generic proxy.
       
   238 	CLplGenericProxy::ChangeTypeL(aItemId, aNewType);
       
   239 
       
   240 	// If a Contact item is changed to be the Own Card then we need to notify
       
   241 	// observers of the change.
       
   242 	if (aNewType.iUid == KUidContactOwnCardValue)
       
   243 		{
       
   244 		NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItemId);	
       
   245 		}
       
   246 	}
       
   247 
       
   248 
       
   249 /**
       
   250 Set the connection ID to be used when notifying observer of a database event
       
   251 (unless a specific connection ID is specified when calling NotifyObserverL()).
       
   252 */
       
   253 void CLplAnalyserProxy::SetConnectionId(TInt aConnectionId)
       
   254 	{
       
   255 	iConnectionId = aConnectionId;	
       
   256 	}
       
   257 
       
   258 
       
   259 /**
       
   260 Notify observer of database event.
       
   261 */
       
   262 void CLplAnalyserProxy::NotifyObserverL(const TContactDbObserverEventType aType,
       
   263         const TContactItemId aContactId, const TUint aConnectionId,
       
   264         const TContactDbObserverEventTypeV2 aTypeV2, const TContactItemId aAdditionalContactId)
       
   265 	{
       
   266 	#if defined(__PROFILE_DEBUG__)
       
   267 		RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::NotifyObserverL"));
       
   268 	#endif 
       
   269 	
       
   270 	TContactDbObserverEventV2 event;
       
   271 	event.iType = aType;
       
   272 	event.iContactId = aContactId;
       
   273 
       
   274 	if(!aConnectionId)
       
   275 		{
       
   276 		event.iConnectionId = iConnectionId;		
       
   277 		}
       
   278 	else
       
   279 		{
       
   280 		event.iConnectionId = aConnectionId;		
       
   281 		}
       
   282 	
       
   283 	event.iTypeV2 = aTypeV2;
       
   284 	event.iAdditionalContactId = aAdditionalContactId;
       
   285 
       
   286 	iCntDbObserver.HandleDatabaseEventV2L(event);	
       
   287 
       
   288 	// Reset connection ID.
       
   289 	iConnectionId = 0;
       
   290 	}
       
   291 
       
   292 	
       
   293 TBool CLplAnalyserProxy::CheckSpeedDialUpdatesL(CContactItem& aItem)
       
   294 	{
       
   295 	TBool retValue = EFalse;
       
   296 
       
   297 	// Check if the specified Contact ID is present in the speed dial array.
       
   298 	// The method returns the number of occurances: if zero then this contact
       
   299 	// is not in the speed dial table.
       
   300 	CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItem.Id());
       
   301 
       
   302 	// Because this contact has one or more speed dial entries we need to ensure
       
   303 	// that the server-side speed dial array is kept up to date with any changes
       
   304 	// by the client. 
       
   305 	for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count)
       
   306 		{
       
   307 		// So there is at least one speed dial with the particular contact ID.
       
   308 		// Fetch speed dial index from array returned by server.
       
   309 		TInt speedDialIndex = speedDialIndices->At(count);
       
   310 		// Fetch phone number associated with speed dial position.
       
   311 		TUid fieldTypeUid = SpeedDialFieldUidFromSpeedDialPosition(speedDialIndex);
       
   312 		TInt fieldPos = aItem.CardFields().Find(fieldTypeUid);
       
   313 		
       
   314 		// Check if the phone number field associated with the speed dial has
       
   315 		// been updated.
       
   316 		if	(fieldPos >= KErrNone)
       
   317 			{		
       
   318 			// Get the requested field (i.e. the field containing the number for
       
   319 			// the speed dial).
       
   320 			CContactItemField& speeddialField = aItem.CardFields()[fieldPos];
       
   321 			// Check if it is a text field otherwise leave.
       
   322 			if (speeddialField.StorageType() != KStorageTypeText)
       
   323 				{
       
   324 				User::Leave(KErrUnknown);		
       
   325 				}
       
   326 			// Fetch phone number associated with speed dial position.
       
   327 			// Truncate it if its length is > KSpeedDialPhoneLength 
       
   328 			TInt numLen = Min(speeddialField.TextStorage()->Text().Length(), KSpeedDialPhoneLength );
       
   329 			TPtrC phoneNumber(speeddialField.TextStorage()->Text().Mid(0, numLen));
       
   330 			// Update the server with the value of this speed dial.
       
   331 			iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, aItem.Id(), phoneNumber, iConnectionId, ETrue);
       
   332 			retValue = ETrue;
       
   333 			}
       
   334 		else
       
   335 			{
       
   336 			// The phone number field associated with the speed dial has been
       
   337 			// deleted.
       
   338 			iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue);
       
   339 			retValue = ETrue;
       
   340 			}
       
   341 		}
       
   342 
       
   343 	CleanupStack::PopAndDestroy(speedDialIndices);
       
   344 
       
   345 	return retValue;
       
   346 	}
       
   347 
       
   348 
       
   349 TBool CLplAnalyserProxy::CheckSpeedDialDeletesL(TContactItemId aItemId)
       
   350 	{
       
   351 	TBool retValue = EFalse;
       
   352 	// Check if the specified contact ID is present in the speed dial array.
       
   353 	// The method returns the number of occurances: if zero then this contact
       
   354 	// is not in the speed dial table.	
       
   355 	CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItemId);	
       
   356 	
       
   357 	// Because this contact has one or more speed dial entries we need to ensure
       
   358 	// that the server-side speed dial array is kept up to date with any changes
       
   359 	// by the client. 
       
   360 	for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count)
       
   361 		{
       
   362 		// Fetch speed dial index.
       
   363 		TInt speedDialIndex = speedDialIndices->At(count);
       
   364 		// Update the speed dial.
       
   365 		iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue);
       
   366 		retValue = ETrue;
       
   367 		}	
       
   368 
       
   369 	CleanupStack::PopAndDestroy(speedDialIndices);
       
   370 
       
   371 	return retValue;
       
   372 	}
       
   373 
       
   374 
       
   375 void CLplAnalyserProxy::CheckPrefTemplateDeleteL(TContactItemId aItemId)
       
   376 	{
       
   377 	if (iProperties.CardTemplatePrefIdL() == aItemId)
       
   378 		{
       
   379 		// Make sure the Own Card ID is persisted and up to date.
       
   380 		iProperties.SetCardTemplatePrefIdL(KNullContactId);
       
   381 		// There was no notification in the old contacts model but there
       
   382 		// probably should have been.
       
   383 		NotifyObserverL(EContactDbObserverEventPreferredTemplateChanged, aItemId);	
       
   384 		}
       
   385 	}
       
   386 
       
   387 
       
   388 /**
       
   389 Static utility method to map a speed dial index onto a field type UID.
       
   390 
       
   391 Note: this method is duplicated, should be refactored into shared code/library.
       
   392 */
       
   393 TUid CLplAnalyserProxy::SpeedDialFieldUidFromSpeedDialPosition(TInt aSpeedDialPosition)
       
   394 	{
       
   395 	TUid fieldTypeUid = KNullUid;
       
   396 	switch (aSpeedDialPosition)
       
   397 		{
       
   398 	case 1:
       
   399 		fieldTypeUid = KUidSpeedDialOne;
       
   400 		break;
       
   401 	case 2:
       
   402 		fieldTypeUid = KUidSpeedDialTwo;
       
   403 		break;
       
   404 	case 3:
       
   405 		fieldTypeUid = KUidSpeedDialThree;
       
   406 		break;
       
   407 	case 4:
       
   408 		fieldTypeUid = KUidSpeedDialFour;
       
   409 		break;
       
   410 	case 5:
       
   411 		fieldTypeUid = KUidSpeedDialFive;
       
   412 		break;
       
   413 	case 6:
       
   414 		fieldTypeUid = KUidSpeedDialSix;
       
   415 		break;
       
   416 	case 7:
       
   417 		fieldTypeUid = KUidSpeedDialSeven;
       
   418 		break;
       
   419 	case 8:
       
   420 		fieldTypeUid = KUidSpeedDialEight;
       
   421 		break;
       
   422 	case 9:
       
   423 		fieldTypeUid = KUidSpeedDialNine;
       
   424 		break;
       
   425 		}
       
   426 	return fieldTypeUid; 
       
   427 	}
       
   428 
       
   429 
       
   430 /**
       
   431 Rollback the current transation in the Persistence Layer.
       
   432 */
       
   433 void CLplAnalyserProxy::RollbackCurrentTransactionL(TUint aSessionId)
       
   434 	{
       
   435 	// Delegate rollback to generic proxy.
       
   436 	CLplGenericProxy::RollbackCurrentTransactionL(aSessionId);
       
   437 	// Notify observer of the rollback.
       
   438 	NotifyObserverL(EContactDbObserverEventRollback, 0);	
       
   439 	}