diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkSimStore/src/CRefineView.cpp --- /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 +#include +#include +#include +#include + +// System includes +#include +#include + +// Debugging headers +#include + +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& 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( + 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( candidate.NativeContact() ); + aMatchedContacts.AppendL( nativeContact ); + } + } + } + +// -------------------------------------------------------------------------- +// CRefineView::DoContactAddedToViewL +// -------------------------------------------------------------------------- +// +void CRefineView::DoContactAddedToViewL( MVPbkContactViewBase& aView, + TInt aIndex, const MVPbkContactLink& /*aContactLink*/, + RPointerArray& 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( + 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( 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( 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