emailuis/emailui/src/FreestyleEmailUiCLSMatchObserverInterface.cpp
changeset 0 8466d47a6819
child 26 968773a0b6ef
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Base class for Contact and RMU match observers
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // for PCS support
       
    20 #include "emailtrace.h"
       
    21 #include <CPsQueryItem.h>
       
    22 #include <CPsRequestHandler.h>
       
    23 
       
    24 #include <aknnotewrappers.h>
       
    25 #include <AknFepInternalCRKeys.h>						// KCRUidAknFep, KAknFepPredTxtFlag
       
    26 #include <VPbkEng.rsg>
       
    27 
       
    28 #include "FreestyleEmailUiCLSListsHandler.h"			// CFSEmailUiClsListsHandler
       
    29 #include "FreestyleEMailUiCLSMatchObserverInterface.h"	// CFSEmailUiClsMatchObserver
       
    30 #include "FreestyleEmailUiUtilities.h"
       
    31 #include "FreestyleEmailUiLiterals.h"
       
    32 #include "FreestyleEmailUiCLSItem.h"
       
    33 #include "FreestyleEmailUiAppui.h"
       
    34 #include "FreestyleEmailUiLayoutHandler.h"
       
    35 
       
    36 
       
    37 // ================= MEMBER FUNCTIONS ==========================================
       
    38 
       
    39 CFSEmailUiClsMatchObserver* CFSEmailUiClsMatchObserver::NewL(CRepository& aCr,  
       
    40 		CFSEmailUiClsListsHandler& aListsHandler,
       
    41 		CPSRequestHandler& aRequestHandler,
       
    42 		CVPbkContactManager* aContactManager)
       
    43 	{
       
    44     FUNC_LOG;
       
    45 	CFSEmailUiClsMatchObserver* api = CFSEmailUiClsMatchObserver::NewLC( aCr, aListsHandler,
       
    46 			aRequestHandler, aContactManager );
       
    47 	
       
    48 	CleanupStack::Pop( api );
       
    49 	return api;	
       
    50 	}
       
    51 
       
    52 CFSEmailUiClsMatchObserver* CFSEmailUiClsMatchObserver::NewLC(CRepository& aCr,  
       
    53 		CFSEmailUiClsListsHandler& aListsHandler,
       
    54 		CPSRequestHandler& aRequestHandler,
       
    55 		CVPbkContactManager* aContactManager )
       
    56 	{
       
    57     FUNC_LOG;
       
    58 	CFSEmailUiClsMatchObserver* api = new (ELeave) CFSEmailUiClsMatchObserver( 
       
    59 			aCr, 
       
    60 			aListsHandler,
       
    61 			aRequestHandler,
       
    62 			aContactManager );
       
    63 	
       
    64 	CleanupStack::PushL( api );
       
    65 	api->ConstructL();
       
    66 	return api;	
       
    67 	}
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // CFSEmailUiClsMatchObserver::CFSEmailUiClsMatchObserver
       
    71 // -----------------------------------------------------------------------------
       
    72 CFSEmailUiClsMatchObserver::CFSEmailUiClsMatchObserver(
       
    73  								CRepository& aCr,  
       
    74 								CFSEmailUiClsListsHandler& aListsHandler,
       
    75 								CPSRequestHandler& aRequestHandler,
       
    76 								CVPbkContactManager* aContactManager ) :
       
    77     iRequestHandler( &aRequestHandler ),
       
    78     iAknFepCenRep( aCr ),
       
    79     iListHandler( aListsHandler ),
       
    80     iInputMode( EQwerty ),
       
    81     iContactManager( aContactManager )
       
    82 	{
       
    83     FUNC_LOG;
       
    84 	}
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CFSEmailUiClsMatchObserver::~CFSEmailUiClsMatchObserver
       
    88 // -----------------------------------------------------------------------------
       
    89 CFSEmailUiClsMatchObserver::~CFSEmailUiClsMatchObserver()
       
    90     {
       
    91     FUNC_LOG;
       
    92     delete iQuery;
       
    93     if ( iRequestHandler )
       
    94         {
       
    95         iRequestHandler->RemoveObserver( this );
       
    96         }
       
    97     }
       
    98 
       
    99 void CFSEmailUiClsMatchObserver::ConstructL()
       
   100 	{
       
   101     FUNC_LOG;
       
   102 	iRequestHandler->AddObserverL( this );
       
   103 	iInputMode = GetInputMode();
       
   104 	iQuery = CPsQuery::NewL();
       
   105 	}
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // CFSEmailUiClsMatchObserver::SearchMatchesL
       
   109 // -----------------------------------------------------------------------------
       
   110 void CFSEmailUiClsMatchObserver::SearchMatchesL( const TDesC& aText )
       
   111 	{
       
   112     FUNC_LOG;
       
   113 	
       
   114 	if( iRequestHandler )
       
   115 		{
       
   116 		TInt cacheStatus = CheckCacheStatusL();
       
   117 		if ( !cacheStatus )
       
   118 			{
       
   119 			// Reset query
       
   120 			iQuery->Reset();
       
   121 			
       
   122 			// Create one queryitem for every character in the query string and append it to the query object
       
   123 			// Every queryitem is filled with two fields : 
       
   124 			//	1) a character from the query string 
       
   125 			//	2) the keyboard mode using which the query was entered
       
   126 			
       
   127 			TInt itemCount = aText.Length();
       
   128 			if ( itemCount > 50 )
       
   129 				{
       
   130 				itemCount = 50;
       
   131 				}
       
   132 			for ( TInt i = 0; i < itemCount; i++ )
       
   133 			{    
       
   134 			   // Add a query item
       
   135 			   CPsQueryItem* item = CPsQueryItem::NewL();
       
   136 			   item->SetCharacter(aText[i]);   
       
   137 			   item->SetMode(iInputMode);	 // EItut refers to numeric keypad
       
   138 			                         // Use EQwerty if QWERTY keyboard is used
       
   139 			   iQuery->AppendL(*item);
       
   140 			}
       
   141 
       
   142 			// Initiate a search request
       
   143 			iRequestHandler->SearchL(*iQuery);
       
   144 			}
       
   145 		else //Cache isn't ready
       
   146 			{
       
   147 			iListHandler.OperationErrorL( cacheStatus );
       
   148 			}
       
   149 
       
   150 		}
       
   151 	}
       
   152 
       
   153 // -----------------------------------------------------------------------------
       
   154 // CFSEmailUiClsMatchObserver::SetInputModeL
       
   155 // -----------------------------------------------------------------------------
       
   156 void CFSEmailUiClsMatchObserver::SetInputMode( TKeyboardModes aInputMode )
       
   157 	{
       
   158     FUNC_LOG;
       
   159 	iInputMode = aInputMode;
       
   160 	}
       
   161 
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CFSEmailUiClsMatchObserver::HandleMatchComplete
       
   165 // -----------------------------------------------------------------------------
       
   166 void CFSEmailUiClsMatchObserver::HandlePsResultsUpdate( 
       
   167         RPointerArray<CPsClientData>& aSearchResults,
       
   168         RPointerArray<CPsPattern>& searchSeqs )
       
   169 	{
       
   170     FUNC_LOG;
       
   171 	TRAP_IGNORE( HandlePsResultsUpdateL( aSearchResults, searchSeqs) );
       
   172 	}
       
   173 // -----------------------------------------------------------------------------
       
   174 // CFSEmailUiClsMatchObserver::HandleMatchComplete
       
   175 // -----------------------------------------------------------------------------
       
   176 void CFSEmailUiClsMatchObserver::HandlePsResultsUpdateL( 
       
   177         RPointerArray<CPsClientData>& aSearchResults,
       
   178         RPointerArray<CPsPattern>& aSearchSeqs )
       
   179 	{
       
   180     FUNC_LOG;
       
   181     RPointerArray<CFSEmailUiClsItem> contacts;
       
   182     CleanupResetAndDestroyClosePushL( contacts );
       
   183     CleanupResetAndDestroyClosePushL( aSearchResults );
       
   184     CleanupResetAndDestroyClosePushL( aSearchSeqs );
       
   185     
       
   186     // Iterate through all or maximum number of search results
       
   187     CFreestyleEmailUiAppUi* appUi = 
       
   188         static_cast<CFreestyleEmailUiAppUi*>( CCoeEnv::Static()->AppUi() );
       
   189     TInt maxPcsMatches = appUi->LayoutHandler()->MaxPcsMatches();
       
   190     
       
   191 	for ( TInt counter = 0 ; counter < aSearchResults.Count() && counter < maxPcsMatches ; counter++ )
       
   192 		{
       
   193 		// Get search result
       
   194 		CPsClientData* result = aSearchResults[counter];
       
   195 
       
   196 	    // Get the order of the data fields in result
       
   197 	    RArray<TInt> dataOrder;
       
   198 	    CleanupClosePushL( dataOrder );
       
   199 	    iRequestHandler->GetDataOrderL( *( result->Uri() ), dataOrder );
       
   200 		
       
   201 		TPtrC firstname( KNullDesC );
       
   202 		TPtrC lastname( KNullDesC );
       
   203 		RArray<TPtrC> emailFields;
       
   204 		CleanupClosePushL( emailFields );
       
   205 		// Iterate through all the data fields in the result.
       
   206 		// Collect the result and resolve which fields did match.
       
   207 		// Email fields are collected into array
       
   208 		for ( TInt dataField = 0 ; dataField < dataOrder.Count(); dataField++ )
       
   209 			{
       
   210 			switch ( dataOrder[dataField] )
       
   211 				{
       
   212 				case R_VPBK_FIELD_TYPE_FIRSTNAME:
       
   213 					firstname.Set( *(result->Data(dataField)) );
       
   214 					break;
       
   215 					
       
   216 				case R_VPBK_FIELD_TYPE_LASTNAME:
       
   217 					lastname.Set( *(result->Data(dataField)) );
       
   218 					break;
       
   219 
       
   220 				case R_VPBK_FIELD_TYPE_EMAILGEN:
       
   221 				case R_VPBK_FIELD_TYPE_EMAILHOME:					
       
   222 				case R_VPBK_FIELD_TYPE_EMAILWORK:
       
   223 					{
       
   224 					if ( result->Data( dataField ) )
       
   225 						{
       
   226 						if ( result->Data( dataField )->Length() > 0 )
       
   227 							{
       
   228 							TPtrC email( *result->Data( dataField ) );
       
   229 							ChopEmailEntriesList(email, emailFields);
       
   230 							}
       
   231 						}
       
   232 					}
       
   233 					break;
       
   234 				}
       
   235 			}
       
   236 
       
   237 
       
   238 		
       
   239 		TDesC& sourceUri = *( result->Uri() );
       
   240 		TBool isMruItem = sourceUri.Find( KDefaultMailBoxURI ) != KErrNotFound;
       
   241 
       
   242 		MVPbkContactLink* contactLink = NULL;
       
   243 		
       
   244 		if ( !isMruItem )
       
   245 			{
       
   246 			contactLink = iRequestHandler->ConvertToVpbkLinkLC( *result, *iContactManager );
       
   247 			CleanupStack::Pop( contactLink );
       
   248 			}
       
   249 		
       
   250 		HBufC* displayname;
       
   251 		
       
   252 		// Determine how many contact address to create:
       
   253 		// If there's no email fields, create one item without email address
       
   254 		if ( emailFields.Count() == 0 )
       
   255 			{
       
   256 			
       
   257 			// Use Ps engine to check if the text matches the search query
       
   258 			CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(10);
       
   259 			CleanupStack::PushL( matchSet );
       
   260 			
       
   261 			// Create display name, this will be used in UI.
       
   262 			displayname = TFsEmailUiUtility::CreateDisplayNameLC( firstname, lastname, KNullDesC );
       
   263 			
       
   264 			RArray<TPsMatchLocation> matchLocation;
       
   265 			CleanupClosePushL( matchLocation );
       
   266 			iRequestHandler->LookupL( *iQuery, *displayname, *matchSet, matchLocation );
       
   267 			
       
   268 			// Create contact item and set highlighting for it
       
   269 			CFSEmailUiClsItem* contactItem = CFSEmailUiClsItem::NewLC();
       
   270 			contactItem->SetDisplayNameL( *displayname );
       
   271 			contactItem->SetHighlights( matchLocation );
       
   272 			if ( contactLink )
       
   273 				{
       
   274 				contactItem->SetContactLinkL( *contactLink );
       
   275 				}
       
   276 			contactItem->SetIsMruItem( isMruItem );
       
   277 			contacts.AppendL( contactItem );
       
   278 			CleanupStack::Pop( contactItem );
       
   279 			
       
   280 			CleanupStack::Pop( &matchLocation );
       
   281 			matchLocation.Close();
       
   282 			CleanupStack::PopAndDestroy( displayname );	
       
   283 			CleanupStack::PopAndDestroy( matchSet );
       
   284 			
       
   285 			}
       
   286 		else
       
   287 			{
       
   288 			// Iterate through all the email fields, check if they match the search criteria and
       
   289 			// create new contact item for each one that matches
       
   290 			for ( TInt fieldIndex = 0; fieldIndex < emailFields.Count(); fieldIndex++ )
       
   291 				{
       
   292 				
       
   293 				// Create display name, this will be used in UI. If the
       
   294 				// contact does not contain either firstname nor lastname,
       
   295 				// the displayname is left empty.
       
   296 				displayname = TFsEmailUiUtility::CreateDisplayNameLC(
       
   297 					firstname, lastname );
       
   298 				
       
   299 				// Create match text field, containing display field and email address
       
   300 				HBufC* matchText = HBufC::NewLC( displayname->Length() +
       
   301 								KSpace().Length() +
       
   302 								emailFields[fieldIndex].Length() );
       
   303 				
       
   304 				//This condition is for checking if there is no display name like in the case of MRU and therefore 
       
   305                 //we dont need to add displayname + KSpace(unnnecessary space) which is causing problem in drawing Underline
       
   306 				if (displayname->Length() > 0)
       
   307 				    {
       
   308 
       
   309 				matchText->Des().Copy( *displayname );
       
   310 				matchText->Des().Append( KSpace );
       
   311 
       
   312 				    }
       
   313 				
       
   314 				matchText->Des().Append( emailFields[fieldIndex] );
       
   315 				
       
   316 
       
   317 				// Use Ps engine to check if the text matches the search query
       
   318 				CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(10);
       
   319 				CleanupStack::PushL( matchSet );
       
   320 				
       
   321 				RArray<TPsMatchLocation> matchLocation;
       
   322 				CleanupClosePushL( matchLocation );
       
   323 				iRequestHandler->LookupL( *iQuery, *matchText, *matchSet, matchLocation );
       
   324 				
       
   325 				if ( matchLocation.Count() > 0 )
       
   326 					{
       
   327 					// Create contact item and set highlighting for it
       
   328 					CFSEmailUiClsItem* contactItem = CFSEmailUiClsItem::NewLC();
       
   329 					contactItem->SetDisplayNameL( *displayname );
       
   330 					contactItem->SetIsMruItem( isMruItem );
       
   331 					contactItem->SetEmailAddressL( emailFields[fieldIndex] );
       
   332 					contactItem->SetHighlights( matchLocation );
       
   333 					if ( contactLink )
       
   334 						{
       
   335 						contactItem->SetContactLinkL( *contactLink );
       
   336 						}
       
   337 					if ( emailFields.Count() > 1 )
       
   338 						{
       
   339 						contactItem->SetMultipleEmails( ETrue );
       
   340 						}
       
   341 					contacts.AppendL( contactItem );	
       
   342 					CleanupStack::Pop( contactItem );					
       
   343 					}
       
   344 				
       
   345 				CleanupStack::PopAndDestroy( &matchLocation );
       
   346 				CleanupStack::PopAndDestroy( matchSet );
       
   347 				CleanupStack::PopAndDestroy( matchText );
       
   348 				CleanupStack::PopAndDestroy( displayname ); 		
       
   349 				}
       
   350 			}
       
   351 		
       
   352 		if ( !isMruItem )
       
   353 			{
       
   354 			delete contactLink;
       
   355 			}
       
   356 		
       
   357 		// Close arrays
       
   358 		CleanupStack::PopAndDestroy( &emailFields );
       
   359         CleanupStack::PopAndDestroy( &dataOrder );
       
   360 		}
       
   361 
       
   362 	iListHandler.UpdateContactMatchListsL( contacts );
       
   363 	CleanupStack::PopAndDestroy( &aSearchSeqs );
       
   364 	CleanupStack::PopAndDestroy( &aSearchResults );
       
   365 	CleanupStack::PopAndDestroy( &contacts );
       
   366 	}
       
   367 
       
   368 void CFSEmailUiClsMatchObserver::HandlePsError(TInt aErrorCode)
       
   369 	{
       
   370     FUNC_LOG;
       
   371 	TRAP_IGNORE( iListHandler.OperationErrorL( aErrorCode ) );
       
   372 	}
       
   373 
       
   374 void CFSEmailUiClsMatchObserver::CachingStatus( TCachingStatus& aStatus,
       
   375     TInt& /*aError*/ )
       
   376 	{
       
   377     FUNC_LOG;
       
   378 	TInt err = KErrNone;
       
   379 	switch ( aStatus )
       
   380 		{
       
   381 		case ECachingComplete:
       
   382 			err = KErrNone;
       
   383 			break;
       
   384 		case ECachingNotStarted:
       
   385 			err = KErrNotFound;
       
   386 			break;
       
   387 		case ECachingInProgress:
       
   388 			err = KErrNotReady;
       
   389 			break;
       
   390 		case ECachingCompleteWithErrors:
       
   391 			err = KErrCorrupt;
       
   392 			break;
       
   393 		default:
       
   394 			break;
       
   395 		}
       
   396 	
       
   397 	TRAP_IGNORE( iListHandler.OperationErrorL( err ) );
       
   398 	}
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // CFSEmailUiClsMatchObserver::IsCurrentInputModePredictive
       
   402 // -----------------------------------------------------------------------------
       
   403 TKeyboardModes CFSEmailUiClsMatchObserver::GetInputMode()
       
   404 	{
       
   405     FUNC_LOG;
       
   406 	TInt repVal = 0;
       
   407 	// 1 = predictive, 0 = non predictive
       
   408 	iAknFepCenRep.Get( KAknFepPredTxtFlag, repVal );
       
   409 	
       
   410 	//If true, EItut (predictive)
       
   411 	if( repVal == 0 )
       
   412 		{
       
   413 		return EQwerty;
       
   414 		}
       
   415 	return EItut;
       
   416 	}
       
   417 
       
   418 TInt CFSEmailUiClsMatchObserver::CheckCacheStatusL()
       
   419 	{
       
   420     FUNC_LOG;
       
   421 	// Get the caching status synchronously
       
   422 	// 'status' has the caching status
       
   423 	// 'err' has KErrNone or any caching errors
       
   424 	TCachingStatus status;
       
   425 	TInt err = iRequestHandler->GetCachingStatusL(status);
       
   426 	
       
   427 	switch (status)
       
   428 		{
       
   429 		case ECachingComplete:
       
   430 			return KErrNone;
       
   431 		case ECachingNotStarted:
       
   432 			return KErrNotFound;
       
   433 		case ECachingInProgress:
       
   434 			return KErrNotReady;
       
   435 		case ECachingCompleteWithErrors:
       
   436 			return KErrCorrupt;
       
   437 		default:
       
   438 			break;
       
   439 		}
       
   440 
       
   441 	return EFalse;
       
   442 	
       
   443 	}
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 // CFSEmailUiClsMatchObserver::ChopEmailEntriesList
       
   447 // -----------------------------------------------------------------------------
       
   448 void CFSEmailUiClsMatchObserver::ChopEmailEntriesList(TPtrC & aEmail, RArray<
       
   449 		TPtrC> & aEmailFields)
       
   450 	{
       
   451 	FUNC_LOG;
       
   452 	const TInt KUnitSeparator = 31;
       
   453 	TInt prevSeparatorIndex = 0;
       
   454 	TInt nextSeparatorIndex = aEmail.Locate( KUnitSeparator );
       
   455 	// check if there are more than one email entry
       
   456 	if ( nextSeparatorIndex == KErrNotFound )
       
   457 		{
       
   458 		aEmailFields.Append( aEmail ); //one entry only
       
   459 		}
       
   460 	else //more then one entry
       
   461 		{
       
   462 		// loop through all but last email entries 
       
   463 		while ( nextSeparatorIndex != KErrNotFound )
       
   464 			{
       
   465 			// First entry needs a separate handling
       
   466 			if ( prevSeparatorIndex == 0 )
       
   467 				{
       
   468 				// -1 because there is a space before a separator character
       
   469 				TPtrC entry = aEmail.Mid( 0, nextSeparatorIndex - 1 ); 
       
   470 				aEmailFields.Append( entry );
       
   471 				}
       
   472 			else //Append the next entry
       
   473 				{ 
       
   474 				nextSeparatorIndex = nextSeparatorIndex + 1 + prevSeparatorIndex;				
       
   475 				TInt length = nextSeparatorIndex - prevSeparatorIndex - 1;
       
   476 				// +2 and -2 because there are a spaces before and after a separator character
       
   477 				TPtrC entry = aEmail.Mid(prevSeparatorIndex + 2, //starting pos
       
   478 						length - 2); //length 
       
   479 				aEmailFields.Append(entry);
       
   480 				}
       
   481 			// Take the part of the list skiping the entries already appended    
       
   482 			TPtrC nextEntry = aEmail.Mid(nextSeparatorIndex + 1); 
       
   483 			prevSeparatorIndex = nextSeparatorIndex;
       
   484 			nextSeparatorIndex = nextEntry.Locate(KUnitSeparator);
       
   485 			}
       
   486 		// the last element does not contain the separator so it needs to be taken here
       
   487 		if (nextSeparatorIndex == KErrNotFound && aEmail.Mid(prevSeparatorIndex + 1).Length() > 1)
       
   488 			{
       
   489 			aEmailFields.Append(aEmail.Mid(prevSeparatorIndex + 2));
       
   490 			}
       
   491 		}
       
   492 	}