phonebookengines/VirtualPhonebook/VPbkSimStore/src/CRefineView.cpp
changeset 0 e686773b3f54
child 32 2828b4d142c0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkSimStore/src/CRefineView.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,270 @@
+/*
+* 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 "CRefineView.h"
+
+// From VPbkSimStore
+#include "CContactStore.h"
+#include "CViewContact.h"
+#include "CContactView.h"
+
+// From Virtual Phonebook
+#include <MVPbkSimContact.h>
+#include <CVPbkSimCntField.h>
+#include <CVPbkContactFindPolicy.h>
+#include <MVPbkContactLink.h>
+#include <CVPbkContactViewSortPolicy.h>
+
+// System includes
+#include <cntviewbase.h>
+#include <featmgr.h>
+
+// Debugging headers
+#include <VPbkProfile.h>
+
+namespace VPbkSimStore {
+
+inline CRefineView::CRefineView( MParentViewForFiltering& aParentView,
+        CContactView& aAllContactsView,
+        MAlwaysIncludedContacts& aAlwaysIncluded ) 
+        :   CFindViewBase( aParentView, aAllContactsView, EFalse ),
+            iAlwaysIncluded( aAlwaysIncluded )
+    {
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::~CRefineView
+// --------------------------------------------------------------------------
+//
+CRefineView::~CRefineView()
+    {
+    delete iIdleUpdate;
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::NewLC
+// --------------------------------------------------------------------------
+//
+CRefineView* CRefineView::NewLC(
+        const MDesCArray& aFindStrings,
+        MParentViewForFiltering& aParentView,
+        CContactView& aAllContactsView,
+        MVPbkContactViewObserver& aExternalViewObserver,
+        MVPbkContactFindPolicy& aContactFindPolicy,
+        MAlwaysIncludedContacts& aAlwaysIncluded )
+    {
+    CRefineView* self =
+        new ( ELeave ) CRefineView( aParentView, aAllContactsView, 
+            aAlwaysIncluded );
+    CleanupStack::PushL( self );
+    self->BaseConstructL( aExternalViewObserver, aFindStrings, 
+        aContactFindPolicy  );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::ContactViewReady
+// --------------------------------------------------------------------------
+//
+void CRefineView::ContactViewReady( MVPbkContactViewBase& /*aView*/ )
+    {
+    // Send view ready event to all observers
+    SendViewStateEventToObservers();
+    }
+    
+// --------------------------------------------------------------------------
+// CRefineView::ContactViewReadyForFiltering
+// --------------------------------------------------------------------------
+//
+void CRefineView::ContactViewReadyForFiltering( 
+        MParentViewForFiltering& /*aView*/ )
+    {
+    // Cancel update so that there won't be double matching in case
+    // the parent view is updating itself and also this view is updating
+    // itself.
+    if ( iIdleUpdate )
+        {
+        iIdleUpdate->Cancel();
+        }
+        
+    // Parent view is ready -> Call base class function to start
+    // matching. MatchContactsL will also call internal observer interface
+    // to send internal view events to higher level filtered views. This
+    // way all the CRefineViews are updated before any external observer
+    // gets the view event. 
+    // External observers will get view event from this view when the
+    // CFindView  (CFindView::ViewFindCompletedL) calls 
+    // SendViewStateEventToObservers.
+    TRAPD( res, MatchContactsL() );
+    if ( res != KErrNone )
+        {
+        ContactViewError( *this, res, EFalse );
+        }
+    }
+    
+// --------------------------------------------------------------------------
+// CRefineView::MatchL
+// --------------------------------------------------------------------------
+//
+void CRefineView::MatchL( RPointerArray<MVPbkSimContact>& aMatchedContacts )
+    {
+    const TInt contactCount = iParentView.ContactCountL();
+    for ( TInt i = 0; i < contactCount; ++i )
+        {
+        // iParentView is always VPbkSimStore view and the contacts type
+        // is CViewContact
+        const CViewContact& candidate = static_cast<const CViewContact&>(
+            iParentView.ContactAtL( i ) );
+        if ( IsContactAlwaysIncluded( candidate ) || IsMatchL( candidate ) )
+            {
+            // iParentView is always CFindView or CRefineView. The contacts type
+            // is CViewContact. It can be safely casted. Const cast be done
+            // because aContact is actually owned by CFindView.
+            MVPbkSimContact* nativeContact = 
+                const_cast<MVPbkSimContact*>( candidate.NativeContact() );
+            aMatchedContacts.AppendL( nativeContact );
+            }
+        }    
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::DoContactAddedToViewL
+// --------------------------------------------------------------------------
+//
+void CRefineView::DoContactAddedToViewL( MVPbkContactViewBase& aView,
+        TInt aIndex, const MVPbkContactLink& /*aContactLink*/,
+        RPointerArray<MVPbkSimContact>& aMatchedContacts )
+    {
+    if ( &iParentView == &aView && 
+         IsMatchL( iParentView.ContactAtL( aIndex )))
+        {
+        // iParentView is always CFindView or CRefineView the contacts type
+        // is CViewContact. It can be safely casted.
+        const CViewContact& contact = static_cast<const CViewContact&>(
+            iParentView.ContactAtL( aIndex ) );
+        
+        // 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();
+        // Create a view contact instance for comparing contacts.
+        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( contact, *current );
+            if ( res < 0 )
+                {
+                index = i;
+                }
+            }
+        sortPolicy->SortCompleted();
+        CleanupStack::PopAndDestroy( 2, sortPolicy );
+        
+        // Const cast be done
+        // because nativeContact is actually owned by CFindView.
+        MVPbkSimContact* nativeContact = 
+            const_cast<MVPbkSimContact*>( contact.NativeContact() );
+        if ( index != KErrNotFound )
+            {
+            aMatchedContacts.InsertL( nativeContact, index );
+            }
+        else
+            {
+            aMatchedContacts.AppendL( nativeContact );
+            }
+        }    
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::UpdateFilterL
+// --------------------------------------------------------------------------
+//
+void CRefineView::UpdateFilterL( 
+        const MDesCArray& aFindWords,
+        const MVPbkContactBookmarkCollection* /*aAlwaysIncludedContacts*/ )
+    {
+    if ( !iIdleUpdate )
+        {
+        iIdleUpdate = CIdle::NewL( CActive::EPriorityStandard );
+        }
+        
+    // NOTE:
+    // aAlwaysIncludedContacts is not used by CRefineView. It uses 
+    // MAlwaysIncludedContacts interface for that purpose.
+    SetFindStringsL( aFindWords );
+    // Start idle update.
+    if ( !iIdleUpdate->IsActive() )
+        {
+        iIdleUpdate->Start( TCallBack( StartUpdateCallback, this ) ); 
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::IsNativeMatchingRequestActive
+// --------------------------------------------------------------------------
+//
+TBool CRefineView::IsNativeMatchingRequestActive()
+    {
+    // Forward to CFindView
+    return iParentView.IsNativeMatchingRequestActive();
+    }
+    
+// --------------------------------------------------------------------------
+// CRefineView::IsContactAlwaysIncluded
+// --------------------------------------------------------------------------
+//
+TBool CRefineView::IsContactAlwaysIncluded( 
+        const CViewContact& aContact ) const
+    {
+    return iAlwaysIncluded.IsContactAlwaysIncluded( aContact );
+    }
+
+// --------------------------------------------------------------------------
+// CRefineView::StartUpdateCallback
+// --------------------------------------------------------------------------
+//
+TInt CRefineView::StartUpdateCallback( TAny* aThis )
+    {
+    CRefineView* view = static_cast<CRefineView*>( aThis );
+    // If the CFindView is doing async match from SIM server then
+    // do nothing here and wait that parent view notifies this view.
+    if ( !view->IsNativeMatchingRequestActive() )
+        {
+        TRAPD( res, view->ActivateContactMatchL() )
+        if ( res != KErrNone )
+            {
+            view->ContactViewError( *view, res, EFalse );
+            }
+        }
+    // Do not continue idle
+    return EFalse;
+    }
+} // namespace VPbkSimStore
+
+// End of File