diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFindView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFindView.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,309 @@ +/* +* 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: Contacts Model store filtered contact view implementation. +* +*/ + + +// INCLUDES +#include "CFindView.h" + +// VPbkCntModel +#include "CRefineView.h" +#include "CViewBase.h" +#include "CContactBookmark.h" +#include "CContactStore.h" + +// From Virtual Phonebook +#include +#include +#include + +// System includes +#include + +// Debugging headers +#include + +namespace VPbkCntModel { + +// -------------------------------------------------------------------------- +// CFindView::CFindView +// -------------------------------------------------------------------------- +// +inline CFindView::CFindView( CViewBase& aBaseView ) + : CFindViewBase( aBaseView, aBaseView, ETrue ) + { + } + +// -------------------------------------------------------------------------- +// CFindView::ConstructL +// -------------------------------------------------------------------------- +// +void CFindView::ConstructL( const MDesCArray& aFindStrings, + const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts, + MVPbkContactViewObserver& aExternalViewObserver, RFs& aRFs ) + { + CVPbkContactFindPolicy::TParam findPolicyParams( + iBaseView.Store().MasterFieldTypeList(), aRFs ); + iFindPolicy = CVPbkContactFindPolicy::NewL( findPolicyParams ); + BaseConstructL( aFindStrings, *iFindPolicy, + aExternalViewObserver ); + SetAlwaysIncludedContactsL( aAlwaysIncludedContacts ); + } + +// -------------------------------------------------------------------------- +// CFindView::NewLC +// -------------------------------------------------------------------------- +// +CFindView* CFindView::NewLC( + const MDesCArray& aFindStrings, + CViewBase& aParentView, + MVPbkContactViewObserver& aExternalViewObserver, + const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts, + RFs& aRFs ) + { + CFindView* self = + new ( ELeave ) CFindView( aParentView ); + CleanupStack::PushL( self ); + self->ConstructL( aFindStrings, aAlwaysIncludedContacts, + aExternalViewObserver, aRFs ); + return self; + } + +// -------------------------------------------------------------------------- +// CFindView::~CFindView +// -------------------------------------------------------------------------- +// +CFindView::~CFindView() + { + delete iFindPolicy; + iAlwaysIncluded.Close(); + iContactsModelMatchContacts.ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// CFindView::SetAlwaysIncludedContactsL +// -------------------------------------------------------------------------- +// +void CFindView::SetAlwaysIncludedContactsL( + const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts ) + { + // Destroy old ids + iAlwaysIncluded.Reset(); + + if ( aAlwaysIncludedContacts ) + { + MVPbkContactStore& store = ParentObject().ContactStore(); + const TInt count = aAlwaysIncludedContacts->Count(); + for ( TInt i = 0; i < count; ++i ) + { + const CContactBookmark* 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->ContactId() ); + } + } + } + } + +// -------------------------------------------------------------------------- +// CFindView::MatchL +// -------------------------------------------------------------------------- +// +void CFindView::MatchL( + RPointerArray& aMatchedContacts ) + { + iContactsModelMatchContacts.ResetAndDestroy(); + + VPBK_PROFILE_START(VPbkProfile::ECntModelFind); + // Get matches from Contacts Model + iBaseView.NativeView().ContactsMatchingPrefixL( + FindStrings(), iContactsModelMatchContacts ); + VPBK_PROFILE_END(VPbkProfile::ECntModelFind); + + if (iAlwaysIncluded.Count() == 0) + { + // No always included contacts. The match can be done using + // only the Contacts Model matched contacts. + CViewContact* viewContact = CViewContact::NewL( iBaseView, SortOrder() ); + CleanupStack::PushL(viewContact); + const TInt count = iContactsModelMatchContacts.Count(); + for (TInt i = 0; i < count; ++i) + { + viewContact->SetViewContact( *iContactsModelMatchContacts[i] ); + if ( IsMatchL( *viewContact ) ) + { + // Keep the order of the contacts same and move contact + // from iContactsModelMatchContacts to aMatchedContacts + aMatchedContacts.AppendL(iContactsModelMatchContacts[i]); + // Don't remove the contact to keep indexes correct. + // Set to NULL so that ResetAndDestroy doesn't crash in + // destructor + iContactsModelMatchContacts[i] = NULL; + } + } + 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 ); + } + } + + iContactsModelMatchContacts.ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// 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 ) ) + { + CCntModelViewContact* cnt = + CCntModelViewContact::NewL( *viewContact.NativeContact() ); + CleanupStack::PushL( cnt ); + aMatchedContacts.InsertInOrderAllowRepeatsL( cnt, + TLinearOrder( + CCompareView::CompareFieldsL ) ); + CleanupStack::Pop( cnt ); + } + } + } + +// -------------------------------------------------------------------------- +// CFindView::UpdateFilterL +// -------------------------------------------------------------------------- +// +void CFindView::UpdateFilterL( + const MDesCArray& aFindWords, + const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts ) + { + SetFindStringsL( aFindWords ); + SetAlwaysIncludedContactsL( aAlwaysIncludedContacts ); + ActivateContactMatchL(); + } + +// -------------------------------------------------------------------------- +// 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 ( IsContactsModelMatchL( aViewContact, matchArrayIndex ) ) + { + // Remove from match array to save memory + delete iContactsModelMatchContacts[matchArrayIndex]; + iContactsModelMatchContacts.Remove( matchArrayIndex ); + + if ( IsMatchL( aViewContact ) ) + { + matched = ETrue; + } + } + + if ( matched ) + { + // Contact matched. + // CFindView owns its contacts so create a copy + CCntModelViewContact* cnt = + CCntModelViewContact::NewL( *aViewContact.NativeContact() ); + CleanupStack::PushL( cnt ); + aMatchedContacts.AppendL( cnt ); + CleanupStack::Pop( cnt ); + } + } + +// -------------------------------------------------------------------------- +// CFindView::IsContactAlwaysIncluded +// -------------------------------------------------------------------------- +// +TBool CFindView::IsContactAlwaysIncluded( + const CViewContact& aContact ) const + { + return iAlwaysIncluded.Find( aContact.Id() ) != KErrNotFound; + } + +// -------------------------------------------------------------------------- +// CFindView::IsContactsModelMatchL +// -------------------------------------------------------------------------- +// +TBool CFindView::IsContactsModelMatchL( const CViewContact& aContact, + TInt& aMatchArrayIndex ) const + { + // Contacts are in order in iContactsModelMatchContacts. Use binary + // search to check if aContact is can be found from the array. + aMatchArrayIndex = FindFromMatchArray( aContact ); + return aMatchArrayIndex != KErrNotFound; + } + +// -------------------------------------------------------------------------- +// CFindView::RemoveFromMatchArrayIfFound +// -------------------------------------------------------------------------- +// +void CFindView::RemoveFromMatchArrayIfFound( const CViewContact& aContact ) + { + TInt index = FindFromMatchArray( aContact ); + if ( index != KErrNotFound ) + { + delete iContactsModelMatchContacts[index]; + iContactsModelMatchContacts.Remove(index); + } + } + +// -------------------------------------------------------------------------- +// CFindView::FindFromMatchArray +// -------------------------------------------------------------------------- +// +TInt CFindView::FindFromMatchArray( const CViewContact& aContact ) const + { + return iContactsModelMatchContacts.FindInOrder( + aContact.NativeContact(), + TLinearOrder( CCompareView::CompareFieldsL ) ); + } +} // namespace VPbkCntModel +// End of File