--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindView.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,490 @@
+/*
+* 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 "CFindView.h"
+
+// From VPbkSimStore
+#include "CContactStore.h"
+#include "CContactView.h"
+#include "CViewContact.h"
+#include "CContactLink.h"
+
+// VPbkEng
+#include <MVPbkSimStoreOperation.h>
+#include <MVPbkSimCntView.h>
+#include <CVPbkSimContact.h>
+#include <RVPbkStreamedIntArray.h>
+#include <MVPbkContactViewObserver.h>
+#include <MVPbkSimCntStore.h>
+#include <MVPbkContactLink.h>
+#include <CVPbkContactFindPolicy.h>
+#include <CVPbkContactNameConstructionPolicy.h>
+#include <CVPbkContactViewSortPolicy.h>
+#include <MVPbkContactBookmarkCollection.h>
+#include <RVPbkStreamedIntArray.h>
+
+// System includes
+#include <cntviewbase.h>
+#include <featmgr.h>
+
+// Debugging headers
+#include <VPbkProfile.h>
+#include <VPbkDebug.h>
+
+namespace VPbkSimStore {
+
+// --------------------------------------------------------------------------
+// CFindView::CFindView
+// --------------------------------------------------------------------------
+//
+inline CFindView::CFindView( CContactView& aAllContactsView ) :
+ CFindViewBase( aAllContactsView, aAllContactsView, ETrue )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::~CFindView
+// --------------------------------------------------------------------------
+//
+CFindView::~CFindView()
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING(
+ "VPbkSimStore:CFindView(%x)::~CFindView"), this );
+
+ delete iFindOperation;
+ delete iFindPolicy;
+ iAlwaysIncluded.Close();
+ iSIMMatchedContacts.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ConstructL
+// --------------------------------------------------------------------------
+//
+void CFindView::ConstructL( const MDesCArray& aFindStrings,
+ MVPbkContactViewObserver& aExternalViewObserver,
+ const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts,
+ RFs& aRFs )
+ {
+ CVPbkContactFindPolicy::TParam findPolicyParams(
+ iAllContactsView.Store().MasterFieldTypeList(), aRFs );
+ iFindPolicy = CVPbkContactFindPolicy::NewL( findPolicyParams );
+ BaseConstructL( aExternalViewObserver, aFindStrings,
+ *iFindPolicy );
+
+ SetAlwaysIncludedContactsL( aAlwaysIncludedContacts );
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::NewLC
+// --------------------------------------------------------------------------
+//
+CFindView* CFindView::NewLC(
+ const MDesCArray& aFindStrings,
+ CContactView& aAllContactsView,
+ MVPbkContactViewObserver& aExternalViewObserver,
+ const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts,
+ RFs& aRFs )
+ {
+ CFindView* self = new ( ELeave ) CFindView( aAllContactsView );
+ CleanupStack::PushL( self );
+ self->ConstructL( aFindStrings, aExternalViewObserver,
+ aAlwaysIncludedContacts, aRFs );
+ CleanupStack::Check( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::SetAlwaysIncludedContactsL
+// --------------------------------------------------------------------------
+//
+void CFindView::SetAlwaysIncludedContactsL(
+ const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts )
+ {
+ iAlwaysIncluded.Reset();
+
+ if ( aAlwaysIncludedContacts )
+ {
+ MVPbkContactStore& store = ParentObject().ContactStore();
+ const TInt count = aAlwaysIncludedContacts->Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ const CContactLink* bookmark =
+ dynamic_cast<const CContactLink*>(
+ &aAlwaysIncludedContacts->At( i ) );
+ // If bookmark was from VPbkCntModel and if it's from same store
+ // as this view then it's added to array.
+ if ( bookmark &&
+ &bookmark->ContactStore() == &store )
+ {
+ iAlwaysIncluded.AppendL( bookmark->SimIndex() );
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ContactViewReady
+// --------------------------------------------------------------------------
+//
+void CFindView::ContactViewReady( MVPbkContactViewBase& /*aView*/ )
+ {
+ // CFindView is only interested in ContactViewReadyForFiltering that
+ // will start an asynchronous native match.
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ContactViewReadyForFiltering
+// --------------------------------------------------------------------------
+//
+void CFindView::ContactViewReadyForFiltering(
+ MParentViewForFiltering& aView )
+ {
+ // Cancel existing match if aready active.
+ delete iFindOperation;
+ iFindOperation = NULL;
+
+ // Parent view is ready. Start asynchronous find from native SIM view.
+ TRAPD( error,
+ {
+ iFindOperation =
+ iAllContactsView.NativeView().ContactMatchingPrefixL(
+ FindStrings(), *this );
+ });
+
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING(
+ "VPbkSimStore:CFindView(%x)::ContactViewReadyForFiltering:\
+ findOp(%x)"), this, iFindOperation );
+
+ if ( error != KErrNone )
+ {
+ ContactViewError( aView, error, EFalse );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::MatchL
+// --------------------------------------------------------------------------
+//
+void CFindView::MatchL( RPointerArray<MVPbkSimContact>& aMatchedContacts )
+ {
+ CleanupResetAndDestroyPushL( aMatchedContacts );
+ if (iAlwaysIncluded.Count() == 0)
+ {
+ // No always included contacts. The match can be done using
+ // only the SIM view matched contacts.
+ CViewContact* viewContact = CViewContact::NewL( iAllContactsView,
+ SortOrder() );
+ CleanupStack::PushL(viewContact);
+ MVPbkSimCntStore& simStore = iAllContactsView.Store().NativeStore();
+ const TInt count = iSIMMatchedContacts.Count();
+ for (TInt i = 0; i < count; ++i)
+ {
+ const TDesC8* cntBuf = simStore.AtL( iSIMMatchedContacts[i] );
+ if ( cntBuf )
+ {
+ CVPbkSimContact* cnt =
+ CVPbkSimContact::NewL( *cntBuf, simStore );
+ CleanupStack::PushL( cnt );
+ viewContact->SetSimContactL( *cnt );
+ if ( IsMatchL( *viewContact ) )
+ {
+ // Keep the order of the contacts same and move contact
+ // from iContactsModelMatchContacts to aMatchedContacts
+ aMatchedContacts.AppendL( cnt );
+ CleanupStack::Pop( cnt );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( cnt );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( viewContact );
+ }
+ else
+ {
+ // Do it slowly by looping all the parent view contacts.
+ const TInt contactCount = iParentView.ContactCountL();
+ for ( TInt i = 0; i < contactCount; ++i )
+ {
+ // iParentView is always VPbkCntModel view and the contacts type
+ // is CViewContact
+ const CViewContact& candidate = static_cast<const CViewContact&>(
+ iParentView.ContactAtL( i ) );
+ MatchContactL( candidate, aMatchedContacts );
+ }
+ }
+
+ // Free the memory
+ iSIMMatchedContacts.Reset();
+ CleanupStack::Pop( &aMatchedContacts );
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ViewFindCompleted
+// --------------------------------------------------------------------------
+//
+void CFindView::ViewFindCompleted(
+ MVPbkSimCntView& aSimCntView,
+ const RVPbkStreamedIntArray& aSimIndexArray )
+ {
+ TRAPD( error, ViewFindCompletedL( aSimCntView, aSimIndexArray ) );
+ VPBK_PROFILE_END(VPbkProfile::ESimStoreFind);
+
+ if ( error != KErrNone )
+ {
+ ContactViewError( *this, error, EFalse );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ViewFindError
+// --------------------------------------------------------------------------
+//
+void CFindView::ViewFindError(
+ MVPbkSimCntView& /*aSimCntView*/,
+ TInt aError )
+ {
+ ContactViewError( *this, aError, EFalse );
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::UpdateFilterL
+// --------------------------------------------------------------------------
+//
+void CFindView::UpdateFilterL(
+ const MDesCArray& aFindWords,
+ const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts )
+ {
+ SetFindStringsL( aFindWords );
+ SetAlwaysIncludedContactsL( aAlwaysIncludedContacts );
+ ActivateContactMatchL();
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::IsNativeMatchingRequestActive
+// --------------------------------------------------------------------------
+//
+TBool CFindView::IsNativeMatchingRequestActive()
+ {
+ if ( iFindOperation )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::IsContactAlwaysIncluded
+// --------------------------------------------------------------------------
+//
+TBool CFindView::IsContactAlwaysIncluded( const CViewContact& aContact ) const
+ {
+ return iAlwaysIncluded.Find( aContact.SimIndex() ) != KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::DoContactAddedToViewL
+// --------------------------------------------------------------------------
+//
+void CFindView::DoContactAddedToViewL(
+ MVPbkContactViewBase& aView,
+ TInt aIndex,
+ const MVPbkContactLink& /*aContactLink*/,
+ RPointerArray<MVPbkSimContact>& aMatchedContacts )
+ {
+ CleanupResetAndDestroyPushL( aMatchedContacts );
+ if ( &iParentView == &aView )
+ {
+ const CViewContact& viewContact = static_cast<const CViewContact&>(
+ iParentView.ContactAtL( aIndex ) );
+ if ( IsMatchL( viewContact ) )
+ {
+ MVPbkSimCntStore& simStore =
+ iAllContactsView.Store().NativeStore();
+ const TDesC8* cntBuf = simStore.AtL( viewContact.SimIndex() );
+ if ( cntBuf )
+ {
+ CVPbkSimContact* cnt =
+ CVPbkSimContact::NewL( *cntBuf, simStore );
+ CleanupStack::PushL( cnt );
+
+ // We have to insert the new contact to the correct
+ // location. VPbk sort policy is used for that.
+ CVPbkContactViewSortPolicy::TParam param(
+ iAllContactsView.Store().MasterFieldTypeList(), SortOrder() );
+ CVPbkContactViewSortPolicy* sortPolicy =
+ CVPbkContactViewSortPolicy::NewL( param );
+ CleanupStack::PushL( sortPolicy );
+ sortPolicy->SortStartL();
+ CViewContact* current =
+ CViewContact::NewL( iAllContactsView, SortOrder() );
+ CleanupStack::PushL( current );
+
+ const TInt count = aMatchedContacts.Count();
+ TInt index = KErrNotFound;
+ for ( TInt i = 0; i < count && index == KErrNotFound; ++i )
+ {
+ current->SetSimContactL( *aMatchedContacts[i] );
+ TInt res =
+ sortPolicy->CompareContacts( viewContact, *current );
+ // CompareContacts returns -1, 0 or 1.
+ if ( res < 0 )
+ {
+ index = i;
+ }
+ }
+ sortPolicy->SortCompleted();
+ CleanupStack::PopAndDestroy( 2, sortPolicy ); // current
+ if ( index != KErrNotFound )
+ {
+ // Contact is inserted to matched contacts list
+ aMatchedContacts.InsertL( cnt, index );
+ }
+ else
+ {
+ // List is empty so append contact to it
+ aMatchedContacts.AppendL( cnt );
+ }
+ CleanupStack::Pop( cnt );
+ }
+ }
+ }
+ CleanupStack::Pop( &aMatchedContacts );
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::ViewFindCompletedL
+// --------------------------------------------------------------------------
+//
+void CFindView::ViewFindCompletedL(
+ MVPbkSimCntView& /*aSimCntView*/,
+ const RVPbkStreamedIntArray& aSimIndexArray )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING(
+ "VPbkSimStore:CFindView(%x)::ViewFindCompletedL:found %d contacts"),
+ this, aSimIndexArray.Count() );
+
+ // Native SIM view find is ready.
+
+ // Clean the table
+ iSIMMatchedContacts.Reset();
+
+ // Copy matched indexes
+ const TInt count( aSimIndexArray.Count() );
+ for ( TInt i(0); i < count; ++i )
+ {
+ iSIMMatchedContacts.AppendL( aSimIndexArray[i] );
+ }
+
+ // The operation is not needed after indexes have been copied
+ delete iFindOperation;
+ iFindOperation = NULL;
+
+ // Call base class matching function. It will send internal observer
+ // event that this view is ready for filtering.
+ MatchContactsL();
+ // Send view ready event to both internal&external observers.
+ SendViewStateEventToObservers();
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::MatchContactL
+// --------------------------------------------------------------------------
+//
+void CFindView::MatchContactL( const CViewContact& aViewContact,
+ RPointerArray<MVPbkSimContact>& aMatchedContacts )
+ {
+ CleanupResetAndDestroyPushL( aMatchedContacts );
+ // aContact matches if it's one of the always included contacts OR
+ // (if it's one of Contacts Model matched contacts AND it also
+ // passes our own match).
+ TInt matchArrayIndex = KErrNotFound;
+ TBool matched = EFalse;
+ if ( IsContactAlwaysIncluded( aViewContact ) )
+ {
+ // Remove from match array to save memory
+ RemoveFromMatchArrayIfFound( aViewContact );
+ matched = ETrue;
+ }
+ else if ( IsSIMMatchL( aViewContact, matchArrayIndex ) )
+ {
+ // Remove from match array to save memory
+ iSIMMatchedContacts.Remove( matchArrayIndex );
+ iSIMMatchedContacts.Compress();
+
+ if ( IsMatchL( aViewContact ) )
+ {
+ matched = ETrue;
+ }
+ }
+
+ if ( matched )
+ {
+ // Contact matched.
+ // CFindView owns its contacts so create a copy
+ MVPbkSimCntStore& simStore = iAllContactsView.Store().NativeStore();
+ const TDesC8* cntBuf = simStore.AtL( aViewContact.SimIndex() );
+ if ( cntBuf )
+ {
+ CVPbkSimContact* cnt =
+ CVPbkSimContact::NewL( *cntBuf, simStore );
+ CleanupStack::PushL( cnt );
+ aMatchedContacts.AppendL( cnt );
+ CleanupStack::Pop( cnt );
+ }
+ }
+ CleanupStack::Pop( &aMatchedContacts );
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::RemoveFromMatchArrayIfFound
+// --------------------------------------------------------------------------
+//
+void CFindView::RemoveFromMatchArrayIfFound( const CViewContact& aViewContact )
+ {
+ TInt index = FindFromMatchArray( aViewContact );
+ if ( index != KErrNotFound )
+ {
+ iSIMMatchedContacts.Remove( index );
+ iSIMMatchedContacts.Compress();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::IsSIMMatchL
+// --------------------------------------------------------------------------
+//
+TBool CFindView::IsSIMMatchL( const CViewContact& aContact,
+ TInt& aMatchArrayIndex ) const
+ {
+ aMatchArrayIndex = FindFromMatchArray( aContact );
+ return aMatchArrayIndex != KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::FindFromMatchArray
+// --------------------------------------------------------------------------
+//
+TInt CFindView::FindFromMatchArray( const CViewContact& aContact ) const
+ {
+ return iSIMMatchedContacts.Find( aContact.SimIndex() );
+ }
+} // namespace VPbkSimStore
+// End of File