diff -r 000000000000 -r 094583676ce7 wvuing/wvuistorage/src/CCAStorageManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvuistorage/src/CCAStorageManager.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,2052 @@ +/* +* Copyright (c) 2002-2005 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: Storage manager implementation + * +*/ + + +// INCLUDE FILES +#include "CCAStorageManager.h" +#include "CCAStorage.h" +#include "CCARefreshTimer.h" +#include "CCAContactList.h" +#include "CCAGroup.h" +#include "CCAContact.h" +#include "CCAContactSorter.h" + +#include "CAUtils.h" + +#include "ChatDebugPrint.h" +#include "chatdebugassert.h" + +#include // for KPEngUserOwnPresenceId + +// CONSTANTS +// Own device type, default to mobile +const TStorageManagerGlobals::TClientType KOwnDeviceType = + TStorageManagerGlobals::EMobile; + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::InstanceL +// Factory method to return the singleton instance of this class, +// used by CCAStorageManagerFactory +// ----------------------------------------------------------------------------- +// +CCAStorageManager* CCAStorageManager::InstanceL() + { + CCAStorageManager *sm = NULL; + sm = static_cast( Dll::Tls() ); + if ( ! sm ) + { + // no existing instance, create a new one + CCAStorageManager *manager = CCAStorageManager::NewL(); + sm = manager; + CleanupStack::PushL( manager ); + User::LeaveIfError( Dll::SetTls( static_cast( sm ) ) ); + CleanupStack::Pop( manager ); + } + + return sm; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ReleaseL +// Factory method to release the singleton instance of this class, +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::ReleaseL() + { + // about to unload, so kill the singleton instance + if ( Dll::Tls() ) + { + CCAStorageManager *storage = NULL; + storage = static_cast( Dll::Tls() ); + if ( storage ) + { + delete storage; + storage = NULL; + } + } + // Ignore error + Dll::SetTls( NULL ); + return KErrNone; + } + +// panic handler +GLDEF_C void Panic( TCAStoragePanics aPanic ) + { + User::Panic( KChatStoragePanicString, aPanic ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CCAStorageManager +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCAStorageManager::CCAStorageManager() : + iNotifyUponSave( ETrue ), + iRefreshStartCounter( 0 ), + iShowNickname( ETrue ), + iGroupDeleted( EFalse ) + { + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ConstructL +// Symbian 2nd phase constructor can leave. +// The constructor also does synchronizing with Phone Book by removing the +// deleted elements from the persistent storage +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::ConstructL() + { + CHAT_DP_TXT( "CCAStorageManager::ConstructL" ); + CHAT_DP_TXT( "CCAStorageManager::Creating Storage" ); + iStorage = CCAStorage::NewL(); + + iRefreshTimer = CCARefreshTimer::NewL( this ); + + // create sorter for contacts + iContactSorter = CCAContactSorter::NewL(); + + // handle Groups + CHAT_DP_TXT( "CCAStorageManager::ConstructL - Synching group data with \ + persistent storage" ); + SynchronizeGroupsL(); + + iOwnStatus = CCAContact::NewL( this, this ); + iOwnStatus->SetClientType( KOwnDeviceType ); + + CHAT_DP_TXT( "CCAStorageManager::ConstructL - Done" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SynchronizeGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SynchronizeGroupsL() + { + // read the groups, if any + TBool fetching( ETrue ); + for ( TInt i = 0; fetching ; i++ ) + { + CCAGroup* group = CCAGroup::NewL( iStorage, this ); + CleanupStack::PushL( group ); + + TInt storStatus( KErrNone ); + TInt err( KErrNone ); + + if ( 0 == i ) + { + // first iteration + CHAT_DP_TXT( "CCAStorageManager::SynchronizeGroupsL - Loading \ + first group" ); + // Load Leaves if storage has no more groups + TRAP( err, storStatus = iStorage->LoadFirstL( group ) ); + } + else + { + // subsequent iterations + CHAT_DP_TXT( "CCAStorageManager::SynchronizeGroupsL - Loading next \ + group" ); + // Load Leaves if storage has no more groups + TRAP( err, storStatus = iStorage->LoadNextL( group ) ); + } + + if ( ( KErrNotFound == storStatus ) || ( KErrNone != err ) ) + { + // no more groups, that's all + CHAT_DP_TXT( "CCAStorageManager::SynchronizeGroupsL - No groups in \ + persistent storage" ); + fetching = EFalse; + } + else + { + // found some group, add to our list + CHAT_DP_TXT( "CCAStorageManager::SynchronizeGroupsL - Found group, \ + adding to list" ); + + // valid group, add to our list + group->SetStorageType( TStorageManagerGlobals::EStoragePersistent ); + TInt status = iGroupList.Append( group ); + User::LeaveIfError( status ); + } + + if ( fetching == EFalse ) + { + // all done + CleanupStack::PopAndDestroy( group ); // group + } + else + { + // going to next iteration + CleanupStack::Pop( group ); // group + } + } + + CHAT_DP_TXT( "CCAStorageManager::SynchronizeGroupsL - Done" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCAStorageManager* CCAStorageManager::NewL() + { + CCAStorageManager* self = new( ELeave ) CCAStorageManager; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// Destructor +CCAStorageManager::~CCAStorageManager() + { + CHAT_DP_TXT( "CCAStorageManager::~CCAStorageManager" ); + + delete iRefreshTimer; + delete iLatestContactToRefresh; + + iContactObservers.Reset(); + iContactObservers.Close(); + + iGroupObservers.Reset(); + iGroupObservers.Close(); + + iContactList.ResetAndDestroy(); + iGroupList.ResetAndDestroy(); + + delete iStorage; + + delete iContactSorter; + + delete iOwnStatus; + + CHAT_DP_TXT( "CCAStorageManager::~CCAStorageManager - I am dead" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SendObserverEventL +// If the changed/deleted contact is in our list, the observers are notified. +// Otherwise the observers are not notified. +// ----------------------------------------------------------------------------- +void CCAStorageManager::SendObserverEvent( + TStorageManagerGlobals::TCAObserverEventType aType, + MCAStoredContact* aContact, + const TDesC& aContactId, + MCAContactList* aList /*= NULL*/, + TBool aUserIdChanged /*= EFalse*/ ) + { + CHAT_DP_TXT( "CCAStorageManager::SendObserverEventL (contact)" ); + CHAT_DP_TXT( "CCAStorageManager::SendObserverEventL - Notifying \ + MCAStoredContactsObserver observers" ); + + if ( !iContactListLock ) + { + switch ( aType ) + { + case TStorageManagerGlobals::EStorageEventPostChange: // flowtrough + case TStorageManagerGlobals::EStorageEventOwnStatusChange: + { + NotifyAllObserversWithDelay( aType, aContact, aContactId, aList, + aUserIdChanged ); + break; + } + default: + { + NotifyAllObservers( aType, aContact, aContactId, aList, aUserIdChanged ); + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::NotifyAllObservers +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::NotifyAllObservers( TStorageManagerGlobals::TCAObserverEventType aType, + MCAStoredContact* aContact, const TDesC& aContactId, + MCAContactList* aList, + TBool aUserIdChanged ) + { + CHAT_DP_FUNC_ENTER( "NotifyAllObservers" ); + + // tell all of the observers about the event. + // the amount of observers might change during the loop, + // so the count MUST be taken in every round + for ( TInt i = 0; i < iContactObservers.Count(); i++ ) + { + MCAStoredContactsObserver* obs = iContactObservers[i]; + switch ( aType ) + { + case TStorageManagerGlobals::EStorageEventPreChange: + case TStorageManagerGlobals::EStorageEventPostChange: + { + obs->HandleChange( aList, aContact, aType, aUserIdChanged ); + break; + } + case TStorageManagerGlobals::EStorageEventContactDelete: + { + obs->HandleContactDelete( aContactId ); + break; + } + case TStorageManagerGlobals::EStorageEventContactAddition: + { + if ( aList ) + { + obs->HandleAddition( *aList, *aContact ); + } + break; + } + case TStorageManagerGlobals::EStorageEventOwnStatusChange: + case TStorageManagerGlobals::EStorageEventMultipleChanges: + case TStorageManagerGlobals::EStorageEventListAddition: + case TStorageManagerGlobals::EStorageEventListDelete: + case TStorageManagerGlobals::EStorageEventListChanged: + { + obs->HandleChange( aList, NULL, aType, EFalse ); + break; + } + default: + { + break; + } + } + } + + CHAT_DP_FUNC_DONE( "NotifyAllObservers" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::NotifyAllObserversWithDelay +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::NotifyAllObserversWithDelay( + TStorageManagerGlobals::TCAObserverEventType aType, + MCAStoredContact* aContact, const TDesC& aContactId, + MCAContactList* aList, + TBool aUserIdChanged ) + { + TRAPD( err, DoNotifyAllObserversWithDelayL( aType, aContact, aContactId, + aList, aUserIdChanged ) ); + if ( err ) + { + CActiveScheduler::Current()->Error( err ); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::DoNotifyAllObserversWithDelayL +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::DoNotifyAllObserversWithDelayL( + TStorageManagerGlobals::TCAObserverEventType aType, + MCAStoredContact* /*aContact*/, const TDesC& aContactId, + MCAContactList* aList, TBool aUserIdChanged ) + { + HBufC* tmpID = aContactId.AllocL(); + delete iLatestContactToRefresh; + iLatestContactToRefresh = tmpID; + iLatestContactList = aList; + tmpID = NULL; + iRefreshEventType = aType; + iRefreshUserIdChanged = aUserIdChanged; + ++iRefreshStartCounter; + if ( iRefreshTimer->IsActive() ) + { + iRefreshTimer->Cancel(); + } + iRefreshTimer->Start(); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SendObserverEventL (overridden for group) +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SendObserverEvent( + TStorageManagerGlobals::TCAObserverEventType aType, + const TDesC& aParameter ) + { + CHAT_DP_TXT( "CCAStorageManager::SendObserverEventL (group)" ); + + TInt pos( FindGroupIndexByGroupId( aParameter ) ); + if ( KErrNotFound == pos ) + { + return; // not found in the list + } + + CHAT_DP_TXT( "CCAStorageManager::SendObserverEventL - Notifying \ + MCAStoredGroupsObserver observers" ); + + // tell all of the observers about the event + const TInt count( iGroupObservers.Count() ); + for ( TInt i = 0; i < count; i++ ) + { + MCAStoredGroupsObserver* obs = iGroupObservers[i]; + + switch ( aType ) + { + case TStorageManagerGlobals::EStorageEventGroupChange: + { + obs->HandleChange( aParameter ); + break; + } + + case TStorageManagerGlobals::EStorageEventContactDelete: + { + obs->HandleDelete( aParameter ); + break; + } + + case TStorageManagerGlobals::EStorageEventContactAddition: + { + obs->HandleAddition( aParameter ); + break; + } + default: + { + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::AddObserverL +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::AddObserverL( MCAStoredContactsObserver* + aObserver ) + { + __ASSERT_ALWAYS( aObserver, Panic( EObserverIsNull ) ); + + TInt status( iContactObservers.Append( aObserver ) ); + User::LeaveIfError( status ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::RemoveObserverL +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +void CCAStorageManager::RemoveObserver( MCAStoredContactsObserver* + aObserver ) + { + __ASSERT_ALWAYS( aObserver, Panic( EObserverIsNull ) ); + + const TInt status( iContactObservers.Find( aObserver ) ); + if ( status != KErrNotFound ) + { + iContactObservers.Remove( status ); + iContactObservers.Compress(); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::AddObserverL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::AddObserverL( MCAStoredGroupsObserver* + aObserver ) + { + __ASSERT_ALWAYS( aObserver, Panic( EObserverIsNull ) ); + + TInt status( iGroupObservers.Append( aObserver ) ); + User::LeaveIfError( status ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::RemoveObserverL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::RemoveObserver( MCAStoredGroupsObserver* + aObserver ) + { + __ASSERT_ALWAYS( aObserver, Panic( EObserverIsNull ) ); + + const TInt status( iGroupObservers.Find( aObserver ) ); + if ( status != KErrNotFound ) + { + iGroupObservers.Remove( status ); + iGroupObservers.Compress(); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::AddContactListIdL +// ----------------------------------------------------------------------------- +// +MCAContactList* CCAStorageManager::AddContactListIdL( + const TDesC& aContactListId, + const TDesC& aDisplayName, + TBool aNotify ) + { + CCAContactList* contactList = CCAContactList::NewLC( *this, + *iContactSorter, + *this, + aContactListId, + aDisplayName ); + TIdentityRelation< CCAContactList > findBy( + CCAStorageManager::ContactListFindByContactId ); + TInt indexOfList( iContactList.Find( contactList, findBy ) ); + if ( indexOfList == KErrNotFound ) + { + TLinearOrder< CCAContactList > order( + CCAStorageManager::ContactListOrderByDisplayName ); + iContactList.InsertInOrderAllowRepeats( contactList, order ); + CleanupStack::Pop( contactList ); + } + else + { + CleanupStack::PopAndDestroy( contactList ); + contactList = iContactList[ indexOfList ]; + } + // Inform observers + if ( aNotify ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventListAddition, + NULL, + KNullDesC, contactList, EFalse ); + } + return contactList; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetContactListCollapsed +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetContactListCollapsed( const TDesC& aContactListId, + TBool aCollapsed ) + { + TInt pos( FindContactListById( aContactListId ) ); + if ( pos >= 0 ) + { + MCAContactList& list = *iContactList[ pos ]; + list.SetCollapsed( aCollapsed ); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::RemoveContactList +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::RemoveContactList( const TDesC& aContactListId ) + { + TInt pos( FindContactListById( aContactListId ) ); + if ( pos >= 0 ) + { + delete iContactList[ pos ]; + iContactList.Remove( pos ); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::RemoveContact +// From MCAStoredContacts. +// ----------------------------------------------------------------------------- +void CCAStorageManager::RemoveContact( const TDesC& aListId, + const TDesC& aContactId ) + { + CCAContactList* list = FindContactListInternal( aListId ); + if ( list ) + { + if ( KErrNone == list->RemoveContact( aContactId ) ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventContactDelete, + NULL, + aContactId ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContact +// From MCAStoredContacts. +// Try to load with given ID, return NULL if not found. +// ----------------------------------------------------------------------------- +MCAStoredContact* CCAStorageManager::FindContact( const TDesC& aContactListId, + const TDesC& aId ) + { + CCAContactList* list = FindContactListInternal( aContactListId ); + if ( list ) + { + return list->FindContact( aId ); + } + CHAT_DP_FUNC_DONE( "CCAStorageManager::FindContact" ); + return NULL; + } + +MCAStoredContact* CCAStorageManager::FindContact( const TDesC& aContactListId, + const TDesC& aId, + MCAContactList*& aContactList ) + { + CCAContactList* list = FindContactListInternal( aContactListId ); + aContactList = list; + if ( list ) + { + return list->FindContact( aId ); + } + CHAT_DP_FUNC_DONE( "CCAStorageManager::FindContact" ); + return NULL; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ContactInAnyList +// From MCAStoredContacts. +// ----------------------------------------------------------------------------- +TBool CCAStorageManager::ContactInAllLists( const TDesC& aContactId ) const + { + TInt listCount( iContactList.Count() ); + for ( TInt a( 0 ); a < listCount; ++a ) + { + if ( !iContactList[ a ]->FindContact( aContactId ) ) + { + return EFalse; + } + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContact +// From MCAStoredContacts. +// Try to load with given ID, return NULL if not found. +// ----------------------------------------------------------------------------- +MCAStoredContact* CCAStorageManager::FindAnyContact( const TDesC& aContactId ) + { + if ( aContactId.Compare( KPEngUserOwnPresenceId ) == 0 ) + { + return iOwnStatus; + } + + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + return contact; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindAnyContactByNick +// From MCAStoredContacts. +// Try to load with given nick, return NULL if not found. +// ----------------------------------------------------------------------------- +MCAStoredContact* CCAStorageManager::FindAnyContactByNick( const TDesC& aNick ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = + iContactList[ a ]->FindContactByNick( aNick ); + if ( contact ) + { + return contact; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ListCount +// Count of contactlists +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::ListCount() const + { + return iContactList.Count(); + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ListAt +// Reference to contact list +// ----------------------------------------------------------------------------- +// +MCAContactList& CCAStorageManager::ListAt( TInt aIndex ) const + { + + return *iContactList[ aIndex ]; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ListAt +// Reference to contact list +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::FindContacts( RPointerArray< MCAStoredContact >& aArray, + const TDesC& aContactId ) const + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = iContactList[a]->FindContact( aContactId ); + if ( contact ) + { + TInt err( aArray.Append( contact ) ); + if ( err != KErrNone ) + { + CActiveScheduler::Current()->Error( err ); + return; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ContactCount +// Count of contacts +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::ContactCount( TBool aSkipOfflineContacts ) const + { + TInt contactCount( 0 ); + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + contactCount += iContactList[ a ]->ContactCount( aSkipOfflineContacts, + EFalse ); + } + return contactCount; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetWVHiding +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetWVHiding( TBool aHiding ) + { + iWVHiding = aHiding; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::WVHiding +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::WVHiding() + { + return iWVHiding; + } +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetWVHidingPrefixOnly UI CR : 101-39728 +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetWVHidingPrefixOnly( TBool aHidingPrefixOnly ) + { + iWVHidingPrefixOnly = aHidingPrefixOnly; + } +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// CCAStorageManager::CapitalizingEnabled UI CR : 101-39727 +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetCapitalizingEnabled( TBool aCapital ) + { + iCapital = aCapital; + } +// CCAStorageManager::WVHidingPrefixOnly UI CR : 101-39728 +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::WVHidingPrefixOnly() + { + return iWVHidingPrefixOnly; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CapitalizingEnabled UI CR : 101-39727 +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::CapitalizingEnabled() + { + return iCapital; + } +// ----------------------------------------------------------------------------- +// CCAStorageManager::CreateGroupL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +MCAExtendedStoredGroup* CCAStorageManager::CreateGroupL() + { + CHAT_DP_FUNC_ENTER( "CreateGroupL" ); + + if ( ! iStorage ) + { + CHAT_DP_FUNC_DP( "CreateGroupL", "No Storage Manager" ); + User::Leave( KErrNotReady ); + } + + CCAGroup* group = CCAGroup::NewL( iStorage, this ); + + // add to our list + TInt status( iGroupList.Append( group ) ); // takes ownership (RPointerArray) + if ( status != KErrNone ) + { + delete group; + User::Leave( status ); + } + + CHAT_DP_FUNC_DONE( "CreateGroupL" ); + return group; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::DeleteGroup +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::DeleteGroupL( MCAStoredGroup* aGroup ) + { + CHAT_DP_FUNC_ENTER( "DeleteGroupL" ); + + if ( ! iStorage ) + { + CHAT_DP_FUNC_DP( "DeleteGroupL", "No Storage Manager" ); + User::Leave( KErrNotReady ); + } + + const TInt pos( FindGroupIndexByGroupId( aGroup->GroupId() ) ); + + if ( KErrNotFound == pos ) + { + // not in the list + CHAT_DP_FUNC_DP( "DeleteGroupL", "Group not in the list, not deleting" ); + return; + } + + // notify observers BEFORE deleting group + SendObserverEvent( TStorageManagerGlobals::EStorageEventContactDelete, + aGroup->GroupId() ); + + if ( aGroup->StorageType() == TStorageManagerGlobals::EStoragePersistent ) + { + // is saved to persistent storage, so we can delete from + // persistent storage + CHAT_DP_FUNC_DP( "DeleteGroupL", "Deleting from persistent storage" ); + iStorage->DeleteL( ( MCAExtendedStoredGroup* ) aGroup ); + } + // otherwise it's just in the internal list, + // so delete from internal list + CHAT_DP_FUNC_DP( "DeleteGroupL", "Deleting from internal list" ); + + delete iGroupList[ pos ]; + iGroupList.Remove( pos ); + iGroupList.Compress(); + + CHAT_DP_FUNC_DONE( "DeleteGroupL" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindGroup +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +MCAStoredGroup* CCAStorageManager::FindGroup( const TDesC& aId ) + { + const TInt pos( FindGroupIndexByGroupId( aId ) ); + return KErrNotFound == pos ? NULL : iGroupList[ pos ]; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::PopulateGroupsList +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::PopulateGroupsListL( + RPointerArray& aList, + TBool aReturnOnlyVisible ) + { + aList.Reset(); + + if ( ! iStorage ) + { + return; + } + + const TInt count( iGroupList.Count() ); + for ( int i = 0; i < count; i++ ) + { + if ( aReturnOnlyVisible ) + { + if ( iGroupList[ i ]->IsVisible() ) + { + // only add visible groups + TInt status( aList.Append( iGroupList[ i ] ) ); + User::LeaveIfError( status ); + } + } + else + { + // add all groups + TInt status( aList.Append( iGroupList[ i ] ) ); + User::LeaveIfError( status ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SignalGroupChangedL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SignalGroupChangedL( const TDesC& aGroupId ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventGroupChange, aGroupId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SignalGroupAddedL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SignalGroupAddedL( const TDesC& aGroupId ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventContactAddition, aGroupId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SaveGroupL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SaveGroupL( const TDesC& aGroupId ) + { + const TInt pos( FindGroupIndexByGroupId( aGroupId ) ); + + if ( pos == KErrNotFound ) + { + // no such group + User::Leave( KErrNotFound ); + } + + iGroupList[ pos ]->SaveChangesL(); + SignalGroupAddedL( aGroupId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HideAllGroupsL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HideAllGroups( TBool aAllGroups /*= EFalse*/ ) + { + CHAT_DP_FUNC_ENTER( "HideAllGroups" ); + + const TInt count( iGroupList.Count() ); + for ( TInt i = 0; i < count; i++ ) + { + CCAGroup * group = iGroupList[i]; + if ( aAllGroups || group->IsOwnGroup() ) + { + // only OWN groups are set to invisible if aAllGroups is EFalse.. + group->SetVisible( EFalse ); + } + } + + CHAT_DP_FUNC_DONE( "HideAllGroups" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ShowAllGroups +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::ShowAllGroups() + { + CHAT_DP_FUNC_ENTER( "ShowAllGroups" ); + + const TInt count( iGroupList.Count() ); + for ( TInt i = 0; i < count; i++ ) + { + CCAGroup * group = iGroupList[i]; + // ALL groups are set to visible... + group->SetVisible( ETrue ); + } + + CHAT_DP_FUNC_DONE( "ShowAllGroups" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::GroupCount +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::GroupCount( TBool aOnlyVisible ) const + { + if ( ! aOnlyVisible ) + { + return iGroupList.Count(); + } + + // find out number of visible groups + TInt count = iGroupList.Count(); + TInt grCount = 0; + for ( TInt i = 0; i < count; i++ ) + { + grCount += iGroupList[ i ]->IsVisible() ? 1 : 0; + } + + return grCount; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CheckFreespaceLevelL +// From MCAStoredGroups +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::CheckFreespaceLevelL( MCAExtendedStoredGroup* aGroup ) + { + iStorage->CheckFreespaceLevelL( aGroup ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetNotifyOnSave +// From MCAStoredContacts +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetNotifyOnSave( TBool aStatus ) + { + iNotifyUponSave = aStatus; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleDelete +// From MCAStoredContactsObserver +// We know when the contact is deleted, because it happens +// via Storage Manager, so this method unused. +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleContactDelete( const TDesC& /* aContact */ ) + { + // unused + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleAddition +// From MCAStoredContactsObserver +// We know when the contact is added, because it happens +// via Storage Manager, so this method unused. +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleAddition( MCAContactList& /*aList*/, + MCAStoredContact& /* aContact */ ) + { + // unused + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleChange +// From MCAStoredContactsObserver +// The contact might be saved via CCAContact::SaveChangesL call, +// in which case we wouldn't know about it. But this observer +// call is invoked if the contact was SaveChangesL'd AND there was +// changed information. +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleChange( MCAContactList* aList, + MCAStoredContact* aContact, + TStorageManagerGlobals::TCAObserverEventType aEventType, + TBool aUserIdChanged ) + { + // contact was changed, possibly the contact WVID has changed (which is the + // key). keep our lists sorted. we do it by removing the old from the + // list, then adding it again. it's faster (2*O(logN)) than sorting + // (O(NlogN)). + if ( !aContact && !aList ) + { + return; + } + + if ( iNotifyUponSave ) + { + // ignore the event type. + // this is a post-change as it comes directly from the CCAContact + if ( aContact ) // contact + { + NotifyAllObserversWithDelay( + TStorageManagerGlobals::EStorageEventPostChange, + aContact, aContact->UserId(), + NULL, aUserIdChanged ); + } + else if ( aList ) + { + NotifyAllObserversWithDelay( + aEventType, + NULL, KNullDesC, + aList, aUserIdChanged ); + } + else //own status + { + NotifyAllObserversWithDelay( + TStorageManagerGlobals::EStorageEventOwnStatusChange, + NULL, KPEngUserOwnPresenceId, + NULL, aUserIdChanged ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleBackupRestoreEvent +// From MCAStoredContactsObserver, MCAStoredGroupsObserver +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleBackupRestoreEvent( + const TStorageManagerGlobals::TCAObserverEventType /* aEventType */ ) + { + // unused + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleDelete +// From MCAStoredGroupsObserver +// All deletions happen via Storage Manager. +// But group hiding is handled as deletion from UI point of view. +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleDelete( const TDesC& aId ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventContactDelete, aId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleAddition +// From MCAStoredGroupsObserver +// Unused: all additions happen via Storage Manager +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleAddition( const TDesC& /* aId */ ) + { + // unused + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleChange +// From MCAStoredGroupsObserver +// The group might be saved via CCAContact::SaveChangesL call, +// in which case we wouldn't know about it. But this observer +// call is invoked if the group was SaveChangesL'd AND there was +// changed information. +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleChange( const TDesC& aId ) + { + if ( iNotifyUponSave ) + { + // ignoring error because can't do anything + // if signal group change fails + TInt ignore; + TRAP( ignore, SignalGroupChangedL( aId ) ); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::HandleTimeWaited +// From MCARefreshTimerObserver +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::HandleTimeWaited( const TInt /* aError */ ) + { + if ( !iContactListLock ) + { + if ( iRefreshStartCounter == 1 ) + { + // checking that contact still exists + MCAStoredContact* contact = FindAnyContact( *iLatestContactToRefresh ); + MCAContactList* contactList = NULL; + for ( TInt a( 0 ); a < iContactList.Count() && !contactList; ++a ) + { + if ( iContactList[ a ] == iLatestContactList ) + { + contactList = iLatestContactList; + } + } + if ( contact ) + { + switch ( iRefreshEventType ) + { + case TStorageManagerGlobals::EStorageEventPostChange: + case TStorageManagerGlobals::EStorageEventOwnStatusChange: + { + NotifyAllObservers( iRefreshEventType, + contact, contact->UserId(), + NULL, iRefreshUserIdChanged ); + break; + } + default: + { + break; + } + } + } + else if ( contactList ) + { + NotifyAllObservers( iRefreshEventType, NULL, KNullDesC, contactList, EFalse ); + } + } + else + { + for ( TInt i = 0; i < iContactObservers.Count(); i++ ) + { + MCAStoredContactsObserver* obs = iContactObservers[i]; + obs->HandleChange( + NULL, NULL, /* multiple changes, contact id does not matter */ + TStorageManagerGlobals::EStorageEventMultipleChanges, + iRefreshUserIdChanged ); + } + } + iRefreshStartCounter = 0; + } + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CollapseLocked +// From MCAStorageInfo +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::CollapseLocked() + { + return iContactListLock; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ShowNickname +// From MCAStorageInfo +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::ShowNickname() + { + return iShowNickname; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CreateContactL +// From MCAExtendedStoredContact +// ----------------------------------------------------------------------------- +// +MCAStoredContact* CCAStorageManager::CreateContactL( + const TDesC& aContactList, + const TDesC& aNickname, + const TDesC& aWVID ) + { + CHAT_DP_FUNC_ENTER( "CreateContactL" ); + + CCAContactList* contactList = FindContactListInternal( aContactList ); + if ( !contactList ) + { + User::LeaveIfError( iOperationError ); + User::Leave( KErrNotFound ); + } + + CCAContact* contact = CCAContact::NewL( this, this ); + CleanupStack::PushL( contact ); + + contact->SetUserIdL( aWVID ); + contact->SetNicknameL( aNickname ); + + MCAStoredContact* addedContact = contactList->AddContactL( contact ); + + TBool notify( EFalse ); + if ( addedContact == contact ) + { + // contact added + CleanupStack::Pop( contact ); + notify = ETrue; + } + else + { + // contact existed + CleanupStack::PopAndDestroy( contact ); + // was something updated? + if ( KErrNone != addedContact->Nickname().Compare( aNickname ) ) + { + addedContact->SetNicknameL( aNickname ); + notify = ETrue; + } + if ( KErrNone != addedContact->UserId().Compare( aWVID ) ) + { + addedContact->SetUserIdL( aWVID ); + notify = ETrue; + } + // something was updated, we need to resort the contact + if ( notify ) + { + contactList->ResortContact( addedContact ); + } + } + if ( notify ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventContactAddition, + addedContact, + addedContact->UserId(), contactList, EFalse ); + } + return addedContact; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::CreateContactL +// ----------------------------------------------------------------------------- +// +MCAStoredContact* CCAStorageManager::CreateContactL( + MCAContactList& aContactList, + const TDesC& aNickname, + const TDesC& aWVID, + TStorageManagerGlobals::TPresenceStatus aStatus, + TStorageManagerGlobals::TClientType aType, + const TDesC& aAlias, + const TDesC& aStatusText ) + { + CCAContactList& contactList = ( CCAContactList& )aContactList; + + CCAContact* contact = CCAContact::NewL( this, this ); + CleanupStack::PushL( contact ); + + contact->SetUserIdL( aWVID ); + contact->SetNicknameL( aNickname ); + + // update attributes + contact->SetOnlineStatus( aStatus ); + contact->SetAliasL( aAlias ); + contact->SetStatusTextL( aStatusText ); + contact->SetClientType( aType ); + + MCAStoredContact* addedContact = contactList.AddContactL( contact ); + // was contact inserted to array, or did it exists? + if ( addedContact == contact ) + { + CleanupStack::Pop( contact ); + } + else + { + CleanupStack::PopAndDestroy( contact ); + // contact was already therem, update attributes and resort that contact + // update attributes + addedContact->SetOnlineStatus( aStatus ); + addedContact->SetAliasL( aAlias ); + addedContact->SetStatusTextL( aStatusText ); + addedContact->SetClientType( aType ); + contactList.ResortContact( addedContact ); + } + + // this is used at fetching, so do not notify any observer, will be done for whole list + return addedContact; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SendContactListUpdatedEvent +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SendContactListUpdatedEvent( MCAContactList& aList ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventListChanged, + NULL, + KNullDesC, &aList, EFalse ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::RemoveAllContactsL +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::RemoveAllContactsL() + { + CHAT_DP_FUNC_ENTER( "RemoveAllContactsL" ); + + // work backwards because the removal removes from + // the array, in which case the length changes! + iContactList.ResetAndDestroy(); + + // Notify observers + NotifyAllObservers( TStorageManagerGlobals::EStorageEventMultipleChanges, + NULL, KNullDesC(), NULL, EFalse ); + + CHAT_DP_FUNC_DONE( "RemoveAllContactsL" ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetShowNickname +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetShowNickname( TBool aShowNickname ) + { + iShowNickname = aShowNickname; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ClearSelected +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::ClearSelected() + { + TInt listCount( iContactList.Count() ); + for ( TInt listI( 0 ); listI < listCount; ++listI ) + { + MCAContactList& list = *iContactList[listI]; + list.SetSelected( EFalse ); + + TInt count( list.Count() ); + for ( TInt i( 0 ); i < count; ++i ) + { + MCAStoredContact& contact = list[i]; + contact.SetSelected( EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::GetSelectedL +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::GetSelectedL( RPointerArray& aSelected, + TStorageManagerGlobals::TFilterType aFilter ) + { + TInt listCount( iContactList.Count() ); + + for ( TInt listI( 0 ); listI < listCount; ++listI ) + { + MCAContactList& list = *iContactList[listI]; + TBool listSelected( list.Selected() ); + + TInt count( list.Count() ); + for ( TInt i( 0 ); i < count; ++i ) + { + MCAStoredContact& contact = list[i]; + + if ( aFilter != TStorageManagerGlobals::EFilterAll ) + { + // Check with the filter + if ( ( listSelected || contact.Selected() ) + && list.FilterAllowsContact( &contact, aFilter ) ) + { + aSelected.AppendL( &contact ); + } + } + else + { + // Do not use filter + if ( listSelected || contact.Selected() ) + { + aSelected.AppendL( &contact ); + } + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindGroupIndexByGroupId +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::FindGroupIndexByGroupId( const TDesC& aId ) + { + const TInt count( iGroupList.Count() ); + for ( TInt i = 0; i < count; i++ ) + { + CCAGroup* group = iGroupList[i]; + + if ( 0 == CAUtils::NeutralCompare( group->GroupId(), aId ) ) + { + CHAT_DP_FUNC_DP( "FindGroupIndexByGroupId", "Found matching group" ); + // found it + return i; + } + } + + CHAT_DP_FUNC_DP( "FindGroupIndexByGroupId", "No such group" ); + + return KErrNotFound; + } + +// TLinearOrder +// ----------------------------------------------------------------------------- +// CCAStorageManager::ContactListOrderByDisplayName +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::ContactListOrderByDisplayName( + const CCAContactList& aContactListA, + const CCAContactList& aContactListB ) + { +#ifdef IMPS_CONTACT_FETCH_BACKGROUND + + // Check fetch status + TBool listANotFetched = + aContactListA.Synchronised() == MCAContactList::ESynchroniseNotDone; + TBool listBNotFetched = + aContactListB.Synchronised() == MCAContactList::ESynchroniseNotDone; + + if ( listANotFetched && !listBNotFetched ) + { + // list A not fetched, B fetched/failed => order B first + return 1; + } + else if ( !listANotFetched && listBNotFetched ) + { + // list A fetched/failed, B not fetched => order A first + return -1; + } + else + { + // Both fetched/failed or both not fetched => order by display name + return aContactListA.DisplayName().CompareC( aContactListB.DisplayName() ); + } + +#else + + return aContactListA.DisplayName().CompareC( aContactListB.DisplayName() ); + +#endif // IMPS_CONTACT_FETCH_BACKGROUND + } + +// TIdentityRelation +// ----------------------------------------------------------------------------- +// CCAStorageManager::ContactListFindByContactId +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::ContactListFindByContactId( + const CCAContactList& aContactListA, + const CCAContactList& aContactListB ) + { + const MCAContactList& listA = aContactListA; + const MCAContactList& listB = aContactListB; + return ( CAUtils::NeutralCompare( listA.ListId(), + listB.ListId(), EFalse ) == 0 ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetWatched +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetWatched( const TDesC& aContactId, TBool aStatus ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = + iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + contact->SetWatched( aStatus ); + contact->SignalChanges(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetWatched +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetPendingMessages( const TDesC& aContactId, TInt aAmount ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = + iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + contact->SetPendingMessages( aAmount ); + contact->SignalChanges(); + } + } + } +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetBlocked +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetBlocked( const TDesC& aContactId, TBool aStatus ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = + iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + contact->SetBlocked( aStatus ); + contact->SignalChanges(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetBlocked +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetBlocked( const TDesC& aContactId, + const TDesC& aListId, + TBool aStatus ) + { + CCAContactList* list = FindContactListInternal( aListId ); + if ( list ) + { + MCAStoredContact* contact = list->FindContact( aContactId ); + if ( contact ) + { + contact->SetBlocked( aStatus ); + contact->SignalChanges(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::Sort +/// KNullDesC -> sort all +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::Sort( const TDesC& aContactListId /* = KNullDesC */ ) + { + if ( aContactListId.Length() != 0 ) + { + MCAContactList* list = FindContactList( aContactListId ); + if ( list ) + { + list->Sort(); + } + } + else + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAContactList& list = *iContactList[ a ]; + list.Sort(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::Sort +/// KNullDesC -> sort all +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::ResortContactInAll( MCAStoredContact* aContact ) + { + TInt count( iContactList.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + iContactList[ x ]->ResortUnKnownContact( aContact ); + } + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetSortAlgorithm +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetSortAlgorithm( + MCAStoredContact::TSortAlgorithm aAlgorithm ) + { + iContactSorter->SetSortAlgorithm( aAlgorithm ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::OnlineStatus +// ----------------------------------------------------------------------------- +// +TStorageManagerGlobals::TPresenceStatus CCAStorageManager::OnlineStatus( + const TDesC& aContactId ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + return contact->OnlineStatus(); + } + } + return TStorageManagerGlobals::EUnknown; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::UpdatePresenceL +// ----------------------------------------------------------------------------- +// +MCAStoredContact* CCAStorageManager::UpdatePresenceL( + const TDesC& aContactId, + TStorageManagerGlobals::TPresenceStatus aStatus, + TStorageManagerGlobals::TClientType aType, + const TDesC& aAlias, + const TDesC& aStatusText, + TStorageManagerGlobals::TPresenceStatus& aOldOnlineStatus ) + { + RPointerArray< MCAStoredContact > tempArray; + CleanupClosePushL( tempArray ); + RPointerArray< MCAContactList > listArray; + CleanupClosePushL( listArray ); + PopulateContactArrayL( listArray, tempArray, aContactId ); + MCAStoredContact* contact = NULL; + MCAStoredContact* watchedContact = NULL; + TInt count( tempArray.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + contact = tempArray[ a ]; + TBool updated( EFalse ); + aOldOnlineStatus = contact->OnlineStatus(); + if ( aOldOnlineStatus != aStatus ) + { + contact->SetOnlineStatus( aStatus ); + updated = ETrue; + } + if ( KErrNone != aAlias.Compare( contact->Alias() ) ) + { + contact->SetAliasL( aAlias ); + updated = ETrue; + } + contact->SetStatusTextL( aStatusText ); + contact->SetClientType( aType ); + if ( updated ) + { + // contacts online state was updated, resort the contact + listArray[ a ]->ResortContact( contact ); + contact->SignalChanges(); + watchedContact = contact; + } + } + CleanupStack::PopAndDestroy( 2 ); // listArray, tempArray + return watchedContact; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::PopulateContactArray +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::PopulateContactArrayL( + RPointerArray< MCAContactList >& aListArray, + RPointerArray< MCAStoredContact >& aContactArray, const TDesC& aContactId ) + { + TInt count( iContactList.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAStoredContact* contact = + iContactList[ a ]->FindContact( aContactId ); + if ( contact ) + { + // also populate lists of lists + aListArray.AppendL( iContactList[ a ] ); + aContactArray.AppendL( contact ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::Identification +// ----------------------------------------------------------------------------- +// +const TPtrC CCAStorageManager::Identification( const TDesC& aContactId ) + { + if ( aContactId.Length() == 0 ) + { + TPtrC retVal( KNullDesC ); + return retVal; + } + + // search from contact lists + MCAStoredContact* contact = FindAnyContact( aContactId ); + if ( contact ) + { + return contact->Identification(); + } + else + { + // could not find contact from contact lists, + // check if it's my own id + if ( 0 == CAUtils::NeutralCompare( aContactId, iOwnStatus->UserId() ) ) + { + return iOwnStatus->Identification(); + } + } + return CAUtils::DisplayId( aContactId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::OwnStatus +// ----------------------------------------------------------------------------- +// +MCAStoredContact& CCAStorageManager::OwnStatus() + { + return *iOwnStatus; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetContactListLock +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetContactListLock( TBool aLocked ) + { + TBool notify( !aLocked && iContactListLock ); + iContactListLock = aLocked; + if ( notify ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventMultipleChanges, + NULL, + KNullDesC ); + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactListInterna +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::ResetContactLists() + { + TInt count( ListCount() ); + TBool collapsed( count == 1 ? EFalse : ETrue ); + + for ( TInt a( 0 ); a < count; ++a ) + { + ListAt( a ).SetCollapsed( collapsed ); + } + if ( count ) + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventMultipleChanges, + NULL, KNullDesC ); + } + + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactListInternal +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetContactListProperty( TContactListProperty aProperty ) + { + TBool primaryInUse( aProperty == EPrimaryCollapseInUse ); + + TInt count( iContactList.Count() ); + switch ( aProperty ) + { + case EPrimaryCollapseInUse: + case ESecondaryCollapseInUse: + { + for ( TInt a( 0 ); a < count; ++a ) + { + iContactList[ a ]->SetPrimaryInuse( primaryInUse ); + } + break; + } + default: + { + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::InitSynchroniseProcess +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::InitSynchroniseProcess() + { + // Set all failed to NotDone + TInt count = iContactList.Count(); + for ( TInt a = count - 1; a >= 0; --a ) + { + if ( iContactList[ a ]->Synchronised() == MCAContactList::ESynchroniseFailed ) + { + iContactList[ a ]->SetSynchronised( MCAContactList::ESynchroniseNotDone ); + } + } + return iCurrentListSync = FindNextForSynch( 0 ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::InitSynchroniseProcess +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::SetNextForSynchroniseProcess() + { + return iCurrentListSync = FindNextForSynch( iCurrentListSync ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::IsAllSynchronised +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::IsAllSynchronised( TBool &aIsFailed ) const + { + TInt count = iContactList.Count(); + aIsFailed = EFalse; + TBool isSync = ETrue; + for ( TInt a = count - 1; a >= 0; --a ) + { + MCAContactList::TSynchroniseState syncState = iContactList[ a ]->Synchronised(); + if ( syncState == MCAContactList::ESynchroniseNotDone ) + { + isSync = EFalse; + } + else if ( syncState == MCAContactList::ESynchroniseFailed ) + { + aIsFailed = ETrue; + } + } + return isSync; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::ListInSyncProcessL +// ----------------------------------------------------------------------------- +// +MCAContactList& CCAStorageManager::ListInSyncProcessL() + { + __CHAT_ASSERT_DEBUG( iCurrentListSync < iContactList.Count() ); + User::LeaveIfError( iCurrentListSync ); + return *iContactList[ iCurrentListSync ]; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactListInternal +// ----------------------------------------------------------------------------- +// +CCAContactList* CCAStorageManager::FindContactListInternal( + const TDesC& aListId ) + { + CHAT_DP_FUNC_ENTER( "CCAStorageManager::FindContact" ); + TInt contactListIndex( FindContactListById( aListId ) ); + return ( contactListIndex >= 0 ? iContactList[ contactListIndex ] : NULL ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactList +// ----------------------------------------------------------------------------- +// +MCAContactList* CCAStorageManager::FindContactList( const TDesC& aListId ) + { + return FindContactListInternal( aListId ); + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactListById +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::FindContactListById( + const TDesC& aListId ) + { + TInt count( iContactList.Count() ); + for ( TInt x ( 0 ) ; x < count ; ++x ) + { + if ( KErrNone == CAUtils::NeutralCompare( + aListId, + iContactList[ x ]->ListId(), EFalse ) + ) + { + return x; + } + } + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CCAStorageManager::FindContactListById +// ----------------------------------------------------------------------------- +// +TInt CCAStorageManager::FindNextForSynch( TInt aOffset ) + { + TInt offset( aOffset == KErrNotFound ? 0 : aOffset ); + TInt count = iContactList.Count(); + TInt currentListSync = KErrNotFound; + while ( currentListSync == KErrNotFound && offset < count ) + { + if ( iContactList[ offset ]->Synchronised() == MCAContactList::ESynchroniseNotDone ) + { + currentListSync = offset; + } + ++offset; + } + return currentListSync; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::IsValidContact +// ----------------------------------------------------------------------------- +// +TBool CCAStorageManager::IsContactValid( const MCAStoredContact* aContact ) const + { + // own status + if ( aContact == iOwnStatus ) + { + // valid + return ETrue; + } + + // search lists + TInt count = iContactList.Count(); + for ( TInt i = 0; i < count; ++i ) + { + if ( iContactList[ i ]->FindIndexOfContact( aContact ) != KErrNotFound ) + { + // contact found -> valid + return ETrue; + } + } + + // contact not found + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CCAStorageManager::SortContactLists +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SortContactLists() + { + SendObserverEvent( TStorageManagerGlobals::EStorageEventPreChange, + NULL, KNullDesC ); + + TLinearOrder< CCAContactList > order( + CCAStorageManager::ContactListOrderByDisplayName ); + + iContactList.Sort( order ); + + SendObserverEvent( TStorageManagerGlobals::EStorageEventMultipleChanges, + NULL, KNullDesC ); + } +// ----------------------------------------------------------------------------- +// CCAStorageManager::IsGroupDeleted +// ----------------------------------------------------------------------------- +// + +TBool CCAStorageManager::IsGroupDeleted() + { + return iGroupDeleted; + } +// ----------------------------------------------------------------------------- +// CCAStorageManager::SetGroupDeleted +// ----------------------------------------------------------------------------- +// +void CCAStorageManager::SetGroupDeleted( TBool aValue ) + { + iGroupDeleted = aValue; + } +// End of File