diff -r 000000000000 -r 094583676ce7 PECengine/ListLibrary2/ContactListSrc/CPEngContactListModBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PECengine/ListLibrary2/ContactListSrc/CPEngContactListModBase.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1328 @@ +/* +* Copyright (c) 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: Contact list model implementation +* +*/ + +// INCLUDE FILES +#include "CPEngContactListModBase.h" + +#include "CPEngContactListModItemContainer.h" +#include "CPEngContactListModChangeMonitor.h" +#include "CPEngContactListSettings.h" +#include "MPEngContactListSettingsManager.h" +#include "MPEngAttributeList2.h" +#include "MPEngStorageManager.h" +#include "PEngListLibraryPanics.h" +#include "PEngContactIdsTools.h" +#include "PresenceDebugPrint.h" + +#include +#include + + + +// CONSTANTS + +// 1001 - initial version +// 1002 - store of the delta and monitor have now length of wv IDs, +static const TInt KListStoreVersion = 1002; + + +// Minimal size of the store entry for contact list model +// count of permanent,cached, and 2 change monitor arrays +static const TInt KListStoreMinSize = 16; + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::CPEngContactListModBase() +// ----------------------------------------------------------------------------- +// +CPEngContactListModBase::CPEngContactListModBase( + CPEngContactListSettings& aListSettings, + MPEngContactListSettingsManager& aCntLstSettingsManager ) + : CPEngStoreEntry( StoreTypeForListType( aListSettings.BaseSettings().iContactListType ) ), + iAccessCount( 1 ), // set initial access count to 1 + iSettings( &aListSettings ), + iCntLstSettingsManager ( aCntLstSettingsManager ) + { + iSize = KListStoreMinSize; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ConstructL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ConstructL( MPEngStorageManager& aStorageManager ) + { + iStorageId = iSettings->Name().AllocL(); + iStorageId->Des().Fold(); + BaseConstructL( aStorageManager ); // CSI: 9 # + + iChangesMonitor = CPEngContactListModChangeMonitor::NewL( *this ); + + iStorageManager->RetrieveL( *this ); + + iCntLstSettingsManager.AddContactListSettingsObserverL( this ); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::NewL() +// ----------------------------------------------------------------------------- +// +CPEngContactListModBase* CPEngContactListModBase::NewL( + CPEngContactListSettings& aListSettings, + MPEngStorageManager& aStorageManager, + MPEngContactListSettingsManager& aCntLstSettingsManager ) + { + CPEngContactListModBase* self = NewLC( aListSettings, + aStorageManager, + aCntLstSettingsManager ); + + CleanupStack::Pop(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::NewL() +// ----------------------------------------------------------------------------- +// +CPEngContactListModBase* CPEngContactListModBase::NewLC( + CPEngContactListSettings& aListSettings, + MPEngStorageManager& aStorageManager, + MPEngContactListSettingsManager& aCntLstSettingsManager ) + { + PENG_DP( D_PENG_LIT( "CPEngContactListModBase::NewLC() - %S" ), + &aListSettings.Name() ) ; + + CPEngContactListModBase* self = new ( ELeave ) + CPEngContactListModBase( aListSettings, + aCntLstSettingsManager ); + + CleanupClosePushL( *self ); + self->ConstructL( aStorageManager ); + + return self; + } + + +// Destructor +CPEngContactListModBase::~CPEngContactListModBase() + { + PENG_DP( D_PENG_LIT( "CPEngContactListModBase::~CPEngContactListModBase" ) ) ; + + // panic if object is still accessed + __ASSERT_DEBUG( iAccessCount == 0 , Panic( ERefAccessedObjectDeleted ) ); + + + iCntLstSettingsManager.RemoveContactListSettingsObserver( this ); + iCntLstSettingsManager.RemoveModel( this ); + + ResetLocalView(); + ResetNetworkView(); + + iServerOrder.Reset(); + + delete iChangesMonitor; + delete iStorageId; + } + + + +// ============================================================================= +// ===============Functions of MPEngContactListAdvance class =================== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ContactItemAdvance() +// ----------------------------------------------------------------------------- +// +MPEngContactItemAdvance& CPEngContactListModBase::ContactItemAdvance( + TInt aIndex, + TPEngContactListView aView ) + { + switch ( aView ) + { + case EPEngCntListLocalView: + { + return *( iLocalView[ aIndex ] ); + } + + case EPEngCntListNetworkView: + { + return *( iNetworkView[ aIndex ] ); + } + + default: + { + Panic( EWrongViewId ); + return *( iNetworkView[ aIndex ] ); + } + } + } + + + +// ============================================================================= +// ===============Functions of MPEngContactList2 class ========================= +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::AddContactL() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::AddContactL( const TDesC& aContact, + const TDesC& aNickName ) + { + PENG_DP( D_PENG_LIT( "CPEngContactListModBase::AddIdL: %S, : %S" ), + &this->StorageId(), &aContact ); + + LeaveIfListUpdateInProgressL(); + iChangesMonitor->Reset(); + + // Check if contact exists in the local list view + TInt pos( KErrNotFound ); + if ( KErrNotFound != DoFindContact( iLocalView, aContact, pos ) ) + { + // Contact already exists, leave + User::Leave( KErrAlreadyExists ); + } + + // does contact exists in the network view + TInt index ( DoFindContact( iNetworkView, aContact ) ); + if ( index != KErrNotFound ) + { + // contact already exist on the network, it was probably removed + // and now it is added, update nick name and reference + iNetworkView[ index ]->UpdateNickNameL( aNickName ); + iLocalView.InsertL( iNetworkView[ index ], pos ); + iLocalView[ pos ]->Open( CPEngContactListModItemContainer::ELocalRef ); + } + + else + { + // Contact does not exist in any view, add it to the local one + CPEngContactListModItemContainer* contact = + CPEngContactListModItemContainer::NewNewNickLC( *this, + aContact, + aNickName ); + + contact->SetFreshContact( ETrue ); + iLocalView.InsertL( contact, pos ); + iLocalView[ pos ]->Open( CPEngContactListModItemContainer::ELocalRef ); + CleanupStack::PopAndDestroy(); // contact + } + + + StoreContactListL(); + return pos; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RemoveContactL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RemoveContactL( const TDesC& aContact ) + { + PENG_DP( D_PENG_LIT( "CPEngContactListModBase::RemoveIdL - %S : %S " ), + &this->StorageId(), &aContact ); + + LeaveIfListUpdateInProgressL(); + iChangesMonitor->Reset(); + + // does contact exist in the local view? + TInt pos( DoFindContact( iLocalView, aContact ) ); + if ( pos == KErrNotFound ) + { + // nothing to delete + return; + } + + + iLocalView[ pos ]->CloseRef( CPEngContactListModItemContainer::ELocalRef ); + iLocalView.Remove( pos ); + + StoreContactListL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::FindContact() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::FindContact( const TDesC& aContact, + TPEngContactListView aView ) const + { + switch ( aView ) + { + case EPEngCntListLocalView: + { + return DoFindContact( iLocalView, aContact ); + } + + case EPEngCntListNetworkView: + { + return DoFindContact( iNetworkView, aContact ); + } + + case EPEngAddedContacts: + { + const TDesC& domain = iCntLstSettingsManager.UserDomain(); + return iChangesMonitor->FindContactIdInAdded( aContact, domain ); + } + + case EPEngRemovedContacts: + { + const TDesC& domain = iCntLstSettingsManager.UserDomain(); + return iChangesMonitor->FindContactIdInRemoved( aContact, domain ); + } + + default: + { + Panic( EWrongViewId ); + return KErrNotFound; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::Count() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::Count( TPEngContactListView aView ) const + { + switch ( aView ) + { + case EPEngCntListLocalView: + { + return iLocalView.Count(); + } + + case EPEngCntListNetworkView: + { + return iNetworkView.Count(); + } + + case EPEngAddedContacts: + { + return iChangesMonitor->CountAddedContactIds(); + } + + case EPEngRemovedContacts: + { + return iChangesMonitor->CountRemovedContactIds(); + } + + default: + { + Panic( EWrongViewId ); + return 0; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ContactItem() +// ----------------------------------------------------------------------------- +// +MPEngContactItem& CPEngContactListModBase::ContactItem( TInt aIndex, + TPEngContactListView aView ) + { + return ContactItemAdvance( aIndex, aView ); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ContactItem() +// ----------------------------------------------------------------------------- +// +const MPEngContactItem& CPEngContactListModBase::ContactItem( + TInt aIndex, + TPEngContactListView aView ) const + { + switch ( aView ) + { + case EPEngCntListLocalView: + { + return *( iLocalView[ aIndex ] ); + } + + case EPEngCntListNetworkView: + { + return *( iNetworkView[ aIndex ] ); + } + + default: + { + Panic( EWrongViewId ); + return *( iNetworkView[ aIndex ] ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RemovedContacts() +// ----------------------------------------------------------------------------- +// +const MDesCArray& CPEngContactListModBase::RemovedContacts( ) const + { + return iChangesMonitor->RemovedContactIds(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::AddedContacts() +// ----------------------------------------------------------------------------- +// +const MDesCArray& CPEngContactListModBase::AddedContacts( ) const + { + return iChangesMonitor->AddedContactIds(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ListProperties() +// ----------------------------------------------------------------------------- +// +MPEngContactListProperties& CPEngContactListModBase::ListProperties() + { + return *iSettings; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RemoveAllContactIdsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RemoveAllContactsL() + { + // reset local view and leave only network view + ResetLocalView(); + StoreContactListL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::SuspendUpdateNotification() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::SuspendUpdateNotification() + { + BufferServerSideNotifications(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ReleaseUpdateNotification() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ReleaseUpdateNotification() + { + ReleaseServerSideBuffering(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RollBackAllChangesL() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::RollBackAllChangesL() + { + LeaveIfListUpdateInProgressL(); + + RollbackL(); + + return KErrNone; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::UpdateInProgress() +// ----------------------------------------------------------------------------- +// +TBool CPEngContactListModBase::UpdateInProgress() const + { + return iStorageManager->Locked( *this, EStorageLockLevelHigh ); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::UpdateInProgress() +// ----------------------------------------------------------------------------- +// +TBool CPEngContactListModBase::UpdateRequired() const + { + TInt countLoc( iLocalView.Count() ); + TInt countNet( iNetworkView.Count() ); + if ( countLoc != countNet ) + { + return ETrue; + } + for ( TInt x( 0 ) ; x < countLoc ; ++x ) + { + if ( ( KErrNotFound == iNetworkView.Find( iLocalView[ x ] ) ) + || + ( iLocalView[ x ]->NewNick() ) + ) + { + return ETrue; + } + } + for ( TInt i( 0 ) ; i < countNet ; ++i ) + { + if ( KErrNotFound == iLocalView.Find( iNetworkView[ i ] ) ) + { + return ETrue; + } + } + return EFalse; + } + + + +// ============================================================================= +// ===============Functions of CPEngStoreEntry class =========================== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ExternalizeL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ExternalizeL( RWriteStream& aStream, + TPEngStorageType aStorageType ) const + { + // what is the type of the list, if it is not mixed store all at once + if ( EPEngMixedCachedVersionCon == StorageType() ) + { + // whole list is cached, store it all + ExternalizeContactsL( aStream, EPEngStorageBasicPermanent ); + ExternalizeContactsL( aStream, EPEngStorageBasicCached ); + iChangesMonitor->ExternalizeArrayL( aStream ); + return; + } + + + // write asked part + switch ( aStorageType ) + { + case EPEngStorageBasicPermanent: + { + // first write version of the storage + aStream.WriteInt32L( KListStoreVersion ); + + // store permanent part of the contact list + ExternalizeContactsL( aStream, aStorageType ); + break; + }; + + + case EPEngStorageBasicCached: + { + // store cached part of the contact list + ExternalizeContactsL( aStream, aStorageType ); + iChangesMonitor->ExternalizeArrayL( aStream ); + break; + } + + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::InternalizeL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::InternalizeL( RReadStream& aStream, + TPEngStorageType aStorageType ) + { + // what is the type of the list, if it is not mixed read all at once + if ( EPEngMixedCachedVersionCon == StorageType() ) + { + // whole list is cached, retrieve it once + Reset(); + InternalizePermanentContactsL( aStream ); + InternalizeCachedContactsL( aStream ); + iChangesMonitor->InternalizeArrayL( aStream ); + return; + } + + + // read offered part + switch ( aStorageType ) + { + case EPEngStorageBasicPermanent: + { + // read permanent part of the contact list + // fist check version + Reset(); + if ( KListStoreVersion != aStream.ReadInt32L() ) + { + // Version is wrong, remove file from store and reset + iStorageManager->Delete( *this ); + return; + } + + // now internalize all permanent parts + InternalizePermanentContactsL( aStream ); + break; + } + + + case EPEngStorageBasicCached: + { + // read cached part of the contact list + InternalizeCachedContactsL( aStream ); + iChangesMonitor->InternalizeArrayL( aStream ); + break; + } + + + default: + { + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::StorageId() +// ----------------------------------------------------------------------------- +// +const TDesC& CPEngContactListModBase::StorageId() const + { + return *iStorageId; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::EntrySize() +// ----------------------------------------------------------------------------- +// +TUint32 CPEngContactListModBase::EntrySize() const + { + return iSize; + } + + + +// ============================================================================= +// ===============Functions of MPEngSIDChangeObserver ========================== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::HandleSIDsChangeL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::HandleSIDsChangeL( CPtrCArray& /* aChangedSIDs */ ) + { + TInt err( iStorageManager->RetrieveL( *this ) ); + if ( err == KErrNotFound ) + { + Reset(); + return; + } + + if ( err != KErrNone ) + { + iStorageManager->Delete( *this ); + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::HandleSIDNotifyError() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::HandleSIDNotifyError( TInt /* aError */ ) + { + Reset(); + } + + + +// ============================================================================= +// ===============Functions of MPEngContactListModStore ======================== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::StoreSizeCount() +// ----------------------------------------------------------------------------- +// +TInt& CPEngContactListModBase::StoreSizeCount() + { + return iSize; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::StoreEntryL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::StoreEntryL() + { + StoreL(); + } + + + + +// ============================================================================= +// ===============Functions of MPEngContactListSettingsObserver class ========== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RefreshSettingsReference() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RefreshSettingsReference() + { + iSettings = iCntLstSettingsManager.ContactListSettingsOrNull( StorageId() ); + } + + + +// ============================================================================= +// ===============Functions of main class ====================================== +// ============================================================================= + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::StoreTypeForListType() +// ----------------------------------------------------------------------------- +// +TPEngStorageType CPEngContactListModBase::StoreTypeForListType( + TPEngContactListType aListType ) + { + return ( aListType == EPEngCachedContactList ) ? EPEngMixedCachedVersionCon : + EPEngMixedPermanentCachedVersionCon; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::Open() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::Open() + { + iAccessCount++; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::Close() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::Close() + { + iAccessCount--; + + if ( iAccessCount == 0 ) + { + delete this; + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::StoreContactListL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::StoreContactListL() + { + TRAPD( err, iStorageManager->StoreL( *this ) ) ; + if ( err != KErrNone ) + { + if ( err == KErrDiskFull ) + { + if ( KErrNotFound == iStorageManager->RetrieveL( *this ) ) + { + Reset(); + } + } + + User::Leave( err ); + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::FillAddNickListL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::FillAddNickListL( + RPointerArray& aAddNickList ) + { + TInt count( iLocalView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + if ( ( KErrNotFound == iNetworkView.Find( iLocalView[ x ] ) ) || + ( iLocalView[ x ]->NewNick() ) ) + { + aAddNickList.AppendL( iLocalView[ x ] ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::FillRemoveNickListL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::FillRemoveNickListL( + RPointerArray& aRemoveNickList ) + { + TInt count( iNetworkView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + if ( KErrNotFound == iLocalView.Find( iNetworkView[ x ] ) ) + { + aRemoveNickList.AppendL( iNetworkView[ x ] ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::CommitAddContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::CommitAddContactsL() + { + TInt count( iLocalView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + iLocalView[ x ]->CommitNickName(); + iLocalView[ x ]->SetFreshContact( EFalse ); + + if ( KErrNotFound == iNetworkView.Find( iLocalView[ x ] ) ) + { + TInt pos( KErrNotFound ); + CPEngContactListModItemContainer* cnt = iLocalView[ x ]; + DoFindContact( iNetworkView, cnt->Id(), pos ); + + iNetworkView.InsertL( cnt, pos ); + cnt->Open( CPEngContactListModItemContainer::ENetworkRef ); // CSI: 65 # + + // no order, add to the end + cnt->SetServerIndex( iServerOrder.Count() ); + iServerOrder.AppendL( cnt ); + + // add contact also to the added + iChangesMonitor->InsertAddedContactIdL( cnt->Id() ); + } + } + + StoreL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::CommitRemoveContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::CommitRemoveContactsL() + { + for ( TInt x( iNetworkView.Count() - 1 ) ; x >= 0 ; --x ) + { + if ( KErrNotFound == iLocalView.Find( iNetworkView[ x ] ) ) + { + CPEngContactListModItemContainer* contact = iNetworkView[ x ]; + + // cache the index that's being removed + TInt serverIndex = contact->ServerIndex(); + + // add contact also to the removed + iChangesMonitor->InsertRemovedContactIdL( contact->Id() ); + + // remove from the network ordered + // let it panic, if not found + // arrays should be always in sync + iServerOrder.Remove( iServerOrder.Find( contact ) ); + + contact->CloseRef( CPEngContactListModItemContainer::ENetworkRef ); + + iNetworkView.Remove( x ); + + // and reorganize iNetworkView's server indexes + ReorganizeServerIndexOrder( serverIndex ); + } + } + + StoreL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RollbackL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RollbackL() + { + // reset local list and add there items from the network one + ResetLocalView(); + + TInt count( iNetworkView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + iLocalView.AppendL( iNetworkView[ x ] ); + iNetworkView[ x ]->Open( CPEngContactListModItemContainer::ELocalRef ); + iNetworkView[ x ]->RollBackNickname(); + } + + StoreContactListL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::FindContactInAll() +// ----------------------------------------------------------------------------- +// +CPEngContactListModItemContainer* CPEngContactListModBase::FindContactInAll( + const TDesC& aContact ) + { + TInt index ( DoFindContact( iLocalView, aContact ) ); + if ( index != KErrNotFound ) + { + return iLocalView[ index ]; + } + + index = DoFindContact( iNetworkView, aContact ); + if ( index != KErrNotFound ) + { + return iNetworkView[ index ]; + } + + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ContactExistsOnServer() +// ----------------------------------------------------------------------------- +// +TBool CPEngContactListModBase::ContactExistsOnServer( + CPEngContactListModItemContainer& aContact ) + { + return aContact.RefActive( CPEngContactListModItemContainer::ENetworkRef ); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::AdoptNewContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::AdoptNewContactsL( + RPointerArray& aContacts ) + { + ResetLocalView(); + ResetNetworkView(); + + TInt count = aContacts.Count(); + for ( TInt ii( 0 ) ; ii < count ; ++ii ) + { + // take always first in array + CPEngContactListModItemContainer* cnt = aContacts[ 0 ]; + iLocalView.AppendL( cnt ); + cnt->Open( CPEngContactListModItemContainer::ELocalRef ); // CSI: 65 # + iNetworkView.AppendL( cnt ); + cnt->Open( CPEngContactListModItemContainer::ENetworkRef ); // CSI: 65 # + iServerOrder.AppendL( NULL ); + aContacts.Remove( 0 ); + cnt->Close(); + } + + + RestoreServerOrderedArray(); + StoreL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::AdoptNetworkViewL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::AdoptNetworkViewL( + RPointerArray& aContacts ) + { + ResetNetworkView(); + + TInt count( aContacts.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + // take always first in array + CPEngContactListModItemContainer* cnt = aContacts[ 0 ]; + iNetworkView.AppendL( cnt ); + cnt->Open( CPEngContactListModItemContainer::ENetworkRef ); // CSI: 65 # + iServerOrder.AppendL( NULL ); + aContacts.Remove( 0 ); + cnt->Close(); + } + + RestoreServerOrderedArray(); + StoreL(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RemoveBadContactL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RemoveBadContactL( const TDesC& aContact ) + { + iChangesMonitor->InsertRemovedContactIdL( aContact ); + iChangesMonitor->RemoveAddedContactId( aContact ); + + CPEngContactListModItemContainer* cnt = FindContactInAll( aContact ); + + + if ( cnt && cnt->RefActive( CPEngContactListModItemContainer::ENetworkRef ) ) + { + TInt serverIndex = cnt->ServerIndex(); + + iNetworkView.Remove( iNetworkView.Find( cnt ) ); + cnt = cnt->CloseRef( CPEngContactListModItemContainer::ENetworkRef ); + iServerOrder.Remove( iServerOrder.Find( cnt ) ); + + // and reorganize iNetworkView's server indexes + ReorganizeServerIndexOrder( serverIndex ); + } + + + if ( cnt && cnt->RefActive( CPEngContactListModItemContainer::ELocalRef ) ) + { + iLocalView.Remove( iLocalView.Find( cnt ) ); + cnt->CloseRef( CPEngContactListModItemContainer::ELocalRef ); + } + + StoreL(); + } + + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::Reset() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::Reset() + { + ResetLocalView(); + ResetNetworkView(); + iChangesMonitor->Reset(); + + iSize = KListStoreMinSize; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ResetLocalView() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ResetLocalView() + { + TInt count( iLocalView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + iLocalView[ x ]->CloseRef( CPEngContactListModItemContainer::ELocalRef ); + } + + iLocalView.Reset(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ResetNetworkView() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ResetNetworkView() + { + TInt count( iNetworkView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + iNetworkView[ x ]->CloseRef( CPEngContactListModItemContainer::ENetworkRef ); + } + + iNetworkView.Reset(); + iServerOrder.Reset(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::LeaveIfListUpdateInProgressL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::LeaveIfListUpdateInProgressL() const + { + if ( UpdateInProgress() ) + { + User::Leave( KErrInUse ); + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ChangeMonitor() +// ----------------------------------------------------------------------------- +// +CPEngContactListModChangeMonitor& CPEngContactListModBase::ChangeMonitor() + { + return *iChangesMonitor; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::Settings() +// ----------------------------------------------------------------------------- +// +CPEngContactListSettings& CPEngContactListModBase::Settings() + { + return *iSettings; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ServerOrderedContacts() +// ----------------------------------------------------------------------------- +// +const RPointerArray& +CPEngContactListModBase::ServerOrderedContacts() const + { + return iServerOrder; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::DoFindContact() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::DoFindContact( + const RPointerArray& aArray, + const TDesC& aContact, + TInt& aIndex, + TBool aFirstPrefered /* EFalse */ ) const + { + const TDesC& domain = iCntLstSettingsManager.UserDomain(); + TInt high( aArray.Count() ); + + + if ( !high || + ( aFirstPrefered && 0 > NContactIdsTools::CompareContactIds( aContact, + aArray[ 0 ]->Id(), + domain ) ) ) + { + aIndex = 0; + return KErrNotFound; + } + + + TInt low( 0 ); + TInt ret( KErrNotFound ); + while ( high > low ) + { + TInt inx = ( low + high ) >> 1; + TInt k ( NContactIdsTools::CompareContactIds( aContact, + aArray[ inx ]->Id(), + domain ) ); + if ( k == 0 ) + { + aIndex = inx; + return KErrNone; + } + else if ( k > 0 ) + low = inx + 1; + else + high = inx; + } + aIndex = high; + return ret; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::DoFindContact() +// ----------------------------------------------------------------------------- +// +TInt CPEngContactListModBase::DoFindContact( + const RPointerArray& aArray, + const TDesC& aContact ) const + { + TInt index( KErrNotFound ); + TInt err( DoFindContact( aArray, aContact, index ) ); + if ( err != KErrNotFound ) + { + return index; + } + + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ExternalizeContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ExternalizeContactsL( RWriteStream& aStream, + TPEngStorageType aStorageType ) const + { + TInt count( iLocalView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + aStream.WriteInt32L( KErrNone ); + iLocalView[ x ]->ExternalizeL( aStream, aStorageType ); + } + + count = iNetworkView.Count(); + for ( TInt y( 0 ) ; y < count ; ++y ) + { + if ( !iNetworkView[ y ]->RefActive( CPEngContactListModItemContainer::ELocalRef ) ) + { + aStream.WriteInt32L( KErrNone ); + iNetworkView[ y ]->ExternalizeL( aStream, aStorageType ); + } + } + + aStream.WriteInt32L( KErrNotFound ); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::InternalizePermanentContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::InternalizePermanentContactsL( RReadStream& aStream ) + { + CPEngContactListModItemContainer* contact = NULL; + + while ( KErrNone == aStream.ReadInt32L() ) + { + contact = CPEngContactListModItemContainer::NewLC( *this, aStream ); + + if ( contact->RefActive( CPEngContactListModItemContainer::ELocalRef ) ) + { + iLocalView.AppendL( contact ); + contact->Open( CPEngContactListModItemContainer::ELocalRef ); // CSI: 65 # + } + + if ( contact->RefActive( CPEngContactListModItemContainer::ENetworkRef ) ) + { + iNetworkView.AppendL( contact ); + contact->Open( CPEngContactListModItemContainer::ENetworkRef ); // CSI: 65 # + iServerOrder.AppendL( NULL ); + } + + CleanupStack::PopAndDestroy(); // contact + } + + RestoreServerOrderedArray(); + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::InternalizeCachedContactsL() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::InternalizeCachedContactsL( RReadStream& aStream ) + { + TInt count( iLocalView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + aStream.ReadInt32L(); // KErrNone + iLocalView[ x ]->InternalizeL( aStream, EPEngStorageBasicCached ); + } + + count = iNetworkView.Count(); + for ( TInt y( 0 ) ; y < count ; ++y ) + { + if ( ! iNetworkView[ y ]->RefActive( CPEngContactListModItemContainer::ELocalRef ) ) + { + aStream.ReadInt32L(); // KErrNone + iNetworkView[ y ]->InternalizeL( aStream, EPEngStorageBasicCached ); + } + } + + aStream.ReadInt32L(); // KErrNotFound + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::RestoreServerOrderedArray() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::RestoreServerOrderedArray() + { + TInt count( iNetworkView.Count() ); + for ( TInt x( 0 ) ; x < count ; ++x ) + { + CPEngContactListModItemContainer* contact = iNetworkView[ x ]; + __ASSERT_DEBUG( count > contact->ServerIndex() , Panic( ERefServerOrderedArrayNotFilled ) ); + iServerOrder[ contact->ServerIndex() ] = contact; + } + } + + +// ----------------------------------------------------------------------------- +// CPEngContactListModBase::ReorganizeServerIndexOrder() +// ----------------------------------------------------------------------------- +// +void CPEngContactListModBase::ReorganizeServerIndexOrder( TInt aIndex ) + { + TInt networkViewCount( iNetworkView.Count() ); + + for ( TInt ii( 0 ) ; ii < networkViewCount; ii++ ) + { + TInt srvIndex( iNetworkView[ii]->ServerIndex() ); + if ( srvIndex > aIndex ) + { + srvIndex--; + iNetworkView[ii]->SetServerIndex( srvIndex ); + } + } + } + + + +// End of File + + + + + + + + + + + + + + + + + +