phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFindView.cpp
changeset 0 e686773b3f54
child 32 2828b4d142c0
--- /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