--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/clplanalyserproxy.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -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);
+ }