meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrclsmatchobserver.cpp
changeset 0 8466d47a6819
child 16 4ce476e64c59
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2007-2009 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 #include "emailtrace.h"
       
    20 #include "cesmrclsmatchobserver.h"
       
    21 #include "cesmrclslistshandler.h"
       
    22 #include "esmrfieldbuilderdef.h"
       
    23 
       
    24 // for PCS support
       
    25 #include <CPsRequestHandler.h>
       
    26 #include <CPsSettings.h>
       
    27 #include <CPsQuery.h>
       
    28 #include <CPsQueryItem.h>
       
    29 #include <CPcsDefs.h>
       
    30 #include <MVPbkContactLink.h>
       
    31 #include <CVPbkContactManager.h>
       
    32 #include <aknnotewrappers.h>
       
    33 #include <centralrepository.h>                          // CRepository
       
    34 #include <AknFepInternalCRKeys.h>                       // KCRUidAknFep, KAknFepPredTxtFlag
       
    35 #include <VPbkEng.rsg>
       
    36 
       
    37 //Constants
       
    38 
       
    39 // Unnamed namespace for local definitions
       
    40 namespace{ // codescanner::namespace
       
    41 
       
    42 const TInt KMatchLen = 10;
       
    43 
       
    44 template<typename T> class CleanupResetAndDestroyClose
       
    45     {
       
    46 public:
       
    47     inline static void PushL( T& aRef );
       
    48 private:
       
    49     static void Close( TAny *aPtr );
       
    50     };
       
    51 
       
    52 template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef );
       
    53 
       
    54 template<typename T> inline void CleanupResetAndDestroyClose<T>::PushL( T& aRef )
       
    55     {
       
    56     CleanupStack::PushL( TCleanupItem( &Close, &aRef ) );
       
    57     }
       
    58 
       
    59 template<typename T> void CleanupResetAndDestroyClose<T>::Close( TAny *aPtr )
       
    60     {
       
    61     static_cast<T*>(aPtr)->ResetAndDestroy();
       
    62     static_cast<T*>(aPtr)->Close();
       
    63     }
       
    64 
       
    65 template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef )
       
    66     {
       
    67     CleanupResetAndDestroyClose<T>::PushL( aRef );
       
    68     }
       
    69 
       
    70 }//namespace
       
    71 
       
    72 // ======== MEMBER FUNCTIONS ========
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CESMRClsMatchObserver::NewL
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CESMRClsMatchObserver* CESMRClsMatchObserver::NewL(CRepository& aCr,
       
    79         CESMRClsListsHandler& aListsHandler,
       
    80         CPSRequestHandler& aRequestHandler,
       
    81         CVPbkContactManager* aContactManager)
       
    82     {
       
    83     FUNC_LOG;
       
    84     CESMRClsMatchObserver* api = CESMRClsMatchObserver::NewLC( aCr, aListsHandler,
       
    85             aRequestHandler, aContactManager );
       
    86 
       
    87     CleanupStack::Pop( api );
       
    88     return api;
       
    89     }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // CESMRClsMatchObserver::NewLC
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 CESMRClsMatchObserver* CESMRClsMatchObserver::NewLC(CRepository& aCr,
       
    96         CESMRClsListsHandler& aListsHandler,
       
    97         CPSRequestHandler& aRequestHandler,
       
    98         CVPbkContactManager* aContactManager )
       
    99     {
       
   100     FUNC_LOG;
       
   101     CESMRClsMatchObserver* api = new (ELeave) CESMRClsMatchObserver(
       
   102             aCr,
       
   103             aListsHandler,
       
   104             aRequestHandler,
       
   105             aContactManager );
       
   106 
       
   107     CleanupStack::PushL( api );
       
   108     api->ConstructL();
       
   109     return api;
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CESMRClsMatchObserver::CESMRClsMatchObserver
       
   114 // -----------------------------------------------------------------------------
       
   115 //
       
   116 CESMRClsMatchObserver::CESMRClsMatchObserver(
       
   117                                 CRepository& aCr,
       
   118                                 CESMRClsListsHandler& aListsHandler,
       
   119                                 CPSRequestHandler& aRequestHandler,
       
   120                                 CVPbkContactManager* aContactManager ) :
       
   121     iRequestHandler( &aRequestHandler ),
       
   122     iAknFepCenRep( aCr ),
       
   123     iListHandler( aListsHandler ),
       
   124     iInputMode(EQwerty),
       
   125     iContactManager( aContactManager )
       
   126     {
       
   127     FUNC_LOG;
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CESMRClsMatchObserver::~CESMRClsMatchObserver
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 CESMRClsMatchObserver::~CESMRClsMatchObserver()
       
   135     {
       
   136     FUNC_LOG;
       
   137     delete iQuery;
       
   138     if(iRequestHandler)
       
   139         {
       
   140         iRequestHandler->RemoveObserver(this);
       
   141         }
       
   142     }
       
   143 
       
   144 void CESMRClsMatchObserver::ConstructL()
       
   145     {
       
   146     FUNC_LOG;
       
   147     iRequestHandler->AddObserverL( this );
       
   148     iInputMode = GetInputMode();
       
   149     iQuery = CPsQuery::NewL();
       
   150     }
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CESMRClsMatchObserver::SearchMatchesL
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CESMRClsMatchObserver::SearchMatchesL( const TDesC& aText )
       
   157     {
       
   158     FUNC_LOG;
       
   159     if( iRequestHandler )
       
   160         {
       
   161         TInt cacheStatus = CheckCacheStatusL();
       
   162         if ( !cacheStatus )
       
   163             {
       
   164             // Reset query
       
   165             iQuery->Reset();
       
   166 
       
   167             // Create one queryitem for every character in the query string and append it to the query object
       
   168             // Every queryitem is filled with two fields :
       
   169             //  1) a character from the query string
       
   170             //  2) the keyboard mode using which the query was entered
       
   171 
       
   172             TInt itemCount = aText.Length();
       
   173             
       
   174             for ( TInt i = 0; i < itemCount; i++ )
       
   175             {
       
   176                // Add a query item
       
   177                CPsQueryItem* item = CPsQueryItem::NewL();
       
   178                item->SetCharacter(aText[i]);
       
   179                item->SetMode(iInputMode);    // EItut refers to numeric keypad
       
   180                                      // Use EQwerty if QWERTY keyboard is used
       
   181                iQuery->AppendL(*item);
       
   182             }
       
   183 
       
   184             // Initiate a search request
       
   185             iRequestHandler->SearchL(*iQuery);
       
   186             }
       
   187         else //Cache isn't ready
       
   188             {
       
   189             iListHandler.OperationErrorL( cacheStatus );
       
   190             }
       
   191 
       
   192         }
       
   193     }
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 // CESMRClsMatchObserver::SetInputModeL
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 void CESMRClsMatchObserver::SetInputMode( TKeyboardModes aInputMode )
       
   200     {
       
   201     FUNC_LOG;
       
   202     iInputMode = aInputMode;
       
   203     }
       
   204 
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CESMRClsMatchObserver::HandleMatchComplete
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 void CESMRClsMatchObserver::HandlePsResultsUpdate(
       
   211         RPointerArray<CPsClientData>& searchResults,
       
   212         RPointerArray<CPsPattern>& searchSeqs)
       
   213     {
       
   214     FUNC_LOG;
       
   215     TRAP_IGNORE( HandlePsResultsUpdateL( searchResults, searchSeqs) );
       
   216     }
       
   217 
       
   218 void CESMRClsMatchObserver::HandlePsError(TInt aErrorCode)
       
   219     {
       
   220     FUNC_LOG;
       
   221     TRAP_IGNORE( iListHandler.OperationErrorL( aErrorCode ) );
       
   222     }
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 // CESMRClsMatchObserver::CachingStatus
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 void CESMRClsMatchObserver::CachingStatus(
       
   229         TCachingStatus& aStatus, TInt& /*aError*/)
       
   230     {
       
   231     FUNC_LOG;
       
   232     TInt err = KErrNone;
       
   233     switch ( aStatus )
       
   234         {
       
   235         case ECachingComplete:
       
   236             err = KErrNone;
       
   237             break;
       
   238         case ECachingNotStarted:
       
   239             err = KErrNotFound;
       
   240             break;
       
   241         case ECachingInProgress:
       
   242             err = KErrNotReady;
       
   243             break;
       
   244         case ECachingCompleteWithErrors:
       
   245             err = KErrCorrupt;
       
   246             break;
       
   247         default:
       
   248             break;
       
   249         }
       
   250 
       
   251     TRAP_IGNORE( iListHandler.OperationErrorL( err ) );
       
   252     }
       
   253 
       
   254 // -----------------------------------------------------------------------------
       
   255 // CESMRClsMatchObserver::IsCurrentInputModePredictive
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 TKeyboardModes CESMRClsMatchObserver::GetInputMode()
       
   259     {
       
   260     FUNC_LOG;
       
   261     TInt repVal = 0;
       
   262     // 1 = predictive, 0 = non predictive
       
   263     iAknFepCenRep.Get( KAknFepPredTxtFlag, repVal );
       
   264 
       
   265     //If true, EItut (predictive)
       
   266     if( repVal == 1 )
       
   267         {
       
   268         return EItut;
       
   269         }
       
   270     return EQwerty;
       
   271     }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CESMRClsMatchObserver::CheckCacheStatusL
       
   275 // -----------------------------------------------------------------------------
       
   276 //
       
   277 TBool CESMRClsMatchObserver::CheckCacheStatusL()
       
   278     {
       
   279     FUNC_LOG;
       
   280     // Get the caching status synchronously
       
   281     // 'status' has the caching status
       
   282     // 'err' has KErrNone or any caching errors
       
   283     TCachingStatus status;
       
   284     TInt err = iRequestHandler->GetCachingStatusL(status);
       
   285 
       
   286     switch (status)
       
   287         {
       
   288         case ECachingComplete:
       
   289             return KErrNone;
       
   290         case ECachingNotStarted:
       
   291             return KErrNotFound;
       
   292         case ECachingInProgress:
       
   293             return KErrNotReady;
       
   294         case ECachingCompleteWithErrors:
       
   295             return KErrCorrupt;
       
   296         default:
       
   297             break;
       
   298         }
       
   299     return EFalse;
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CESMRClsMatchObserver::CreateDisplayNameLC
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 HBufC* CESMRClsMatchObserver::CreateDisplayNameLC( const TDesC& aFirstname, const TDesC& aLastname, const TDesC& aEmailField )
       
   307     {
       
   308     FUNC_LOG;
       
   309     HBufC* displayname;
       
   310     if ( aFirstname.Length() == 0)
       
   311         {
       
   312         if ( aLastname.Length() == 0 )
       
   313             {
       
   314             //There's just the email address for Displayname
       
   315             displayname = HBufC::NewLC( aEmailField.Length() );
       
   316             displayname->Des().Copy( aEmailField );
       
   317             }
       
   318         else
       
   319             {
       
   320             //Lastname = displayname
       
   321             displayname = HBufC::NewLC( aLastname.Length() );
       
   322             displayname->Des().Copy( aLastname );
       
   323             }
       
   324         }
       
   325 
       
   326     else if ( aLastname.Length() == 0 )
       
   327         {
       
   328         //Firstname = displayname
       
   329         displayname = HBufC::NewLC( aFirstname.Length() );
       
   330         displayname->Des().Copy( aFirstname );
       
   331         }
       
   332 
       
   333     else
       
   334         {
       
   335         //Displayname = firstname + " " + lastname
       
   336         displayname = HBufC::NewLC( aFirstname.Length() +
       
   337                                     1 +
       
   338                                     aLastname.Length() );
       
   339         displayname->Des().Copy( aFirstname );
       
   340         displayname->Des().Append( KEmptySpace );
       
   341         displayname->Des().Append( aLastname );
       
   342         }
       
   343     return displayname;
       
   344     }
       
   345 
       
   346 // -----------------------------------------------------------------------------
       
   347 // CESMRClsMatchObserver::HandlePsResultsUpdateL
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CESMRClsMatchObserver::HandlePsResultsUpdateL(
       
   351         RPointerArray<CPsClientData>& searchResults,
       
   352         RPointerArray<CPsPattern>& searchSeqs)
       
   353     {
       
   354     FUNC_LOG;
       
   355     RPointerArray<CESMRClsItem> contacts;
       
   356     CleanupResetAndDestroyClosePushL( contacts );
       
   357     CleanupResetAndDestroyClosePushL( searchResults );
       
   358     CleanupResetAndDestroyClosePushL( searchSeqs );
       
   359 
       
   360     // Iterate through all the search results
       
   361     for( TInt counter = 0 ; counter < searchResults.Count(); counter++ )
       
   362         {
       
   363         // Get search result
       
   364         CPsClientData* result = searchResults[counter];
       
   365 
       
   366         // Get the order of the data fields in result
       
   367         RArray<TInt> dataOrder;
       
   368         CleanupClosePushL( dataOrder );
       
   369         iRequestHandler->GetDataOrderL( *( result->Uri() ), dataOrder );
       
   370 
       
   371         HBufC* firstname = HBufC::NewLC( KMaxTextLength );
       
   372         HBufC* lastname = HBufC::NewLC( KMaxTextLength );
       
   373         RPointerArray<HBufC> emailFields;
       
   374         CleanupResetAndDestroyClosePushL( emailFields );
       
   375         // Iterate through all the data fields in the result.
       
   376         // Collect the result and resolve which fields did match.
       
   377         // Email fields are collected into array
       
   378         for( TInt dataField = 0 ; dataField < dataOrder.Count(); dataField++ )
       
   379             {
       
   380             switch( dataOrder[dataField] )
       
   381                 {
       
   382                 case R_VPBK_FIELD_TYPE_FIRSTNAME:
       
   383                     firstname->Des().Append( *(result->Data(dataField)) );
       
   384                     break;
       
   385 
       
   386                 case R_VPBK_FIELD_TYPE_LASTNAME:
       
   387                     lastname->Des().Append( *(result->Data(dataField)) );
       
   388                     break;
       
   389 
       
   390                 case R_VPBK_FIELD_TYPE_EMAILGEN:
       
   391                 case R_VPBK_FIELD_TYPE_EMAILHOME:
       
   392                 case R_VPBK_FIELD_TYPE_EMAILWORK:
       
   393                     {
       
   394                     if( result->Data( dataField ) )
       
   395                         {
       
   396                         if( (*(result->Data( dataField ))).Length() > 0 )
       
   397                             {
       
   398                             HBufC* email = HBufC::NewLC( KMaxTextLength );
       
   399                             email->Des().Append( *(result->Data( dataField )) );
       
   400                             emailFields.Append( email );
       
   401                             CleanupStack::Pop( email );
       
   402                             }
       
   403                         }
       
   404                     }
       
   405                     break;
       
   406                 }
       
   407             }
       
   408 
       
   409 
       
   410 
       
   411         TDesC& sourceUri = *( result->Uri() );
       
   412         TBool isMruItem = sourceUri.Find( KDefaultMailBoxURI ) != KErrNotFound;
       
   413 
       
   414         MVPbkContactLink* contactLink = NULL;
       
   415 
       
   416         if( !isMruItem )
       
   417             {
       
   418             contactLink = iRequestHandler->ConvertToVpbkLinkLC( *result, *iContactManager );
       
   419             CleanupStack::Pop();
       
   420             // Push M-pointer to contactLink into CleanupStack for proper cleanup
       
   421             CleanupDeletePushL( contactLink );
       
   422             }
       
   423 
       
   424         // Determine how many contact address to create:
       
   425         // If there's no email fields, create one item without email address
       
   426         if ( emailFields.Count() == 0 )
       
   427             {
       
   428 
       
   429             // Use Ps engine to check if the text matches the search query
       
   430             CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(KMatchLen);
       
   431             CleanupStack::PushL( matchSet );
       
   432 
       
   433             // Create display name, this will be used in UI.
       
   434             HBufC* displayname = CreateDisplayNameLC( *firstname, *lastname, KNullDesC );
       
   435 
       
   436             RArray<TPsMatchLocation> matchLocation;
       
   437             CleanupClosePushL( matchLocation );
       
   438             iRequestHandler->LookupL( *iQuery, *displayname, *matchSet, matchLocation );
       
   439 
       
   440             // Create contact item and set highlighting for it
       
   441             CESMRClsItem* contactItem = CESMRClsItem::NewLC();
       
   442             contactItem->SetDisplayNameL( *displayname );
       
   443             contactItem->SetHighlightsL( matchLocation );
       
   444             if ( contactLink )
       
   445                 {
       
   446                 contactItem->SetContactLinkL( *contactLink );
       
   447                 }
       
   448             contactItem->SetIsMruItem( isMruItem );
       
   449             contacts.AppendL( contactItem );
       
   450             CleanupStack::Pop( contactItem );
       
   451 
       
   452             CleanupStack::Pop( &matchLocation );
       
   453             matchLocation.Close();
       
   454             CleanupStack::PopAndDestroy( displayname );
       
   455             CleanupStack::PopAndDestroy( matchSet );
       
   456 
       
   457             }
       
   458         else
       
   459             {
       
   460             // Iterate through all the email fields, check if they match the search criteria and
       
   461             // create new contact item for each one that matches
       
   462             for(TInt fieldIndex = 0; fieldIndex < emailFields.Count(); ++fieldIndex )
       
   463                 {
       
   464 
       
   465                 // Create display name, this will be used in UI.
       
   466                 HBufC* displayname = CreateDisplayNameLC( *firstname,
       
   467                                                           *lastname,
       
   468                                                           *emailFields[fieldIndex] );
       
   469 
       
   470                 // Create match text field, containing display field and email address
       
   471                 HBufC* matchText = HBufC::NewLC( displayname->Des().Length() +
       
   472                                 1 +
       
   473                                 emailFields[fieldIndex]->Des().Length() );
       
   474 
       
   475                 matchText->Des().Copy( *displayname );
       
   476                 matchText->Des().Append( KEmptySpace );
       
   477                 matchText->Des().Append( *emailFields[fieldIndex] );
       
   478 
       
   479                 // Use Ps engine to check if the text matches the search query
       
   480                 CDesCArray* matchSet = new (ELeave) CDesCArrayFlat(KMatchLen);
       
   481                 CleanupStack::PushL( matchSet );
       
   482 
       
   483                 RArray<TPsMatchLocation> matchLocation;
       
   484                 iRequestHandler->LookupL( *iQuery, *matchText, *matchSet, matchLocation );
       
   485                 CleanupClosePushL( matchLocation );
       
   486 
       
   487                 if( matchLocation.Count() > 0 )
       
   488                     {
       
   489                     // Create contact item and set highlighting for it
       
   490                     CESMRClsItem* contactItem = CESMRClsItem::NewLC();
       
   491                     contactItem->SetDisplayNameL( *displayname );
       
   492                     contactItem->SetIsMruItem( isMruItem );
       
   493                     contactItem->SetEmailAddressL( *emailFields[fieldIndex] );
       
   494                     contactItem->SetHighlightsL(matchLocation);
       
   495                     if ( contactLink )
       
   496                         {
       
   497                         contactItem->SetContactLinkL( *contactLink );
       
   498                         }
       
   499                     if ( emailFields.Count() > 1 )
       
   500                         {
       
   501                         contactItem->SetMultipleEmails( );
       
   502                         }
       
   503                     contacts.AppendL( contactItem );
       
   504                     CleanupStack::Pop( contactItem );
       
   505                     }
       
   506 
       
   507                 CleanupStack::PopAndDestroy( &matchLocation );
       
   508                 CleanupStack::PopAndDestroy( matchSet );
       
   509                 CleanupStack::PopAndDestroy( matchText );
       
   510                 CleanupStack::PopAndDestroy( displayname );
       
   511                 }
       
   512             }
       
   513         
       
   514         if ( contactLink )
       
   515             {
       
   516             CleanupStack::PopAndDestroy(); //codescanner::cleanup
       
   517             }
       
   518 
       
   519         // De-allocate name fields, first & last name
       
   520         CleanupStack::PopAndDestroy( &emailFields );
       
   521         CleanupStack::PopAndDestroy( lastname );
       
   522         CleanupStack::PopAndDestroy( firstname );
       
   523         CleanupStack::PopAndDestroy( &dataOrder );
       
   524         }
       
   525 
       
   526     iListHandler.UpdateContactMatchListsL(contacts);
       
   527     CleanupStack::PopAndDestroy( &searchSeqs );
       
   528     CleanupStack::PopAndDestroy( &searchResults );
       
   529     CleanupStack::PopAndDestroy( &contacts );
       
   530     }
       
   531 
       
   532 //EOF
       
   533