diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookengines/contactsmodel/cntplsql/src/clplanalyserproxy.cpp --- /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 +#include + +/** +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* 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* 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); + }