phonebookengines/contactsmodel/cntplsql/src/clplanalyserproxy.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/clplanalyserproxy.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,400 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#include "clplanalyserproxy.h"
+#include <cntitem.h>
+#include <cntfldst.h>
+
+/**
+CLplAnalyserProxy constructor.
+*/
+CLplAnalyserProxy::CLplAnalyserProxy(MIniFileManager& aIniManager, MContactDbObserver& aCntDbObserver, MLplPersistenceBroker& aBroker, MLplTransactionManager& aTranMan, MLplContactProperties& aProperties)
+	:
+	CLplGenericProxy(aBroker, aTranMan),
+	iCntDbObserver(aCntDbObserver),
+	iIniManager(aIniManager),
+	iProperties(aProperties)
+	{
+	}
+
+
+/**
+Create a new Contact item.
+*/
+TContactItemId CLplAnalyserProxy::CreateL(CContactItem& aItem, TUint aSessionId)
+	{
+	#if defined(__PROFILE_DEBUG__)
+		RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::CreateL"));
+	#endif 
+
+	// Delegate creation to generic proxy.
+	TContactItemId cntId = CLplGenericProxy::CreateL(aItem, aSessionId); 
+
+	// Notify observer of the change.
+	switch(aItem.Type().iUid)
+		{
+		case KUidContactCardTemplateValue:
+			{
+			NotifyObserverL(EContactDbObserverEventTemplateAdded, aItem.Id());	
+			}
+			break;
+		case KUidContactGroupValue:
+			{
+			NotifyObserverL(EContactDbObserverEventGroupAdded, aItem.Id());	
+			}
+			break;
+		case KUidContactCardValue:
+		case KUidContactOwnCardValue:
+		case KUidContactICCEntryValue:
+			{
+			NotifyObserverL(EContactDbObserverEventContactAdded, aItem.Id());	
+			}
+			break;
+		default:
+			break;
+		};		
+
+	return(cntId);
+	}
+
+
+/**
+Update an existing Contact item (or parts of it as specified by the view
+definition).
+*/
+void CLplAnalyserProxy::UpdateL(CContactItem& aItem, TUint aSessionId, TBool aSpeeDailUpdate)
+	{
+	// Delegate update to generic proxy.
+	CLplGenericProxy::UpdateL(aItem, aSessionId);
+
+	// Notify observer of the change.
+	switch(aItem.Type().iUid)
+		{
+		case KUidContactTemplateValue:
+		case KUidContactCardTemplateValue:
+			{
+			NotifyObserverL(EContactDbObserverEventTemplateChanged, aItem.Id());	
+			}
+			break;
+		case KUidContactOwnCardValue:
+			{
+			NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItem.Id());	
+			// If an item with a speed dial is updated then update the speed
+			// dials.
+			(void)CheckSpeedDialUpdatesL(aItem);
+			}
+			break;
+		case KUidContactGroupValue:
+			{
+			NotifyObserverL(EContactDbObserverEventGroupChanged, aItem.Id());	
+			}
+			break;
+		case KUidContactCardValue:
+		case KUidContactICCEntryValue:
+			{
+			// If an item with a speed dial is updated then update the speed
+			// dials.
+			if (!CheckSpeedDialUpdatesL(aItem) || !aSpeeDailUpdate)
+				{
+				NotifyObserverL(EContactDbObserverEventContactChanged, aItem.Id());				
+    			}
+			}
+			break;
+		default:
+			break;
+		};
+	}
+
+
+/**
+Delete a Contact item.
+*/
+CContactItem* CLplAnalyserProxy::DeleteLC(TContactItemId  aItemId, TUint aSessionId, TCntSendEventAction aEventType)
+	{
+	// Delegate delete to generic proxy.
+	CContactItem* item = CLplGenericProxy::DeleteLC(aItemId, aSessionId, aEventType); 
+
+	// Notify observer of the change.
+	switch(item->Type().iUid)
+		{
+		case KUidContactCardTemplateValue:
+			{
+			NotifyObserverL(EContactDbObserverEventTemplateDeleted, item->Id());
+			// If the prefered template is deleted then do the appropriate
+			// follow up actions.
+			CheckPrefTemplateDeleteL(aItemId);
+			}
+			break;
+		case KUidContactOwnCardValue:
+			{						
+			if (aEventType == ESendEvent)
+ 			    {
+			    NotifyObserverL(EContactDbObserverEventOwnCardDeleted, item->Id());	
+ 			    }							
+ 			else if (aEventType == ESendUnknownChangesEvent)
+ 				{
+ 				NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId);
+ 				}
+ 				
+			// If an item with a speed dial is deleted then update the speed
+			// dials.
+			CheckSpeedDialDeletesL(aItemId);
+			// Resets the Own Card ID to be KNullContactId.
+			iProperties.SetOwnCardIdL(KNullContactId);
+			}
+			break;
+		case KUidContactGroupValue:
+			{
+			NotifyObserverL(EContactDbObserverEventGroupDeleted, item->Id());	
+			}
+			break;
+		case KUidContactCardValue:
+		case KUidContactICCEntryValue:
+			{
+			// If an item with a speed dial is deleted then update the speed
+			// dials.
+			(void)CheckSpeedDialDeletesL(aItemId);
+			if (aEventType == ESendEvent)
+ 			    {
+			    NotifyObserverL(EContactDbObserverEventContactDeleted, item->Id());
+ 			    }							
+ 			else if (aEventType == ESendUnknownChangesEvent)
+ 				{
+ 				NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId);
+ 				}					
+			}
+			break;
+		default:
+			break;
+		};
+
+	// Check if we deleted the current item (managed by initialisation file
+	// manager).
+	iIniManager.DeleteNotifyL(aItemId);
+
+	return(item);
+	}
+
+
+/**
+Change the type of an existing Contact item.
+*/
+void CLplAnalyserProxy::ChangeTypeL(TContactItemId aItemId, TUid aNewType)
+	{
+	// Delegate type change to generic proxy.
+	CLplGenericProxy::ChangeTypeL(aItemId, aNewType);
+
+	// If a Contact item is changed to be the Own Card then we need to notify
+	// observers of the change.
+	if (aNewType.iUid == KUidContactOwnCardValue)
+		{
+		NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItemId);	
+		}
+	}
+
+
+/**
+Set the connection ID to be used when notifying observer of a database event
+(unless a specific connection ID is specified when calling NotifyObserverL()).
+*/
+void CLplAnalyserProxy::SetConnectionId(TInt aConnectionId)
+	{
+	iConnectionId = aConnectionId;	
+	}
+
+
+/**
+Notify observer of database event.
+*/
+void CLplAnalyserProxy::NotifyObserverL(const TContactDbObserverEventType aType, const TContactItemId aContactId, const TUint aConnectionId)
+	{
+	#if defined(__PROFILE_DEBUG__)
+		RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::NotifyObserverL"));
+	#endif 
+	
+	TContactDbObserverEvent event;
+	event.iType = aType;
+	event.iContactId = aContactId;
+
+	if(!aConnectionId)
+		{
+		event.iConnectionId = iConnectionId;		
+		}
+	else
+		{
+		event.iConnectionId = aConnectionId;		
+		}	
+
+	iCntDbObserver.HandleDatabaseEventL(event);	
+
+	// Reset connection ID.
+	iConnectionId = 0;
+	}
+
+	
+TBool CLplAnalyserProxy::CheckSpeedDialUpdatesL(CContactItem& aItem)
+	{
+	TBool retValue = EFalse;
+
+	// Check if the specified Contact ID is present in the speed dial array.
+	// The method returns the number of occurances: if zero then this contact
+	// is not in the speed dial table.
+	CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItem.Id());
+
+	// Because this contact has one or more speed dial entries we need to ensure
+	// that the server-side speed dial array is kept up to date with any changes
+	// by the client. 
+	for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count)
+		{
+		// So there is at least one speed dial with the particular contact ID.
+		// Fetch speed dial index from array returned by server.
+		TInt speedDialIndex = speedDialIndices->At(count);
+		// Fetch phone number associated with speed dial position.
+		TUid fieldTypeUid = SpeedDialFieldUidFromSpeedDialPosition(speedDialIndex);
+		TInt fieldPos = aItem.CardFields().Find(fieldTypeUid);
+		
+		// Check if the phone number field associated with the speed dial has
+		// been updated.
+		if	(fieldPos >= KErrNone)
+			{		
+			// Get the requested field (i.e. the field containing the number for
+			// the speed dial).
+			CContactItemField& speeddialField = aItem.CardFields()[fieldPos];
+			// Check if it is a text field otherwise leave.
+			if (speeddialField.StorageType() != KStorageTypeText)
+				{
+				User::Leave(KErrUnknown);		
+				}
+			// Fetch phone number associated with speed dial position.
+			// Truncate it if its length is > KSpeedDialPhoneLength 
+			TInt numLen = Min(speeddialField.TextStorage()->Text().Length(), KSpeedDialPhoneLength );
+			TPtrC phoneNumber(speeddialField.TextStorage()->Text().Mid(0, numLen));
+			// Update the server with the value of this speed dial.
+			iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, aItem.Id(), phoneNumber, iConnectionId, ETrue);
+			retValue = ETrue;
+			}
+		else
+			{
+			// The phone number field associated with the speed dial has been
+			// deleted.
+			iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue);
+			retValue = ETrue;
+			}
+		}
+
+	CleanupStack::PopAndDestroy(speedDialIndices);
+
+	return retValue;
+	}
+
+
+TBool CLplAnalyserProxy::CheckSpeedDialDeletesL(TContactItemId aItemId)
+	{
+	TBool retValue = EFalse;
+	// Check if the specified contact ID is present in the speed dial array.
+	// The method returns the number of occurances: if zero then this contact
+	// is not in the speed dial table.	
+	CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItemId);	
+	
+	// Because this contact has one or more speed dial entries we need to ensure
+	// that the server-side speed dial array is kept up to date with any changes
+	// by the client. 
+	for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count)
+		{
+		// Fetch speed dial index.
+		TInt speedDialIndex = speedDialIndices->At(count);
+		// Update the speed dial.
+		iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue);
+		retValue = ETrue;
+		}	
+
+	CleanupStack::PopAndDestroy(speedDialIndices);
+
+	return retValue;
+	}
+
+
+void CLplAnalyserProxy::CheckPrefTemplateDeleteL(TContactItemId aItemId)
+	{
+	if (iProperties.CardTemplatePrefIdL() == aItemId)
+		{
+		// Make sure the Own Card ID is persisted and up to date.
+		iProperties.SetCardTemplatePrefIdL(KNullContactId);
+		// There was no notification in the old contacts model but there
+		// probably should have been.
+		NotifyObserverL(EContactDbObserverEventPreferredTemplateChanged, aItemId);	
+		}
+	}
+
+
+/**
+Static utility method to map a speed dial index onto a field type UID.
+
+Note: this method is duplicated, should be refactored into shared code/library.
+*/
+TUid CLplAnalyserProxy::SpeedDialFieldUidFromSpeedDialPosition(TInt aSpeedDialPosition)
+	{
+	TUid fieldTypeUid = KNullUid;
+	switch (aSpeedDialPosition)
+		{
+	case 1:
+		fieldTypeUid = KUidSpeedDialOne;
+		break;
+	case 2:
+		fieldTypeUid = KUidSpeedDialTwo;
+		break;
+	case 3:
+		fieldTypeUid = KUidSpeedDialThree;
+		break;
+	case 4:
+		fieldTypeUid = KUidSpeedDialFour;
+		break;
+	case 5:
+		fieldTypeUid = KUidSpeedDialFive;
+		break;
+	case 6:
+		fieldTypeUid = KUidSpeedDialSix;
+		break;
+	case 7:
+		fieldTypeUid = KUidSpeedDialSeven;
+		break;
+	case 8:
+		fieldTypeUid = KUidSpeedDialEight;
+		break;
+	case 9:
+		fieldTypeUid = KUidSpeedDialNine;
+		break;
+		}
+	return fieldTypeUid; 
+	}
+
+
+/**
+Rollback the current transation in the Persistence Layer.
+*/
+void CLplAnalyserProxy::RollbackCurrentTransactionL(TUint aSessionId)
+	{
+	// Delegate rollback to generic proxy.
+	CLplGenericProxy::RollbackCurrentTransactionL(aSessionId);
+	// Notify observer of the rollback.
+	NotifyObserverL(EContactDbObserverEventRollback, 0);	
+	}