--- /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 <e32std.h>
+#include <bamdesca.h>
+
+
+
+// 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<CPEngContactListModItemContainer>& 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<CPEngContactListModItemContainer>& 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<CPEngContactListModItemContainer>& 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<CPEngContactListModItemContainer>& 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<CPEngContactListModItemContainer>&
+CPEngContactListModBase::ServerOrderedContacts() const
+ {
+ return iServerOrder;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngContactListModBase::DoFindContact()
+// -----------------------------------------------------------------------------
+//
+TInt CPEngContactListModBase::DoFindContact(
+ const RPointerArray<CPEngContactListModItemContainer>& 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<CPEngContactListModItemContainer>& 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+