--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindViewBase.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,760 @@
+/*
+* Copyright (c) 2002-2007 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: Sim store filtered contact view implementation.
+*
+*/
+
+
+#include "CFindViewBase.h"
+
+#include "CRefineView.h"
+#include "CContactStore.h"
+#include "CContactLink.h"
+#include "CContactView.h"
+#include "CViewContact.h"
+
+// Virtual Phonebook
+#include <VPbkError.h>
+#include <MVPbkSimContact.h>
+#include <CVPbkSimContact.h>
+#include <CVPbkSimCntField.h>
+#include <MVPbkSimStoreOperation.h>
+#include <CVPbkAsyncCallback.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <CVPbkContactFieldIterator.h>
+#include <MVPbkContactNameConstructionPolicy.h>
+#include <MVPbkContactFindPolicy.h>
+#include <VPbkSendEventUtility.h>
+
+// System includes
+#include <cntviewbase.h>
+#include <featmgr.h>
+
+namespace VPbkSimStore {
+
+#ifdef _DEBUG
+enum TCFindViewBasePanicCode
+ {
+ EPreCond_SetFindStringsL = 1
+ };
+
+void Panic( TCFindViewBasePanicCode aPanicCode )
+ {
+ _LIT( KPanicText, "CFindViewBase" );
+ User::Panic( KPanicText, aPanicCode );
+ }
+#endif // _DEBUG
+
+const TInt KGranularity( 4 );
+
+// --------------------------------------------------------------------------
+// CFindViewBase::CFindViewBase
+// --------------------------------------------------------------------------
+//
+CFindViewBase::CFindViewBase( MParentViewForFiltering& aParentView,
+ CContactView& aAllContactsView,
+ TBool aOwnsMatchedContacts )
+ : iParentView( aParentView ),
+ iAllContactsView( aAllContactsView ),
+ iOwnsContacts( aOwnsMatchedContacts )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::BaseConstructL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::BaseConstructL(
+ MVPbkContactViewObserver& aExternalViewObserver,
+ const MDesCArray& aFindStrings,
+ MVPbkContactFindPolicy& aFindPolicy )
+ {
+ iObserverOp =
+ CVPbkAsyncObjectOperation<MVPbkContactViewObserver>::NewL();
+ iFilterObsOp =
+ CVPbkAsyncObjectOperation<MFilteredViewSupportObserver>::NewL();
+
+ // Copy find words
+ iFindStrings = new(ELeave)CDesCArrayFlat( KGranularity );
+ SetFindStringsL( aFindStrings );
+
+ iCurrentContact = CViewContact::NewL( iAllContactsView, SortOrder() );
+
+ // Assign contact find policy
+ iContactFindPolicy = &aFindPolicy;
+
+ //Create field type list
+ iFieldTypeRefsList = CVPbkFieldTypeRefsList::NewL();
+
+ // Append the observer who created the view. Events must be always send
+ // to this observer first.
+ iObservers.AppendL( &aExternalViewObserver );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::~CFindViewBase
+// --------------------------------------------------------------------------
+//
+CFindViewBase::~CFindViewBase()
+ {
+ delete iObserverOp;
+ delete iFilterObsOp;
+ iObservers.Close();
+ iFilteringObservers.Close();
+ ResetContacts();
+ delete iCurrentContact;
+ delete iFindStrings;
+ delete iFieldTypeRefsList;
+ iParentView.RemoveFilteringObserver( *this );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ActivateContactMatchL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ActivateContactMatchL()
+ {
+ // If used from update then we must renew the observing
+ iParentView.RemoveFilteringObserver( *this );
+ // Get the state of the parent view asynchrnounsly
+ iParentView.AddFilteringObserverL( *this );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ParentObject
+// --------------------------------------------------------------------------
+//
+MVPbkObjectHierarchy& CFindViewBase::ParentObject() const
+ {
+ return iParentView.ParentObject();
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::RefreshL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::RefreshL()
+ {
+ iParentView.RefreshL();
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactCountL
+// --------------------------------------------------------------------------
+//
+TInt CFindViewBase::ContactCountL() const
+ {
+ return iMatchedContacts.Count();
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactAtL
+// --------------------------------------------------------------------------
+//
+const MVPbkViewContact& CFindViewBase::ContactAtL(
+ TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0,
+ VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
+ if ( aIndex >= iMatchedContacts.Count() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ iCurrentContact->SetSimContactL( *iMatchedContacts[ aIndex ] );
+ return *iCurrentContact;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::CreateLinkLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactLink* CFindViewBase::CreateLinkLC(
+ TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0,
+ VPbkError::Panic(VPbkError::EInvalidContactIndex) );
+ if ( aIndex >= iMatchedContacts.Count() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt simIndex = iMatchedContacts[aIndex]->SimIndex();
+ return CContactLink::NewLC( iAllContactsView.Store(), simIndex );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::IndexOfLinkL
+// --------------------------------------------------------------------------
+//
+TInt CFindViewBase::IndexOfLinkL(
+ const MVPbkContactLink& aContactLink ) const
+ {
+ if ( &aContactLink.ContactStore() == &iAllContactsView.Store() )
+ {
+ TInt simIndex =
+ static_cast<const CContactLink&>( aContactLink ).SimIndex();
+
+ const TInt count( iMatchedContacts.Count() );
+ for ( TInt i(0); i < count; ++i )
+ {
+ if ( iMatchedContacts[i]->SimIndex() == simIndex )
+ {
+ return i;
+ }
+ }
+ }
+ return KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::Type
+// --------------------------------------------------------------------------
+//
+TVPbkContactViewType CFindViewBase::Type() const
+ {
+ return iParentView.Type();
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ChangeSortOrderL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ChangeSortOrderL(
+ const MVPbkFieldTypeList& aSortOrder )
+ {
+ iParentView.ChangeSortOrderL( aSortOrder );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::SortOrder
+// --------------------------------------------------------------------------
+//
+const MVPbkFieldTypeList& CFindViewBase::SortOrder() const
+ {
+ return iParentView.SortOrder();
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::AddObserverL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::AddObserverL(
+ MVPbkContactViewObserver& aObserver )
+ {
+ CVPbkAsyncObjectCallback<MVPbkContactViewObserver>* callback =
+ VPbkEngUtils::CreateAsyncObjectCallbackLC(
+ *this,
+ &CFindViewBase::DoAddObserver,
+ &CFindViewBase::DoAddObserverError,
+ aObserver);
+ iObserverOp->CallbackL( callback );
+ CleanupStack::Pop( callback );
+
+ // Insert to first position because events are send in reverse order.
+ // Events must be send in the same order as the observers were added.
+ iObservers.InsertL( &aObserver, 0 );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::RemoveObserver
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::RemoveObserver(
+ MVPbkContactViewObserver& aObserver )
+ {
+ iObserverOp->CancelCallback( &aObserver );
+ const TInt index = iObservers.Find( &aObserver );
+ if ( index != KErrNotFound )
+ {
+ iObservers.Remove( index );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::MatchContactStore
+// --------------------------------------------------------------------------
+//
+TBool CFindViewBase::MatchContactStore(
+ const TDesC& aContactStoreUri ) const
+ {
+ return iParentView.MatchContactStore( aContactStoreUri );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::MatchContactStoreDomain
+// --------------------------------------------------------------------------
+//
+TBool CFindViewBase::MatchContactStoreDomain(
+ const TDesC& aContactStoreDomain ) const
+ {
+ return iParentView.MatchContactStoreDomain( aContactStoreDomain );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::CreateBookmarkLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactBookmark* CFindViewBase::CreateBookmarkLC(
+ TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0,
+ VPbkError::Panic(VPbkError::EInvalidContactIndex) );
+ if ( aIndex >= iMatchedContacts.Count() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt simIndex = iMatchedContacts[aIndex]->SimIndex();
+ return CContactLink::NewLC( iAllContactsView.Store(), simIndex );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::IndexOfBookmarkL
+// --------------------------------------------------------------------------
+//
+TInt CFindViewBase::IndexOfBookmarkL(
+ const MVPbkContactBookmark& aContactBookmark ) const
+ {
+ // Bookmark is implemented as a link in this store
+ const CContactLink* link =
+ dynamic_cast<const CContactLink*>( &aContactBookmark );
+ if ( link && ( &link->ContactStore() == &iAllContactsView.Store() ) )
+ {
+ TInt simIndex = link->SimIndex();
+
+ const TInt count( iMatchedContacts.Count() );
+ for ( TInt i(0); i < count; ++i )
+ {
+ if ( iMatchedContacts[i]->SimIndex() == simIndex )
+ {
+ return i;
+ }
+ }
+ }
+
+
+ return KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::AddFilteringObserverL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::AddFilteringObserverL(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ // Insert observer in callback function. That ensures that the observer
+ // will always get the event asynchronously.
+
+ CVPbkAsyncObjectCallback<MFilteredViewSupportObserver>* callback =
+ VPbkEngUtils::CreateAsyncObjectCallbackLC(
+ *this,
+ &CFindViewBase::DoAddFilteringObserverL,
+ &CFindViewBase::DoAddFilteringObserverError,
+ aObserver);
+
+ iFilterObsOp->CallbackL( callback );
+ CleanupStack::Pop( callback );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::RemoveFilteringObserver
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::RemoveFilteringObserver(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ iFilterObsOp->CancelCallback( &aObserver );
+ const TInt index( iFilteringObservers.Find( &aObserver ) );
+ if ( index != KErrNotFound )
+ {
+ iFilteringObservers.Remove( index );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ViewFiltering
+// --------------------------------------------------------------------------
+//
+MVPbkContactViewFiltering* CFindViewBase::ViewFiltering()
+ {
+ // Find view supports further filtering using CRefineView
+ return this;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::CreateFilteredViewLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactViewBase* CFindViewBase::CreateFilteredViewLC(
+ MVPbkContactViewObserver& aObserver,
+ const MDesCArray& aFindWords,
+ const MVPbkContactBookmarkCollection* /*aAlwaysIncludedContacts*/ )
+ {
+ // NOTE: aAlwaysIncludedContacts is commented because in VPbkSimStore
+ // filtered views are linked. CFindView->CRefineView->CRefineView etc.
+ // Only the CFindView saves the always included contacts and they
+ // are used also by all CRefineView instances through
+ // MAlwaysIncludedContacts interface.
+ CRefineView* refineView = CRefineView::NewLC( aFindWords, *this,
+ iAllContactsView, aObserver, *iContactFindPolicy, *this );
+ refineView->ActivateContactMatchL();
+ return refineView;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactViewUnavailable
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ContactViewUnavailable(
+ MVPbkContactViewBase& aView )
+ {
+ if ( &iParentView == &aView )
+ {
+ SendViewStateEventToObservers();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactAddedToView
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ContactAddedToView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex,
+ const MVPbkContactLink& aContactLink )
+ {
+ TRAPD( error, HandleContactAddedToViewL( aView, aIndex, aContactLink ) );
+ if ( error != KErrNone )
+ {
+ ContactViewError( aView, error, EFalse );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactRemovedFromView
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ContactRemovedFromView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex,
+ const MVPbkContactLink& aContactLink )
+ {
+ TRAPD( error, HandleContactRemovedFromViewL( aView, aIndex, aContactLink ) );
+ if ( error != KErrNone )
+ {
+ ContactViewError( aView, error, EFalse );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactViewError
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ContactViewError(
+ MVPbkContactViewBase& /*aView*/,
+ TInt aError,
+ TBool aErrorNotified )
+ {
+ // This function can be called from the parent view or from the subclass.
+ // In both cases this view is not usable anymore.
+ iViewReady = EFalse;
+ ResetContacts();
+
+ // Send first to external observers...
+ VPbkEng::SendEventToObservers( *this, aError, aErrorNotified, iObservers,
+ &MVPbkContactViewObserver::ContactViewError );
+ // ...then to internal. This ensures that events come first from lower
+ // level find view.
+ VPbkEng::SendEventToObservers( *this, aError, aErrorNotified,
+ iFilteringObservers, &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ContactViewUnavailableForFiltering
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ContactViewUnavailableForFiltering(
+ MParentViewForFiltering& aView )
+ {
+ if ( &iParentView == &aView )
+ {
+ iViewReady = EFalse;
+ ResetContacts();
+ // Send events first to filtered views that are built on this
+ // view so that they can update them selves before notifying
+ // any external observers.
+ // Parent view will call ContactViewUnvailable after this and then
+ // the external observers will get the view event too.
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MFilteredViewSupportObserver::ContactViewUnavailableForFiltering,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::MatchContactsL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::MatchContactsL()
+ {
+ // Destroy old matches
+ ResetContacts();
+ // Do the match
+ MatchL( iMatchedContacts );
+ iViewReady = ETrue;
+ // Send events to filtered views that are built on this
+ // view so that they can update them selves before notifying
+ // any external observers.
+ // It's subclass responsibility to call SendViewStateEventToObservers
+ // when external observers are allowed to get view event.
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MFilteredViewSupportObserver::ContactViewReadyForFiltering,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::IsMatchL
+// --------------------------------------------------------------------------
+//
+TBool CFindViewBase::IsMatchL( const MVPbkViewContact& aViewContact )
+ {
+ return iContactFindPolicy->MatchContactNameL( *iFindStrings,
+ aViewContact );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::FindStrings
+// --------------------------------------------------------------------------
+//
+const MDesCArray& CFindViewBase::FindStrings() const
+ {
+ return *iFindStrings;
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::SetFindStringsL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::SetFindStringsL( const MDesCArray& aFindStrings )
+ {
+ __ASSERT_DEBUG( iFindStrings, Panic( EPreCond_SetFindStringsL ) );
+
+ iFindStrings->Reset();
+ const TInt count( aFindStrings.MdcaCount() );
+ for ( TInt i(0); i < count; ++i )
+ {
+ iFindStrings->AppendL( aFindStrings.MdcaPoint( i ) );
+ }
+ }
+
+// -------------------------------------------------------------------------
+// CFindViewBase::SendViewStateEventToObservers
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::SendViewStateEventToObservers()
+ {
+ // Cancel any new AddObserverL callbacks to avoid duplicate event
+ // sending.
+ iObserverOp->Purge();
+
+ void (MVPbkContactViewObserver::*notifyFunc)(MVPbkContactViewBase&);
+ notifyFunc = &MVPbkContactViewObserver::ContactViewReady;
+
+ if ( !iViewReady )
+ {
+ notifyFunc = &MVPbkContactViewObserver::ContactViewUnavailable;
+ }
+
+ VPbkEng::SendViewEventToObservers( *this, iObservers,
+ notifyFunc, &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ notifyFunc, &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::DoAddObserver
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::DoAddObserver( MVPbkContactViewObserver& aObserver )
+ {
+ if (iViewReady)
+ {
+ // If this view is ready and there was no error,
+ // tell it to the observer
+ aObserver.ContactViewReady( *this );
+ }
+ else
+ {
+ aObserver.ContactViewUnavailable( *this );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::DoAddObserverError
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::DoAddObserverError(
+ MVPbkContactViewObserver& /*aObserver*/, TInt /*aError*/ )
+ {
+ // Empty implementation
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::DoAddFilteringObserverL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::DoAddFilteringObserverL(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ // Insert to first position because events are send in reverse order.
+ iFilteringObservers.InsertL( &aObserver, 0 );
+
+ if (iViewReady)
+ {
+ aObserver.ContactViewReadyForFiltering( *this );
+ aObserver.ContactViewReady( *this );
+ }
+ else
+ {
+ aObserver.ContactViewUnavailableForFiltering( *this );
+ aObserver.ContactViewUnavailable( *this );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::DoAddFilteringObserverError
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::DoAddFilteringObserverError(
+ MFilteredViewSupportObserver& aObserver, TInt aError )
+ {
+ aObserver.ContactViewError( *this, aError, EFalse );
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::HandleContactAddedToViewL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::HandleContactAddedToViewL( MVPbkContactViewBase& aView,
+ TInt aIndex, const MVPbkContactLink& aContactLink )
+ {
+ if ( &iParentView == &aView )
+ {
+ // Let sub class do the addition if needed
+ DoContactAddedToViewL( aView, aIndex, aContactLink,
+ iMatchedContacts );
+
+ // Get the index of the new contact in this view.
+ TInt index( IndexOfLinkL( aContactLink ) );
+ if ( index != KErrNotFound )
+ {
+ VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
+ iObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindViewBase::HandleContactRemovedFromViewL
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::HandleContactRemovedFromViewL(
+ MVPbkContactViewBase& aView, TInt /*aIndex*/, const
+ MVPbkContactLink& aContactLink )
+ {
+ if ( &iParentView == &aView )
+ {
+ // We know that link is always VPbkSimStore::CContactLink
+ const CContactLink& link =
+ static_cast<const CContactLink&>(aContactLink);
+
+ TInt index = KErrNotFound;
+ MVPbkSimContact* removedContact = NULL;
+ const TInt simIndex = link.SimIndex();
+ const TInt count( iMatchedContacts.Count() );
+ for ( TInt i= 0; i < count && !removedContact; ++i )
+ {
+ MVPbkSimContact* contact = iMatchedContacts[i];
+
+ // Filter away the removed contact
+ if ( contact->SimIndex() == simIndex )
+ {
+ // Remove contact from the array
+ iMatchedContacts.Remove( i );
+ // Save the removed index for the observers
+ index = i;
+ // At this point nobody owns removedContact.
+ removedContact = contact;
+ }
+ }
+ TBool takeCareOfOwnership = (removedContact && iOwnsContacts);
+
+ // Notice: we can not delete the contact instance before
+ // all observers have received the event. This is because
+ // in case of CRefineView, iMatchedContacts contains references
+ // to MVPbkSimContact instances. If we delete the contact
+ // before notifying observer then the there will be invalid
+ // pointer.
+ if ( takeCareOfOwnership )
+ {
+ CleanupDeletePushL( removedContact );
+ }
+
+ if ( index != KErrNotFound )
+ {
+ VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
+ iObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+ if ( takeCareOfOwnership)
+ {
+ // After all observers have received the Removed -event, it's
+ // safe to actually destroy the contact.
+ CleanupStack::PopAndDestroy(); // removedContact
+ }
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// CFindViewBase::ResetContacts
+// --------------------------------------------------------------------------
+//
+void CFindViewBase::ResetContacts()
+ {
+ if ( iOwnsContacts )
+ {
+ iMatchedContacts.ResetAndDestroy();
+ }
+ else
+ {
+ iMatchedContacts.Reset();
+ }
+ }
+} // namespace VPbkSimStore
+// End of File