--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFilteredContactView.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,620 @@
+/*
+* 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 "CFilteredContactView.h"
+
+// VPbkCntModel
+#include "CContactStore.h"
+#include "CFieldFactory.h"
+#include "CCustomFilteredContactView.h"
+#include <VPbkCntModelRes.rsg>
+#include "VPbkCntModelRemoteViewPreferences.h"
+#include "NamedRemoteViewViewDefinitionStoreUtility.h"
+
+
+// VPbkEng
+#include <CVPbkFieldTypeSelector.h>
+#include <VPbkDataCaging.hrh>
+#include <CVPbkFieldType.h>
+#include <CVPbkFieldTypeList.h>
+#include <CVPbkContactViewDefinition.h>
+#include <TVPbkFieldVersitProperty.h>
+#include <VPbkSendEventUtility.h>
+#include <VPbkPrivateUid.h> // KFindPluingUID
+#include <CVPbkSortOrder.h>
+
+// VPbkEngUtils
+#include <RLocalizedResourceFile.h>
+
+// System includes
+#include <cntview.h>
+#include <barsread.h>
+
+// Debugging headers
+#include <VPbkDebug.h>
+
+namespace VPbkCntModel {
+
+// CONSTANTS
+
+_LIT( KResourceFile, "VPbkCntModelRes.rsc" );
+
+/// Field type filter mapping structure
+struct TVPbkFieldTypeFilterMapping
+ {
+ /// Virtual Phonebook field type resource id
+ TUint iFieldTypeResourceId;
+ /// Contacst Model native filter matching the field type
+ TUint iNativeFilter;
+ };
+
+/// Last element marker
+const TUint KLastElement = 0;
+
+/// Array of field type filter mappings
+static const TVPbkFieldTypeFilterMapping FilterMapping[] =
+ {
+ { R_CNTMODEL_NATIVE_FILTER_EMAIL_ADDRESS,
+ CContactDatabase::EMailable },
+
+ { R_CNTMODEL_NATIVE_FILTER_PHONE_NUMBER,
+ CContactDatabase::EPhonable },
+
+ { R_CNTMODEL_NATIVE_FILTER_SMS_ADDRESS,
+ CContactDatabase::ESmsable },
+
+ { R_CNTMODEL_NATIVE_FILTER_FAX_NUMBER,
+ CContactDatabase::EFaxable },
+
+ { R_CNTMODEL_NATIVE_FILTER_RINGING_TONE,
+ CContactDatabase::ERingTone },
+
+ { R_CNTMODEL_NATIVE_FILTER_ASSISTANT_PHONE_NUMBER,
+ CContactDatabase::EPhonable },
+
+ { R_CNTMODEL_NATIVE_FILTER_TOP_CONTACT,
+ CContactDatabase::ECustomFilter2 },
+
+ /// This has to be the last
+ { KLastElement,
+ CContactDatabase::EUnfiltered }
+ };
+
+
+/**
+ * Appends native filter aFilter based on the given field type resource id.
+ *
+ * @param aFieldTypeResourceId Field type resource id.
+ * @param aFilter Native Contacts Model filter.
+ */
+inline void BuildNativeFilter( const TInt aFieldTypeResourceId,
+ TUint& aFilter )
+ {
+ for ( TInt i=0;
+ FilterMapping[i].iFieldTypeResourceId != KLastElement; ++i )
+ {
+ if ( aFieldTypeResourceId == FilterMapping[i].iFieldTypeResourceId )
+ {
+ aFilter |= FilterMapping[i].iNativeFilter;
+ break;
+ }
+ }
+ }
+
+/**
+ * Checks wheter custom filtering is needed. This is the case
+ * when the native filters cannot provide all the necessary filtering.
+ *
+ * @param aFieldType The field type which matched selectors field type
+ * collection.
+ * @param aFilterType The filter type which matched aFieldType, or NULL.
+ * @param aSelector The field type selector, the filtering criteria.
+ * @return ETrue if custom filtering is needed.
+ */
+TBool RequiresCustomFiltering(
+ const MVPbkFieldType& aFieldType,
+ const MVPbkFieldType* aFilterType,
+ const CVPbkFieldTypeSelector& aSelector )
+ {
+ TBool ret = ETrue;
+
+ if ( aFilterType )
+ {
+ const TVPbkFieldVersitProperty* matchingProperty =
+ aSelector.MatchingVersitProperty( aFieldType );
+ if ( matchingProperty )
+ {
+ const TInt maxMatchPriority =
+ aFilterType->VersitProperties().Count() - 1;
+ for ( TInt matchPriority = 0;
+ matchPriority <= maxMatchPriority; ++matchPriority )
+ {
+ if ( matchingProperty->Matches(
+ aFilterType->VersitProperties()[matchPriority]) )
+ {
+ ret = EFalse;
+ break;
+ }
+ }
+ }
+ else
+ {
+ TVPbkNonVersitFieldType matchingType =
+ aSelector.MatchingNonVersitType( aFieldType );
+ if ( aFieldType.NonVersitType() == matchingType )
+ {
+ ret = EFalse;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+/**
+ * Checks does the given field type match any of the native filter types.
+ *
+ * @param aFieldType The field type to inspect.
+ * @param aSupportedFilterTypes Field types which are supported
+ * by the native filters.
+ * @return Native filter field type which matched aFieldType,
+ * or NULL if no matches.
+ */
+inline const MVPbkFieldType* MatchesNativeFilter
+ ( const MVPbkFieldType& aFieldType,
+ const CVPbkFieldTypeList& aSupportedFilterTypes )
+
+ {
+ const MVPbkFieldType* matchingType = NULL;
+
+ const TInt maxMatchPriority =
+ aFieldType.VersitProperties().Count() - 1;
+
+ for ( TInt matchPriority = 0;
+ matchPriority <= maxMatchPriority && !matchingType; ++matchPriority )
+ {
+ matchingType = aSupportedFilterTypes.FindMatch(
+ aFieldType.VersitProperties()[matchPriority],
+ matchPriority );
+ }
+
+ if ( !matchingType && aFieldType.NonVersitType() != EVPbkNonVersitTypeNone )
+ {
+ matchingType = aSupportedFilterTypes.FindMatch
+ ( aFieldType.NonVersitType() );
+ }
+
+ return matchingType;
+ }
+
+/**
+ * Converts VPbk field type filter to a native filter.
+ *
+ * @param aSource Field type filter to convert.
+ * @param aFieldTypeList List of supported field types
+ * of the store.
+ * @param aFs File server session.
+ * @param aCustomFilteringNeeded Indicates whether the native filters
+ * are enough, or do we have to do custom
+ * filtering.
+ * @return Native Contacts model contact view filter.
+ */
+TUint ConvertFieldTypeFilterL
+ ( const CVPbkFieldTypeSelector& aSource,
+ const MVPbkFieldTypeList& aFieldTypeList,
+ RFs& aFs, TBool& aCustomFilteringNeeded )
+ {
+ TUint ret = CContactDatabase::EUnfiltered;
+
+ // Build own field type list containing field types supported
+ // by native filters
+ VPbkEngUtils::RLocalizedResourceFile resFile;
+ resFile.OpenLC( aFs,
+ KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, KResourceFile );
+
+ TResourceReader reader;
+ reader.SetBuffer( resFile.AllocReadLC
+ ( R_CNTMODEL_NATIVE_FILTER_FIELD_TYPES ) );
+
+ CVPbkFieldTypeList* supportedFilterTypes =
+ CVPbkFieldTypeList::NewL( resFile, reader );
+ CleanupStack::PushL( supportedFilterTypes );
+
+ // Go through the store's field type list
+ TInt typeCount = aFieldTypeList.FieldTypeCount();
+ for ( TInt i=0; i < typeCount; ++i )
+ {
+ const MVPbkFieldType& fieldType =
+ aFieldTypeList.FieldTypeAt( i );
+
+ if ( aSource.IsFieldTypeIncluded( fieldType ) )
+ {
+ // We have a match. Now lets inspect does it match
+ // any of the native filter field types
+ const MVPbkFieldType* matchingType =
+ MatchesNativeFilter( fieldType, *supportedFilterTypes );
+
+ if ( matchingType )
+ {
+ // We found a match to a native filter, lets build
+ // the native filter
+ BuildNativeFilter( matchingType->FieldTypeResId(), ret );
+ }
+
+ // Then, find out do we need to custom filtering
+ TBool customFilteringRequired = RequiresCustomFiltering
+ ( fieldType, matchingType, aSource );
+ aCustomFilteringNeeded = customFilteringRequired;
+
+ if ( !matchingType && customFilteringRequired )
+ {
+ // Custom filtering is required and there is no appropriate
+ // native filter which could be used as a base filter.
+ // In this case the custom filter has to handle all
+ // the filtering. So reset the native filter and break out.
+ ret = CContactDatabase::EUnfiltered;
+ break;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 3 ); // supportedFilterTypes,
+ // reader, resFile
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::CFilteredContactView
+// --------------------------------------------------------------------------
+//
+inline CFilteredContactView::CFilteredContactView
+ ( CContactStore& aParentStore,
+ RFs& aFs ) :
+ CViewBase( aParentStore ),
+ iFs( aFs )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::~CFilteredContactView
+// --------------------------------------------------------------------------
+//
+CFilteredContactView::~CFilteredContactView()
+ {
+ // Customically filtered view has to be destructed first
+ delete iCustomFilteredView;
+ delete iFilter;
+
+ // Set iView to NULL, so that CViewBase does not close it
+ iView = NULL;
+
+ if ( iFilteredView )
+ {
+ //after iFilteredView->Close( *iNativeObserver )
+ //both iFilteredView and iBaseView are deleted
+ iFilteredView->Close( *iNativeObserver );
+ }
+ else if ( iBaseView )
+ {
+ //but iBaseView's pointer is still not NULL
+ //make sure iBaseView is unable to call its member function
+ iBaseView->Close( *iNativeObserver );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::NewLC
+// --------------------------------------------------------------------------
+//
+CFilteredContactView* CFilteredContactView::NewLC(
+ const CVPbkContactViewDefinition& aViewDefinition,
+ MVPbkContactViewObserver& aObserver,
+ CContactStore& aParentStore,
+ const MVPbkFieldTypeList& aSortOrder,
+ RFs& aFs )
+ {
+ CFilteredContactView* self = new ( ELeave ) CFilteredContactView
+ ( aParentStore, aFs );
+ CleanupStack::PushL( self );
+ self->ConstructL( aViewDefinition, aObserver, aSortOrder );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ConstructL
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ConstructL(
+ const CVPbkContactViewDefinition& aViewDefinition,
+ MVPbkContactViewObserver& aObserver,
+ const MVPbkFieldTypeList& aSortOrder )
+ {
+ CViewBase::ConstructL( aViewDefinition, aObserver, aSortOrder );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::Type
+// --------------------------------------------------------------------------
+//
+TVPbkContactViewType CFilteredContactView::Type() const
+ {
+ return EVPbkContactsView;
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::DoInitializeViewL
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::DoInitializeViewL(
+ const CVPbkContactViewDefinition& aViewDefinition,
+ RContactViewSortOrder& aViewSortOrder )
+ {
+ // Construct the native filter
+ if ( aViewDefinition.FieldTypeFilter() )
+ {
+ const CFieldFactory& fieldFactory = Store().FieldFactory();
+
+ // Copy construct the filter
+ iFilter = CVPbkFieldTypeSelector::NewL(
+ *aViewDefinition.FieldTypeFilter() );
+
+ iNativeFilter = ConvertFieldTypeFilterL
+ ( *iFilter, fieldFactory, iFs, iCustomFilteringNeeded );
+ }
+ if ( aViewDefinition.ContactSelector() )
+ {
+ iCustomFilteringNeeded = ETrue;
+ // Custom filtering and MVPbkContactSelector filtering cannot be used at the same time.
+ iNativeFilter = 0; // no filter
+ }
+ if ( iCustomFilteringNeeded )
+ {
+ // Stop observing the base view, the custom view
+ // will observe it and report back
+ // Construction of the iCustomFilteredView should be done in two
+ // phases. Due to that there is dependencies between views in this
+ // and iCustomFilteredView class.
+ iCustomFilteredView =
+ new (ELeave) CCustomFilteredContactView( Store(), iFilter,
+ *this, aViewDefinition.ContactSelector() );
+ ConstructBaseViewsL( aViewDefinition, *iCustomFilteredView,
+ aViewSortOrder );
+
+ if ( iFilteredView )
+ {
+ iBaseView->Close( *iCustomFilteredView );
+ }
+
+ iCustomFilteredView->ConstructL
+ ( aViewDefinition, *this, *iSortOrder, *iView );
+
+ iView = &iCustomFilteredView->ContactViewBase();
+ }
+ else
+ {
+ ConstructBaseViewsL( aViewDefinition, *this, aViewSortOrder );
+
+ // If we built Contact's Model's native filtered view we must
+ // stop observing the base view since otherwise we get double
+ // view events and VPbk composite view does not tolerate double
+ // events
+ if ( iFilteredView )
+ {
+ iBaseView->Close( *this );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::DoTeardownView
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::DoTeardownView()
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::DoChangeSortOrderL
+// --------------------------------------------------------------------------
+//
+TBool CFilteredContactView::DoChangeSortOrderL(
+ const CVPbkContactViewDefinition& aViewDefinition,
+ RContactViewSortOrder& aSortOrder )
+ {
+ TBool canBeChanged = ETrue;
+ if ( iRemoteView )
+ {
+ if ( RemoteViewName( aViewDefinition ).Compare(
+ KVPbkAllContactsViewName ) == 0 )
+ {
+ // Set Contacts Model default view setting only if client
+ // is using KVPbkAllContactsViewName shared view.
+ NamedRemoteViewViewDefinitionStoreUtility::
+ SetNamedRemoteViewViewDefinitionL(
+ KVPbkAllContactsViewName, aSortOrder,
+ KVPbkDefaultContactViewPrefs);
+ }
+ iRemoteView->ChangeSortOrderL( aSortOrder );
+ }
+ else
+ {
+ // CContactLocalView doesn't support ChangeSortOrderL
+ canBeChanged = EFalse;
+ }
+
+ return canBeChanged;
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ContactViewReady
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ContactViewReady(
+ MVPbkContactViewBase& aView )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
+ ("CFilteredContactView::ContactViewReady(0x%x)"), &aView);
+
+ /* when custom filtering view is used, MVPbkContactViewObserver doesn't support
+ * sortOrder changed notification, CViewBase will send viewReady instead,
+ * use it to keep sort order up to date */
+ if ( iCustomFilteringNeeded )
+ {
+ DoUpdateTypeListL();
+ }
+
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MFilteredViewSupportObserver::ContactViewReadyForFiltering,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iObservers,
+ &MVPbkContactViewObserver::ContactViewReady,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MVPbkContactViewObserver::ContactViewReady,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ContactViewUnavailable
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ContactViewUnavailable(
+ MVPbkContactViewBase& aView )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
+ ("CFilteredContactView::ContactViewUnavailable(0x%x)"), &aView);
+
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MFilteredViewSupportObserver::ContactViewUnavailableForFiltering,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iObservers,
+ &MVPbkContactViewObserver::ContactViewUnavailable,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ &MVPbkContactViewObserver::ContactViewUnavailable,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ContactAddedToView
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ContactAddedToView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex, const MVPbkContactLink& aContactLink )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
+ ("CFilteredContactView::ContactAddedToView(0x%x)"), &aView);
+
+ VPbkEng::SendViewEventToObservers( *this, aIndex, aContactLink,
+ iObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, aIndex, aContactLink,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ContactRemovedFromView
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ContactRemovedFromView(
+ MVPbkContactViewBase& aView,
+ TInt aIndex, const MVPbkContactLink& aContactLink )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
+ ("CFilteredContactView::ContactRemovedFromView(0x%x)"), &aView);
+
+ VPbkEng::SendViewEventToObservers( *this, aIndex, aContactLink,
+ iObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, aIndex, aContactLink,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ContactViewError
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ContactViewError(
+ MVPbkContactViewBase& aView,
+ TInt aError, TBool aErrorNotified )
+ {
+ VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
+ ("CFilteredContactView::ContactViewError(0x%x)"), &aView);
+
+ VPbkEng::SendEventToObservers( *this, aError, aErrorNotified, iObservers,
+ &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendEventToObservers( *this, aError, aErrorNotified,
+ iFilteringObservers, &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CFilteredContactView::ConstructBaseViewsL
+// --------------------------------------------------------------------------
+//
+void CFilteredContactView::ConstructBaseViewsL
+ ( const CVPbkContactViewDefinition& aViewDefinition,
+ MContactViewObserver& aObserver,
+ RContactViewSortOrder& aViewSortOrder )
+ {
+ iNativeObserver = &aObserver;
+
+ // Construct the all contacts view first
+ if ( RemoteViewDefinition( aViewDefinition ) )
+ {
+ iRemoteView = CContactNamedRemoteView::NewL(
+ *iNativeObserver, RemoteViewName( aViewDefinition ),
+ Store().NativeDatabase(), aViewSortOrder,
+ KVPbkDefaultContactViewPrefs );
+
+ iBaseView = iRemoteView;
+ }
+ else
+ {
+ iBaseView = CContactLocalView::NewL( *iNativeObserver,
+ Store().NativeDatabase(), aViewSortOrder,
+ KVPbkDefaultContactViewPrefs );
+ }
+
+ // Set base class view pointer
+ iView = iBaseView;
+
+ // If there is a native filter, construct a native filtered view
+ if ( iNativeFilter > 0 )
+ {
+ iFilteredView = CContactFilteredView::NewL
+ ( *iNativeObserver, Store().NativeDatabase(),
+ *iBaseView, iNativeFilter );
+ // Set find plugin also for BaseView, otherwise searching doesn't
+ // work properly with other languages in other clients.
+ iView->SetViewFindConfigPlugin( TUid::Uid( KFindPluginUID ) );
+ iView = iFilteredView;
+ }
+ }
+
+} // namespace VPbkCntModel
+
+// End of File