--- /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 <CVPbkContactNameConstructionPolicy.h>
+#include <CVPbkContactFindPolicy.h>
+#include <MVPbkContactBookmarkCollection.h>
+
+// System includes
+#include <cntdef.h>
+
+// Debugging headers
+#include <VPbkProfile.h>
+
+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<const CContactBookmark*>(
+ &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<CCntModelViewContact>& 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<const CViewContact&>(
+ iParentView.ContactAtL( i ) );
+ MatchContactL( candidate, aMatchedContacts );
+ }
+ }
+
+ iContactsModelMatchContacts.ResetAndDestroy();
+ }
+
+// --------------------------------------------------------------------------
+// CFindView::DoContactAddedToViewL
+// --------------------------------------------------------------------------
+//
+void CFindView::DoContactAddedToViewL( MVPbkContactViewBase& aView,
+ TInt aIndex, const MVPbkContactLink& /*aContactLink*/,
+ RPointerArray<CCntModelViewContact>& aMatchedContacts )
+ {
+ if ( &iParentView == &aView )
+ {
+ const CViewContact& viewContact = static_cast<const CViewContact&>(
+ iParentView.ContactAtL( aIndex ) );
+ if ( IsMatchL( viewContact ) )
+ {
+ CCntModelViewContact* cnt =
+ CCntModelViewContact::NewL( *viewContact.NativeContact() );
+ CleanupStack::PushL( cnt );
+ aMatchedContacts.InsertInOrderAllowRepeatsL( cnt,
+ TLinearOrder<CCntModelViewContact>(
+ 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<CCntModelViewContact>& 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<CCntModelViewContact>( CCompareView::CompareFieldsL ) );
+ }
+} // namespace VPbkCntModel
+// End of File