diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindView.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,484 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include + +// Debugging headers +#include +#include + +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( + &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& 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( + iParentView.ContactAtL( i ) ); + MatchContactL( candidate, aMatchedContacts ); + } + } + + // Free the memory + iSIMMatchedContacts.Reset(); + } + +// -------------------------------------------------------------------------- +// 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& aMatchedContacts ) + { + if ( &iParentView == &aView ) + { + const CViewContact& viewContact = static_cast( + 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 ); + } + } + } + } + +// -------------------------------------------------------------------------- +// 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& 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 ); + } + } + } + +// -------------------------------------------------------------------------- +// 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