--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrclsmatchobserver.cpp Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,533 @@
+/*
+* Copyright (c) 2009 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: Base class for Contact and RMU match observers
+ *
+*/
+
+
+#include "emailtrace.h"
+#include "cesmrclsmatchobserver.h"
+#include "cesmrclslistshandler.h"
+#include "esmrfieldbuilderdef.h"
+
+// for PCS support
+#include <CPsRequestHandler.h>
+#include <CPsSettings.h>
+#include <CPsQuery.h>
+#include <CPsQueryItem.h>
+#include <CPcsDefs.h>
+#include <MVPbkContactLink.h>
+#include <CVPbkContactManager.h>
+#include <aknnotewrappers.h>
+#include <centralrepository.h> // CRepository
+#include <AknFepInternalCRKeys.h> // KCRUidAknFep, KAknFepPredTxtFlag
+#include <VPbkEng.rsg>
+
+//Constants
+
+// Unnamed namespace for local definitions
+namespace{ // codescanner::namespace
+
+const TInt KMatchLen = 10;
+
+template<typename T> class CleanupResetAndDestroyClose
+ {
+public:
+ inline static void PushL( T& aRef );
+private:
+ static void Close( TAny *aPtr );
+ };
+
+template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef );
+
+template<typename T> inline void CleanupResetAndDestroyClose<T>::PushL( T& aRef )
+ {
+ CleanupStack::PushL( TCleanupItem( &Close, &aRef ) );
+ }
+
+template<typename T> void CleanupResetAndDestroyClose<T>::Close( TAny *aPtr )
+ {
+ static_cast<T*>(aPtr)->ResetAndDestroy();
+ static_cast<T*>(aPtr)->Close();
+ }
+
+template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef )
+ {
+ CleanupResetAndDestroyClose<T>::PushL( aRef );
+ }
+
+}//namespace
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::NewL
+// -----------------------------------------------------------------------------
+//
+CESMRClsMatchObserver* CESMRClsMatchObserver::NewL(CRepository& aCr,
+ CESMRClsListsHandler& aListsHandler,
+ CPSRequestHandler& aRequestHandler,
+ CVPbkContactManager* aContactManager)
+ {
+ FUNC_LOG;
+ CESMRClsMatchObserver* api = CESMRClsMatchObserver::NewLC( aCr, aListsHandler,
+ aRequestHandler, aContactManager );
+
+ CleanupStack::Pop( api );
+ return api;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::NewLC
+// -----------------------------------------------------------------------------
+//
+CESMRClsMatchObserver* CESMRClsMatchObserver::NewLC(CRepository& aCr,
+ CESMRClsListsHandler& aListsHandler,
+ CPSRequestHandler& aRequestHandler,
+ CVPbkContactManager* aContactManager )
+ {
+ FUNC_LOG;
+ CESMRClsMatchObserver* api = new (ELeave) CESMRClsMatchObserver(
+ aCr,
+ aListsHandler,
+ aRequestHandler,
+ aContactManager );
+
+ CleanupStack::PushL( api );
+ api->ConstructL();
+ return api;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::CESMRClsMatchObserver
+// -----------------------------------------------------------------------------
+//
+CESMRClsMatchObserver::CESMRClsMatchObserver(
+ CRepository& aCr,
+ CESMRClsListsHandler& aListsHandler,
+ CPSRequestHandler& aRequestHandler,
+ CVPbkContactManager* aContactManager ) :
+ iRequestHandler( &aRequestHandler ),
+ iAknFepCenRep( aCr ),
+ iListHandler( aListsHandler ),
+ iInputMode(EQwerty),
+ iContactManager( aContactManager )
+ {
+ FUNC_LOG;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::~CESMRClsMatchObserver
+// -----------------------------------------------------------------------------
+//
+CESMRClsMatchObserver::~CESMRClsMatchObserver()
+ {
+ FUNC_LOG;
+ delete iQuery;
+ if(iRequestHandler)
+ {
+ iRequestHandler->RemoveObserver(this);
+ }
+ }
+
+void CESMRClsMatchObserver::ConstructL()
+ {
+ FUNC_LOG;
+ iRequestHandler->AddObserverL( this );
+ iInputMode = GetInputMode();
+ iQuery = CPsQuery::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::SearchMatchesL
+// -----------------------------------------------------------------------------
+//
+void CESMRClsMatchObserver::SearchMatchesL( const TDesC& aText )
+ {
+ FUNC_LOG;
+ if( iRequestHandler )
+ {
+ TInt cacheStatus = CheckCacheStatusL();
+ if ( !cacheStatus )
+ {
+ // Reset query
+ iQuery->Reset();
+
+ // Create one queryitem for every character in the query string and append it to the query object
+ // Every queryitem is filled with two fields :
+ // 1) a character from the query string
+ // 2) the keyboard mode using which the query was entered
+
+ TInt itemCount = aText.Length();
+
+ for ( TInt i = 0; i < itemCount; i++ )
+ {
+ // Add a query item
+ CPsQueryItem* item = CPsQueryItem::NewL();
+ item->SetCharacter(aText[i]);
+ item->SetMode(iInputMode); // EItut refers to numeric keypad
+ // Use EQwerty if QWERTY keyboard is used
+ iQuery->AppendL(*item);
+ }
+
+ // Initiate a search request
+ iRequestHandler->SearchL(*iQuery);
+ }
+ else //Cache isn't ready
+ {
+ iListHandler.OperationErrorL( cacheStatus );
+ }
+
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::SetInputModeL
+// -----------------------------------------------------------------------------
+//
+void CESMRClsMatchObserver::SetInputMode( TKeyboardModes aInputMode )
+ {
+ FUNC_LOG;
+ iInputMode = aInputMode;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::HandleMatchComplete
+// -----------------------------------------------------------------------------
+//
+void CESMRClsMatchObserver::HandlePsResultsUpdate(
+ RPointerArray<CPsClientData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
+ {
+ FUNC_LOG;
+ TRAP_IGNORE( HandlePsResultsUpdateL( searchResults, searchSeqs) );
+ }
+
+void CESMRClsMatchObserver::HandlePsError(TInt aErrorCode)
+ {
+ FUNC_LOG;
+ TRAP_IGNORE( iListHandler.OperationErrorL( aErrorCode ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::CachingStatus
+// -----------------------------------------------------------------------------
+//
+void CESMRClsMatchObserver::CachingStatus(
+ TCachingStatus& aStatus, TInt& /*aError*/)
+ {
+ FUNC_LOG;
+ TInt err = KErrNone;
+ switch ( aStatus )
+ {
+ case ECachingComplete:
+ err = KErrNone;
+ break;
+ case ECachingNotStarted:
+ err = KErrNotFound;
+ break;
+ case ECachingInProgress:
+ err = KErrNotReady;
+ break;
+ case ECachingCompleteWithErrors:
+ err = KErrCorrupt;
+ break;
+ default:
+ break;
+ }
+
+ TRAP_IGNORE( iListHandler.OperationErrorL( err ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::IsCurrentInputModePredictive
+// -----------------------------------------------------------------------------
+//
+TKeyboardModes CESMRClsMatchObserver::GetInputMode()
+ {
+ FUNC_LOG;
+ TInt repVal = 0;
+ // 1 = predictive, 0 = non predictive
+ iAknFepCenRep.Get( KAknFepPredTxtFlag, repVal );
+
+ //If true, EItut (predictive)
+ if( repVal == 1 )
+ {
+ return EItut;
+ }
+ return EQwerty;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::CheckCacheStatusL
+// -----------------------------------------------------------------------------
+//
+TBool CESMRClsMatchObserver::CheckCacheStatusL()
+ {
+ FUNC_LOG;
+ // Get the caching status synchronously
+ // 'status' has the caching status
+ // 'err' has KErrNone or any caching errors
+ TCachingStatus status;
+ TInt err = iRequestHandler->GetCachingStatusL(status);
+
+ switch (status)
+ {
+ case ECachingComplete:
+ return KErrNone;
+ case ECachingNotStarted:
+ return KErrNotFound;
+ case ECachingInProgress:
+ return KErrNotReady;
+ case ECachingCompleteWithErrors:
+ return KErrCorrupt;
+ default:
+ break;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::CreateDisplayNameLC
+// -----------------------------------------------------------------------------
+//
+HBufC* CESMRClsMatchObserver::CreateDisplayNameLC( const TDesC& aFirstname, const TDesC& aLastname, const TDesC& aEmailField )
+ {
+ FUNC_LOG;
+ HBufC* displayname;
+ if ( aFirstname.Length() == 0)
+ {
+ if ( aLastname.Length() == 0 )
+ {
+ //There's just the email address for Displayname
+ displayname = HBufC::NewLC( aEmailField.Length() );
+ displayname->Des().Copy( aEmailField );
+ }
+ else
+ {
+ //Lastname = displayname
+ displayname = HBufC::NewLC( aLastname.Length() );
+ displayname->Des().Copy( aLastname );
+ }
+ }
+
+ else if ( aLastname.Length() == 0 )
+ {
+ //Firstname = displayname
+ displayname = HBufC::NewLC( aFirstname.Length() );
+ displayname->Des().Copy( aFirstname );
+ }
+
+ else
+ {
+ //Displayname = firstname + " " + lastname
+ displayname = HBufC::NewLC( aFirstname.Length() +
+ 1 +
+ aLastname.Length() );
+ displayname->Des().Copy( aFirstname );
+ displayname->Des().Append( KEmptySpace );
+ displayname->Des().Append( aLastname );
+ }
+ return displayname;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRClsMatchObserver::HandlePsResultsUpdateL
+// -----------------------------------------------------------------------------
+//
+void CESMRClsMatchObserver::HandlePsResultsUpdateL(
+ RPointerArray<CPsClientData>& searchResults,
+ RPointerArray<CPsPattern>& searchSeqs)
+ {
+ FUNC_LOG;
+ RPointerArray<CESMRClsItem> contacts;
+ CleanupResetAndDestroyClosePushL( contacts );
+ CleanupResetAndDestroyClosePushL( searchResults );
+ CleanupResetAndDestroyClosePushL( searchSeqs );
+
+ // Iterate through all the search results
+ for( TInt counter = 0 ; counter < searchResults.Count(); counter++ )
+ {
+ // Get search result
+ CPsClientData* result = searchResults[counter];
+
+ // Get the order of the data fields in result
+ RArray<TInt> dataOrder;
+ CleanupClosePushL( dataOrder );
+ iRequestHandler->GetDataOrderL( *( result->Uri() ), dataOrder );
+
+ HBufC* firstname = HBufC::NewLC( KMaxTextLength );
+ HBufC* lastname = HBufC::NewLC( KMaxTextLength );
+ RPointerArray<HBufC> emailFields;
+ CleanupResetAndDestroyClosePushL( emailFields );
+ // Iterate through all the data fields in the result.
+ // Collect the result and resolve which fields did match.
+ // Email fields are collected into array
+ for( TInt dataField = 0 ; dataField < dataOrder.Count(); dataField++ )
+ {
+ switch( dataOrder[dataField] )
+ {
+ case R_VPBK_FIELD_TYPE_FIRSTNAME:
+ firstname->Des().Append( *(result->Data(dataField)) );
+ break;
+
+ case R_VPBK_FIELD_TYPE_LASTNAME:
+ lastname->Des().Append( *(result->Data(dataField)) );
+ break;
+
+ case R_VPBK_FIELD_TYPE_EMAILGEN:
+ case R_VPBK_FIELD_TYPE_EMAILHOME:
+ case R_VPBK_FIELD_TYPE_EMAILWORK:
+ {
+ if( result->Data( dataField ) )
+ {
+ if( (*(result->Data( dataField ))).Length() > 0 )
+ {
+ HBufC* email = HBufC::NewLC( KMaxTextLength );
+ email->Des().Append( *(result->Data( dataField )) );
+ emailFields.Append( email );
+ CleanupStack::Pop( email );
+ }
+ }
+ }
+ break;
+ }
+ }
+
+
+
+ TDesC& sourceUri = *( result->Uri() );
+ TBool isMruItem = sourceUri.Find( KDefaultMailBoxURI ) != KErrNotFound;
+
+ MVPbkContactLink* contactLink = NULL;
+
+ if( !isMruItem )
+ {
+ contactLink = iRequestHandler->ConvertToVpbkLinkLC( *result, *iContactManager );
+ CleanupStack::Pop();
+ // Push M-pointer to contactLink into CleanupStack for proper cleanup
+ CleanupDeletePushL( contactLink );
+ }
+
+ // Determine how many contact address to create:
+ // If there's no email fields, create one item without email address
+ if ( emailFields.Count() == 0 )
+ {
+
+ // Use Ps engine to check if the text matches the search query
+ CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(KMatchLen);
+ CleanupStack::PushL( matchSet );
+
+ // Create display name, this will be used in UI.
+ HBufC* displayname = CreateDisplayNameLC( *firstname, *lastname, KNullDesC );
+
+ RArray<TPsMatchLocation> matchLocation;
+ CleanupClosePushL( matchLocation );
+ iRequestHandler->LookupL( *iQuery, *displayname, *matchSet, matchLocation );
+
+ // Create contact item and set highlighting for it
+ CESMRClsItem* contactItem = CESMRClsItem::NewLC();
+ contactItem->SetDisplayNameL( *displayname );
+ contactItem->SetHighlightsL( matchLocation );
+ if ( contactLink )
+ {
+ contactItem->SetContactLinkL( *contactLink );
+ }
+ contactItem->SetIsMruItem( isMruItem );
+ contacts.AppendL( contactItem );
+ CleanupStack::Pop( contactItem );
+
+ CleanupStack::Pop( &matchLocation );
+ matchLocation.Close();
+ CleanupStack::PopAndDestroy( displayname );
+ CleanupStack::PopAndDestroy( matchSet );
+
+ }
+ else
+ {
+ // Iterate through all the email fields, check if they match the search criteria and
+ // create new contact item for each one that matches
+ for(TInt fieldIndex = 0; fieldIndex < emailFields.Count(); ++fieldIndex )
+ {
+
+ // Create display name, this will be used in UI.
+ HBufC* displayname = CreateDisplayNameLC( *firstname,
+ *lastname,
+ *emailFields[fieldIndex] );
+
+ // Create match text field, containing display field and email address
+ HBufC* matchText = HBufC::NewLC( displayname->Des().Length() +
+ 1 +
+ emailFields[fieldIndex]->Des().Length() );
+
+ matchText->Des().Copy( *displayname );
+ matchText->Des().Append( KEmptySpace );
+ matchText->Des().Append( *emailFields[fieldIndex] );
+
+ // Use Ps engine to check if the text matches the search query
+ CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(KMatchLen);
+ CleanupStack::PushL( matchSet );
+
+ RArray<TPsMatchLocation> matchLocation;
+ iRequestHandler->LookupL( *iQuery, *matchText, *matchSet, matchLocation );
+ CleanupClosePushL( matchLocation );
+
+ if( matchLocation.Count() > 0 )
+ {
+ // Create contact item and set highlighting for it
+ CESMRClsItem* contactItem = CESMRClsItem::NewLC();
+ contactItem->SetDisplayNameL( *displayname );
+ contactItem->SetIsMruItem( isMruItem );
+ contactItem->SetEmailAddressL( *emailFields[fieldIndex] );
+ contactItem->SetHighlightsL(matchLocation);
+ if ( contactLink )
+ {
+ contactItem->SetContactLinkL( *contactLink );
+ }
+ if ( emailFields.Count() > 1 )
+ {
+ contactItem->SetMultipleEmails( );
+ }
+ contacts.AppendL( contactItem );
+ CleanupStack::Pop( contactItem );
+ }
+
+ CleanupStack::PopAndDestroy( &matchLocation );
+ CleanupStack::PopAndDestroy( matchSet );
+ CleanupStack::PopAndDestroy( matchText );
+ CleanupStack::PopAndDestroy( displayname );
+ }
+ }
+
+ if ( contactLink )
+ {
+ CleanupStack::PopAndDestroy(); //codescanner::cleanup
+ }
+
+ // De-allocate name fields, first & last name
+ CleanupStack::PopAndDestroy( &emailFields );
+ CleanupStack::PopAndDestroy( lastname );
+ CleanupStack::PopAndDestroy( firstname );
+ CleanupStack::PopAndDestroy( &dataOrder );
+ }
+
+ iListHandler.UpdateContactMatchListsL(contacts);
+ CleanupStack::PopAndDestroy( &searchSeqs );
+ CleanupStack::PopAndDestroy( &searchResults );
+ CleanupStack::PopAndDestroy( &contacts );
+ }
+
+//EOF
+