phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindViewBase.cpp
changeset 0 e686773b3f54
--- /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