homescreensrv_plat/context_utility_api/tsrc/src/hgctxcontactmatcher.cpp
changeset 0 79c6a41cd166
equal deleted inserted replaced
-1:000000000000 0:79c6a41cd166
       
     1 /*
       
     2 * Copyright (c) 2008 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:  Contact matching class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // System includes
       
    20 #include <e32base.h>
       
    21 #include <bamdesca.h>
       
    22 #include <cntitem.h>
       
    23 #include <eikenv.h>
       
    24 #include <bautils.h>
       
    25 #include <fbs.h>
       
    26 #include <imageconversion.h>
       
    27 #include <data_caging_path_literals.hrh>
       
    28 
       
    29 #include <CVPbkContactManager.h>
       
    30 #include <MVPbkContactStoreList.h>
       
    31 #include <MVPbkContactStore.h>
       
    32 #include <CVPbkContactStoreUriArray.h>
       
    33 #include <MVPbkContactLinkArray.h>
       
    34 #include <MVPbkContactLink.h>
       
    35 #include <MVPbkFieldType.h>
       
    36 #include <MVPbkStoreContact.h>
       
    37 #include <MVPbkStoreContactField.h>
       
    38 #include <MVPbkStoreContactFieldCollection.h>
       
    39 #include <MVPbkContactFieldData.h>
       
    40 #include <MVPbkContactFieldTextData.h>
       
    41 #include <MVPbkContactFieldUriData.h>
       
    42 #include <MVPbkContactFieldDateTimeData.h>
       
    43 #include <MVPbkContactFieldBinaryData.h>
       
    44 #include <MVPbkContactOperationBase.h>
       
    45 #include <MVPbkContactStoreProperties.h>
       
    46 #include <TVPbkContactStoreUriPtr.h>
       
    47 #include <VPbkContactStoreUris.h>
       
    48 #include <MPbk2ContactNameFormatter.h>
       
    49 #include <CVPbkFieldTypeSelector.h>
       
    50 #include <TVPbkFieldVersitProperty.h>
       
    51 #include <CVPbkFieldTypeRefsList.h>
       
    52 #include <TVPbkWordParserCallbackParam.h>
       
    53 #include <CVPbkContactViewDefinition.h>
       
    54 #include <MVPbkContactViewBase.h>
       
    55 #include <coemain.h>
       
    56 #include <CPbk2SortOrderManager.h>
       
    57 #include <Pbk2ContactNameFormatterFactory.h>
       
    58 
       
    59 #include "hgctxcontactmatcher.h"
       
    60 
       
    61 
       
    62 #include "hgctxutilslogging.h"
       
    63 
       
    64 
       
    65 // ================= Static Constant Data ===================
       
    66 
       
    67 typedef const TDesC& (*UriFuncPtr)();
       
    68 
       
    69 // Number match store URIs in priority order.
       
    70 // When doing number matching, order of the stores in the uri array will
       
    71 // determine which stores are searched first (sequential match). We stop
       
    72 // the search when first match is found.
       
    73 static const UriFuncPtr NumberMatchStoreUris[] =
       
    74     {
       
    75     VPbkContactStoreUris::DefaultCntDbUri,
       
    76     // If we don't manage to open some store, we remove it from our array
       
    77     VPbkContactStoreUris::SimGlobalAdnUri,
       
    78     VPbkContactStoreUris::SimGlobalSdnUri,
       
    79     NULL,   // end marker
       
    80     };
       
    81 
       
    82 // All store URIs except own number store
       
    83 static const UriFuncPtr AllStoreUris[] =
       
    84     {
       
    85     VPbkContactStoreUris::DefaultCntDbUri,
       
    86     // If we don't manage to open some store, we remove it from our array
       
    87     VPbkContactStoreUris::SimGlobalAdnUri,
       
    88     VPbkContactStoreUris::SimGlobalSdnUri,
       
    89     VPbkContactStoreUris::SimGlobalFdnUri,
       
    90     NULL,   // end marker
       
    91     };
       
    92 
       
    93 // Own number store URIs
       
    94 static const UriFuncPtr OwnNumberStoreUris[] =
       
    95     {
       
    96     VPbkContactStoreUris::SimGlobalOwnNumberUri,
       
    97     NULL,   // end marker
       
    98     };
       
    99 
       
   100 // number of digits that must match from the right side of a phone number
       
   101 const TInt KNumberMatchLenFromRight = 7;
       
   102 
       
   103 // granularity for CDesCArray
       
   104 const TInt KArrayGranularity = 4;
       
   105 
       
   106 //               YYYYMMDD:HHMMSS.MMMMMM
       
   107 _LIT(KNullTime, "11110000:010101.00000");
       
   108 
       
   109 // ================= STATIC FUNCTIONS =======================
       
   110 
       
   111 // ---------------------------------------------------------
       
   112 // FindWordSplitterL
       
   113 // ---------------------------------------------------------
       
   114 //
       
   115 static TInt FindWordSplitterL( TAny* aParams )
       
   116 	{
       
   117 	TVPbkWordParserCallbackParam* parser = 
       
   118         static_cast<TVPbkWordParserCallbackParam*>( aParams );
       
   119         
       
   120     const TText* ptr = parser->iStringToParse->Ptr();
       
   121 	const TText* end = ptr + parser->iStringToParse->Length();
       
   122 
       
   123 	const TText* startOfWord=NULL;
       
   124 	for ( ; ; )
       
   125 		{
       
   126 		if ( ptr==end || TChar(*ptr).IsSpace() || *ptr == ',' || *ptr == ';' )
       
   127 			{
       
   128 			if ( startOfWord )
       
   129 				{
       
   130 				TPtrC addWord( startOfWord,ptr - startOfWord );
       
   131 				parser->iWordArray->AppendL( addWord );
       
   132 				startOfWord = NULL;
       
   133 				}
       
   134 			if ( ptr == end )
       
   135                 {
       
   136 				break;
       
   137                 }
       
   138 			}
       
   139 		else if ( !startOfWord )
       
   140             {
       
   141 			startOfWord = ptr;
       
   142             }
       
   143 		ptr++;
       
   144 		}
       
   145 	return( KErrNone );
       
   146 	}
       
   147 
       
   148 static HBufC* CombineStringsLC( CDesCArray& aArray )
       
   149     {
       
   150     TInt len = 0;
       
   151     for ( TInt i = 0, ie = aArray.Count(); i != ie; ++i )
       
   152         {
       
   153         len += aArray[i].Length() + 1;
       
   154         }
       
   155     HBufC* result = HBufC::NewLC( len );
       
   156     TPtr p( result->Des() );
       
   157     for ( TInt i = 0, ie = aArray.Count(); i != ie; ++i )
       
   158         {
       
   159         if ( i )
       
   160             {
       
   161             p.Append( ' ' );
       
   162             }
       
   163         p.Append( aArray[i] );
       
   164         }
       
   165     return result;
       
   166     }
       
   167     
       
   168 // ================= MEMBER FUNCTIONS =======================
       
   169 
       
   170 // ----------------------------------------------------------------------------
       
   171 // Two-phase constructor for CHgCtxContactMatcher class.
       
   172 // ----------------------------------------------------------------------------
       
   173 EXPORT_C CHgCtxContactMatcher* CHgCtxContactMatcher::NewL(
       
   174     RFs* aFsSession )
       
   175     {
       
   176     CHgCtxContactMatcher* self = CHgCtxContactMatcher::NewLC( aFsSession );
       
   177     CleanupStack::Pop(self);
       
   178     return self;
       
   179     }
       
   180 
       
   181 // ----------------------------------------------------------------------------
       
   182 // Two-phase constructor for CHgCtxContactMatcher class.
       
   183 // ----------------------------------------------------------------------------
       
   184 EXPORT_C CHgCtxContactMatcher* CHgCtxContactMatcher::NewLC(
       
   185     RFs* aFsSession )
       
   186     {
       
   187     CHgCtxContactMatcher* self = new ( ELeave ) CHgCtxContactMatcher( aFsSession );
       
   188     CleanupStack::PushL(self);
       
   189     self->ConstructL();
       
   190     return self;
       
   191     }
       
   192 
       
   193 // ----------------------------------------------------------------------------
       
   194 // C++ destructor.
       
   195 // ----------------------------------------------------------------------------
       
   196 EXPORT_C CHgCtxContactMatcher::~CHgCtxContactMatcher()
       
   197     {
       
   198     delete iNameFieldTypes;
       
   199     delete iNumberFieldTypes;
       
   200     delete iEmailFieldTypes;
       
   201     delete iXspIdFieldTypes;
       
   202     delete iAddressFieldTypes;
       
   203 	delete iWebAddressFieldTypes;
       
   204     delete iHomeAddressFieldTypes;
       
   205     delete iWorkAddressFieldTypes;
       
   206     
       
   207     FreeOldOperation();
       
   208     CleanupNumberMatch();
       
   209     delete iStoreUris;
       
   210     delete iContactManager;
       
   211     delete iSortOrderManager;
       
   212     delete iNameFormatter;
       
   213 
       
   214     if ( iClientStatus )
       
   215         {
       
   216         User::RequestComplete( iClientStatus, KErrCancel );
       
   217         }
       
   218     if ( iASchedulerWait.IsStarted() )
       
   219         {
       
   220         iASchedulerWait.AsyncStop();
       
   221         }
       
   222         
       
   223     iContactObservers.Close();
       
   224     
       
   225     if ( iFsSessionOwned && iFsSession )
       
   226         {
       
   227         iFsSession->Close();
       
   228         delete iFsSession;
       
   229         }
       
   230     }
       
   231 
       
   232 // ----------------------------------------------------------------------------
       
   233 // C++ Constructor.
       
   234 // ----------------------------------------------------------------------------
       
   235 CHgCtxContactMatcher::CHgCtxContactMatcher( RFs* aFsSession) : iFsSession( aFsSession )
       
   236     {
       
   237     }
       
   238 
       
   239 // ----------------------------------------------------------------------------
       
   240 // Second phase constructor
       
   241 // ----------------------------------------------------------------------------
       
   242 void CHgCtxContactMatcher::ConstructL()
       
   243     {
       
   244     if ( !iFsSession )
       
   245         {
       
   246         // The contact manager would be okay with NULL but some of our own functions
       
   247         // need an RFs.
       
   248         iFsSessionOwned = ETrue;
       
   249         iFsSession = new ( ELeave ) RFs;
       
   250         User::LeaveIfError( iFsSession->Connect() );
       
   251         }
       
   252         
       
   253     iContactManager = CVPbkContactManager::NewL(
       
   254         *CVPbkContactStoreUriArray::NewLC(), iFsSession );
       
   255     CleanupStack::PopAndDestroy(); // CVPbkContactStoreUriArray
       
   256 
       
   257     // No stores open yet
       
   258     iStoreUris = CVPbkContactStoreUriArray::NewL();
       
   259     }
       
   260 
       
   261 //******************* API-methods *********************************************
       
   262 
       
   263 // ----------------------------------------------------------------------------
       
   264 // Synchronous version
       
   265 // ----------------------------------------------------------------------------
       
   266 EXPORT_C void CHgCtxContactMatcher::OpenStoreL(
       
   267     const CVPbkContactStoreUriArray& aUriArray )
       
   268     {
       
   269     InitOperationL( EOpenStore );
       
   270     OpenStoreCommonL( aUriArray );
       
   271     if ( iApiMethodStatus != EFinished )
       
   272         {
       
   273         iApiMethodStatus = EExecuting;
       
   274         // Wait until stores are open
       
   275         iASchedulerWait.Start();
       
   276         }
       
   277     User::LeaveIfError( iError );
       
   278     }
       
   279 
       
   280 // ----------------------------------------------------------------------------
       
   281 // Asynchronous version
       
   282 // ----------------------------------------------------------------------------
       
   283 EXPORT_C void CHgCtxContactMatcher::OpenStoreL(
       
   284     const CVPbkContactStoreUriArray& aUriArray, TRequestStatus&  aStatus )
       
   285     {
       
   286     InitOperationL( EOpenStore );
       
   287     OpenStoreCommonL( aUriArray );
       
   288     InitOperation( &aStatus );
       
   289 
       
   290     if ( iApiMethodStatus != EFinished )
       
   291         {
       
   292         iApiMethodStatus = EExecuting;
       
   293         }
       
   294     }
       
   295 
       
   296 
       
   297 // ----------------------------------------------------------------------------
       
   298 // Common code to sync/async versions.
       
   299 // ----------------------------------------------------------------------------
       
   300 void CHgCtxContactMatcher::OpenStoreCommonL(
       
   301     const CVPbkContactStoreUriArray& aUriArray )
       
   302     {
       
   303     if (iStoreUris->Count())
       
   304         {
       
   305         // Opening more stores when some stores are already open is not
       
   306         // supported. Support would require managing iStoreUris properly
       
   307         // so that it contains all open stores.
       
   308         User::Leave(KErrGeneral);
       
   309         }
       
   310 
       
   311     const TInt count = aUriArray.Count();
       
   312     
       
   313     for (TInt i = 0; i < count; ++i)
       
   314         {
       
   315         // Appended Uri:s to the array. If store fails to open it is removed
       
   316         // from the array. This keeps Uri's in priority order in the array.
       
   317         TVPbkContactStoreUriPtr uriPtr = aUriArray[i];
       
   318         iStoreUris->AppendL( uriPtr );
       
   319 
       
   320         iContactManager->LoadContactStoreL( uriPtr );
       
   321         }
       
   322     MVPbkContactStoreList& storeList = iContactManager->ContactStoresL();
       
   323     storeList.OpenAllL( *this );
       
   324     }
       
   325 
       
   326 // ----------------------------------------------------------------------------
       
   327 // Synchronous version
       
   328 // ----------------------------------------------------------------------------
       
   329 EXPORT_C void CHgCtxContactMatcher::OpenAllStoresL()
       
   330     {
       
   331     OpenStoreL(AllStoreUris);
       
   332     }
       
   333 
       
   334 // ----------------------------------------------------------------------------
       
   335 // Asynchronous version
       
   336 // ----------------------------------------------------------------------------
       
   337 EXPORT_C void CHgCtxContactMatcher::OpenAllStoresL( TRequestStatus& aStatus )
       
   338     {
       
   339     OpenStoreL(AllStoreUris, aStatus);
       
   340     }
       
   341 
       
   342 // ----------------------------------------------------------------------------
       
   343 // Synchronous version
       
   344 // ----------------------------------------------------------------------------
       
   345 EXPORT_C void CHgCtxContactMatcher::OpenDefaultMatchStoresL()
       
   346     {
       
   347     OpenStoreL(NumberMatchStoreUris);
       
   348     }
       
   349 
       
   350 // ----------------------------------------------------------------------------
       
   351 // Asynchronous version
       
   352 // ----------------------------------------------------------------------------
       
   353 EXPORT_C void CHgCtxContactMatcher::OpenDefaultMatchStoresL( TRequestStatus& aStatus )
       
   354     {
       
   355     OpenStoreL(NumberMatchStoreUris, aStatus);
       
   356     }
       
   357 
       
   358 // ----------------------------------------------------------------------------
       
   359 // Open OwnNumber stores.
       
   360 // Synchronous version
       
   361 // ----------------------------------------------------------------------------
       
   362 EXPORT_C void CHgCtxContactMatcher::OpenOwnNumberStoresL()
       
   363     {
       
   364     OpenStoreL(OwnNumberStoreUris);
       
   365     }
       
   366 
       
   367 // ----------------------------------------------------------------------------
       
   368 // Open OwnNumber stores.
       
   369 // Asynchronous version
       
   370 // ----------------------------------------------------------------------------
       
   371 EXPORT_C void CHgCtxContactMatcher::OpenOwnNumberStoresL( TRequestStatus& aStatus )
       
   372     {
       
   373     OpenStoreL(OwnNumberStoreUris, aStatus);
       
   374     }
       
   375 
       
   376 // ----------------------------------------------------------------------------
       
   377 // Close all open stores.
       
   378 // ----------------------------------------------------------------------------
       
   379 EXPORT_C void CHgCtxContactMatcher::CloseStoresL()
       
   380     {
       
   381     // Closing stores does not work. MatchDataL() finds contacts from
       
   382     // closed stores.
       
   383 
       
   384     InitOperationL( ECloseStores );
       
   385 
       
   386     iApiMethodStatus = EExecuting;
       
   387     TRAPD( err, iContactManager->ContactStoresL().CloseAll( *this ) );
       
   388     iApiMethodStatus = EFinished;
       
   389     if ( err == KErrNone)
       
   390         {
       
   391         delete iStoreUris; iStoreUris = NULL;
       
   392         iStoreUris = CVPbkContactStoreUriArray::NewL();        
       
   393         }
       
   394     else
       
   395         {
       
   396         User::Leave(err);
       
   397         }
       
   398     }
       
   399 
       
   400 // ----------------------------------------------------------------------------
       
   401 // Synchronous version
       
   402 // ----------------------------------------------------------------------------
       
   403 EXPORT_C void CHgCtxContactMatcher::MatchPhoneNumberL(
       
   404     const TDesC& aData, TInt aDigits,
       
   405     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags,
       
   406     CVPbkContactLinkArray& aLinkArray )
       
   407     {
       
   408     InitOperationL( EMatchPhoneNumber );
       
   409     iResultContactLinkArray = &aLinkArray;
       
   410 
       
   411     // Start asynchronous matching and wait until results are ready
       
   412     MatchPhoneNumberCommonL( aData, aDigits, aFlags );
       
   413     if ( iApiMethodStatus != EFinished )
       
   414         {
       
   415         iApiMethodStatus = EExecuting;
       
   416         iASchedulerWait.Start();
       
   417         }
       
   418     User::LeaveIfError( iError );
       
   419     }
       
   420 
       
   421 
       
   422 // ----------------------------------------------------------------------------
       
   423 // Asynchronous version
       
   424 // ----------------------------------------------------------------------------
       
   425 EXPORT_C void CHgCtxContactMatcher::MatchPhoneNumberL(
       
   426     const TDesC& aData, TInt aDigits,
       
   427     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags,
       
   428     CVPbkContactLinkArray& aLinkArray, TRequestStatus& aStatus )
       
   429     {
       
   430     InitOperationL( EMatchPhoneNumber );
       
   431     iResultContactLinkArray = &aLinkArray;
       
   432     // Start asynchronous matching
       
   433     MatchPhoneNumberCommonL( aData, aDigits, aFlags );
       
   434     InitOperation( &aStatus );
       
   435     if ( iApiMethodStatus != EFinished )
       
   436         {
       
   437         iApiMethodStatus = EExecuting;
       
   438         }
       
   439     }
       
   440 
       
   441 // ----------------------------------------------------------------------------
       
   442 // Common code for sync and async versions
       
   443 // ----------------------------------------------------------------------------
       
   444 void CHgCtxContactMatcher::MatchPhoneNumberCommonL(
       
   445     const TDesC& aData, TInt aDigits,
       
   446     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags )
       
   447     {
       
   448     // Delete resources allocated for previous match
       
   449     CleanupNumberMatch();
       
   450 
       
   451     // iStoreUris is filled when stores are opened
       
   452 
       
   453     iStratConfig = new (ELeave) CVPbkPhoneNumberMatchStrategy::TConfig(
       
   454         aDigits,
       
   455         *iStoreUris,
       
   456         CVPbkPhoneNumberMatchStrategy::EVPbkSequentialMatch,
       
   457         aFlags);
       
   458     iMatchStrategy = CVPbkPhoneNumberMatchStrategy::NewL(
       
   459                 *iStratConfig,
       
   460                 *iContactManager,
       
   461                 *this);
       
   462     // Start asynchronous matching
       
   463     iMatchStrategy->MatchL( aData );
       
   464     }
       
   465 
       
   466 
       
   467 // ----------------------------------------------------------------------------
       
   468 // Find from a store succeeded
       
   469 // ----------------------------------------------------------------------------
       
   470 void CHgCtxContactMatcher::FindFromStoreSucceededL( MVPbkContactStore& /*aStore*/,
       
   471         MVPbkContactLinkArray* aResultsFromStore )
       
   472     {
       
   473     __ASSERT_DEBUG( aResultsFromStore, HgContactMatcherPanics::Panic(
       
   474         HgContactMatcherPanics::EPanNullPointer ));
       
   475 
       
   476     // Take the ownership of the result immediately
       
   477     CleanupDeletePushL( aResultsFromStore );
       
   478 
       
   479     CopyFindResultsL( aResultsFromStore );
       
   480 
       
   481     CleanupStack::PopAndDestroy(); // aResultsFromStore
       
   482     }
       
   483 
       
   484 // ----------------------------------------------------------------------------
       
   485 // Copy the found results for a store into array
       
   486 // ----------------------------------------------------------------------------
       
   487 void CHgCtxContactMatcher::CopyFindResultsL( MVPbkContactLinkArray*
       
   488     aResults )
       
   489     {
       
   490     const TInt count = aResults->Count();
       
   491     if ( iResultContactLinkArray )
       
   492         {
       
   493         // Copy links to the member array
       
   494         for ( TInt i = 0; i < count; ++i )
       
   495             {
       
   496             iResultContactLinkArray->AppendL( aResults->At( i ).CloneLC() );
       
   497             CleanupStack::Pop(); // cloned link
       
   498             }
       
   499         }
       
   500     else
       
   501         {
       
   502         iResultContactLinkCnt += count;
       
   503         }
       
   504     }
       
   505 
       
   506 
       
   507 // ----------------------------------------------------------------------------
       
   508 // Find failed
       
   509 // ----------------------------------------------------------------------------
       
   510 void CHgCtxContactMatcher::FindFromStoreFailed( MVPbkContactStore& /*aStore*/, TInt /*aError*/ )
       
   511     {
       
   512     //no operation, search to continue from the other stores
       
   513     }
       
   514 
       
   515 
       
   516 // ----------------------------------------------------------------------------
       
   517 // Find complete
       
   518 // ----------------------------------------------------------------------------
       
   519 void CHgCtxContactMatcher::FindFromStoresOperationComplete()
       
   520     {
       
   521     if (!iResultContactLinkArray)
       
   522         {
       
   523         // Links were not copied. Result is whether any links found or not.
       
   524         OperationComplete( iResultContactLinkCnt ? KErrNone:KErrNotFound );
       
   525         }
       
   526     else
       
   527         {
       
   528         OperationComplete();
       
   529         iResultContactLinkArray = NULL;
       
   530         }
       
   531     }
       
   532 
       
   533 // ----------------------------------------------------------------------------
       
   534 // Return global list of field types.
       
   535 // ----------------------------------------------------------------------------
       
   536 EXPORT_C const MVPbkFieldTypeList& CHgCtxContactMatcher::FieldTypes() const
       
   537     {
       
   538     return iContactManager->FieldTypes();
       
   539     }
       
   540 
       
   541 // ----------------------------------------------------------------------------
       
   542 // Synchronous version
       
   543 // ----------------------------------------------------------------------------
       
   544 EXPORT_C void CHgCtxContactMatcher::GetStoreContactL(
       
   545     const MVPbkContactLink& aLink, MVPbkStoreContact** aStoreContact )
       
   546     {
       
   547     InitOperationL( EGetStoreContact );
       
   548     iResultStoreContact = aStoreContact;
       
   549 
       
   550     // Start asynchronous operation and wait until results are ready
       
   551     FreeOldOperation();
       
   552     iOperation = iContactManager->RetrieveContactL( aLink, *this );
       
   553     if ( iApiMethodStatus != EFinished )
       
   554         {
       
   555         iApiMethodStatus = EExecuting;
       
   556         iASchedulerWait.Start();
       
   557         }
       
   558     User::LeaveIfError( iError );
       
   559     }
       
   560 
       
   561 // ----------------------------------------------------------------------------
       
   562 // Asynchronous version
       
   563 // ----------------------------------------------------------------------------
       
   564 EXPORT_C void CHgCtxContactMatcher::GetStoreContactL(
       
   565     const MVPbkContactLink& aLink, MVPbkStoreContact** aStoreContact,
       
   566     TRequestStatus& aStatus )
       
   567     {
       
   568     InitOperationL( EGetStoreContact );
       
   569     iResultStoreContact = aStoreContact;
       
   570     // Start asynchronous operation
       
   571     FreeOldOperation();
       
   572     iOperation = iContactManager->RetrieveContactL( aLink, *this );
       
   573     InitOperation( &aStatus );
       
   574     if ( iApiMethodStatus != EFinished )
       
   575         {
       
   576         iApiMethodStatus = EExecuting;
       
   577         }
       
   578     }
       
   579 
       
   580 // ----------------------------------------------------------------------------
       
   581 // Synchronous version
       
   582 // ----------------------------------------------------------------------------
       
   583 EXPORT_C void CHgCtxContactMatcher::IsOwnNumberL( const TDesC& aNumber, TBool& aResult )
       
   584     {
       
   585     InitOperationL( EMatchPhoneNumber );
       
   586 
       
   587      // Not interested in links, only whether found or not
       
   588     iResultContactLinkArray = NULL;
       
   589     iResultContactLinkCnt = 0;
       
   590 
       
   591     // Start asynchronous matching and wait until results are ready
       
   592     MatchPhoneNumberCommonL( aNumber, aNumber.Length(),
       
   593         CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag );
       
   594     if ( iApiMethodStatus != EFinished )
       
   595         {
       
   596         iApiMethodStatus = EExecuting;
       
   597         iASchedulerWait.Start();
       
   598         }
       
   599     User::LeaveIfError( iError );
       
   600 
       
   601     aResult = iResultContactLinkCnt > 0;
       
   602     }
       
   603 
       
   604 // ----------------------------------------------------------------------------
       
   605 // Asynchronous version
       
   606 // ----------------------------------------------------------------------------
       
   607 EXPORT_C void CHgCtxContactMatcher::IsOwnNumberL( const TDesC& aNumber,
       
   608     TRequestStatus& aStatus )
       
   609     {
       
   610     InitOperationL( EMatchPhoneNumber );
       
   611 
       
   612      // Not interested in links, only whether found or not
       
   613     iResultContactLinkArray = NULL;
       
   614     iResultContactLinkCnt = 0;
       
   615 
       
   616     // Start asynchronous matching
       
   617     MatchPhoneNumberCommonL( aNumber, aNumber.Length(),
       
   618         CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag );
       
   619     InitOperation( &aStatus );
       
   620     if ( iApiMethodStatus != EFinished )
       
   621         {
       
   622         iApiMethodStatus = EExecuting;
       
   623         }
       
   624     }
       
   625 
       
   626 // ----------------------------------------------------------------------------
       
   627 // Cancel asynchronous operation
       
   628 // ----------------------------------------------------------------------------
       
   629 EXPORT_C void CHgCtxContactMatcher::CancelOperation()
       
   630     {
       
   631     if (iApiMethodStatus != EExecuting)
       
   632         {
       
   633         return;
       
   634         }
       
   635 
       
   636     __ASSERT_DEBUG(!iSync, HgContactMatcherPanics::Panic(
       
   637         HgContactMatcherPanics::EPanInvalidOp));
       
   638 
       
   639     switch(iApiMethod)
       
   640         {
       
   641         case EMatchData:
       
   642         case EGetStoreContact:
       
   643             FreeOldOperation(); // deleting the operation cancels it
       
   644             break;
       
   645         case EMatchPhoneNumber:
       
   646             CleanupNumberMatch();
       
   647             break;
       
   648         default:
       
   649             ;
       
   650         }
       
   651 
       
   652     User::RequestComplete( iClientStatus, KErrCancel );
       
   653 
       
   654     iApiMethod = ENoMethod;
       
   655     iApiMethodStatus = EFinished;
       
   656     }
       
   657 
       
   658 // ----------------------------------------------------------------------------
       
   659 // GetFieldData, for EVPbkFieldStorageTypeText
       
   660 // ----------------------------------------------------------------------------
       
   661 EXPORT_C TPtrC CHgCtxContactMatcher::GetFieldDataTextL(
       
   662     const MVPbkStoreContact& aContact,
       
   663     const MVPbkFieldType& aFType ) const
       
   664     {
       
   665     TPtrC ret(KNullDesC);
       
   666     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   667     if (field)
       
   668         {
       
   669         const MVPbkContactFieldData& fdata = field->FieldData();
       
   670         if (fdata.DataType() == EVPbkFieldStorageTypeText)
       
   671             {
       
   672             const MVPbkContactFieldTextData& fdata2 =
       
   673                 MVPbkContactFieldTextData::Cast(fdata);
       
   674             ret.Set( fdata2.Text() );
       
   675             }
       
   676         else
       
   677             {
       
   678             User::Leave( KErrArgument );
       
   679             }
       
   680         }
       
   681     return ret;
       
   682     }
       
   683 
       
   684 // ----------------------------------------------------------------------------
       
   685 // GetFieldData, for EVPbkFieldStorageTypeDateTime
       
   686 // ----------------------------------------------------------------------------
       
   687 EXPORT_C TTime CHgCtxContactMatcher::GetFieldDataDateTimeL(
       
   688     const MVPbkStoreContact& aContact,
       
   689     const MVPbkFieldType& aFType ) const
       
   690     {
       
   691     TTime ret(KNullTime);
       
   692     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   693     if (field)
       
   694         {
       
   695         const MVPbkContactFieldData& fdata = field->FieldData();
       
   696         if (fdata.DataType() == EVPbkFieldStorageTypeDateTime)
       
   697             {
       
   698             const MVPbkContactFieldDateTimeData& fdata2 =
       
   699                 MVPbkContactFieldDateTimeData::Cast( fdata );
       
   700             ret = fdata2.DateTime();
       
   701             }
       
   702         else
       
   703             {
       
   704             User::Leave( KErrArgument );
       
   705             }
       
   706         }
       
   707     return ret;
       
   708     }
       
   709 
       
   710 // ----------------------------------------------------------------------------
       
   711 // GetFieldData, for EVPbkFieldStorageTypeBinary
       
   712 // ----------------------------------------------------------------------------
       
   713 EXPORT_C TPtrC8 CHgCtxContactMatcher::GetFieldDataBinaryL(
       
   714     const MVPbkStoreContact& aContact,
       
   715     const MVPbkFieldType& aFType ) const
       
   716     {
       
   717     TPtrC8 ret(KNullDesC8);
       
   718     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   719     if (field)
       
   720         {
       
   721         const MVPbkContactFieldData& fdata = field->FieldData();
       
   722         if (fdata.DataType() == EVPbkFieldStorageTypeBinary)
       
   723             {
       
   724             const MVPbkContactFieldBinaryData& fdata2 =
       
   725                 MVPbkContactFieldBinaryData::Cast( fdata );
       
   726             ret.Set( fdata2.BinaryData() );
       
   727             }
       
   728         else
       
   729             {
       
   730             User::Leave( KErrArgument );
       
   731             }
       
   732         }
       
   733     return ret;
       
   734     }
       
   735 
       
   736 
       
   737 //******************************** Private Methods ***************************
       
   738 
       
   739 // ----------------------------------------------------------------------------
       
   740 // Finds a field of given type from contact.
       
   741 // Returns pointer to field or NULL if not found.
       
   742 // ----------------------------------------------------------------------------
       
   743  const MVPbkStoreContactField* CHgCtxContactMatcher::FindField(
       
   744     const MVPbkStoreContact& aContact,
       
   745     const MVPbkFieldType& aFType ) const
       
   746     {
       
   747     const MVPbkStoreContactFieldCollection& coll = aContact.Fields();
       
   748     TInt n = coll.FieldCount();
       
   749 
       
   750     const MVPbkStoreContactField* field = NULL;
       
   751     TBool bFound = EFalse;
       
   752     for(TInt i=0; i < n && !bFound; ++i)
       
   753         {
       
   754         field = &coll.FieldAt( i );
       
   755         const MVPbkFieldType* ftype = field->MatchFieldType( 0 );
       
   756         if ( ftype )
       
   757             {
       
   758             if ( ftype->IsSame( aFType ))
       
   759                 {
       
   760                 bFound = ETrue;
       
   761                 }
       
   762             }
       
   763         }
       
   764     if ( !bFound )
       
   765         {
       
   766         field = NULL;
       
   767         }
       
   768     return field;
       
   769     }
       
   770 
       
   771 // ----------------------------------------------------------------------------
       
   772 // Get URI array with stores
       
   773 // ----------------------------------------------------------------------------
       
   774 CVPbkContactStoreUriArray* CHgCtxContactMatcher::GetStoreArrayLC(
       
   775     const TDesC& (* const aFuncPtrs[])() )
       
   776     {
       
   777     CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC();
       
   778 
       
   779     // Add stores
       
   780     for(TInt i = 0; aFuncPtrs[i]; i++)
       
   781         {
       
   782         TVPbkContactStoreUriPtr uriPtr(aFuncPtrs[i]());
       
   783         uriArray->AppendL(uriPtr);
       
   784         }
       
   785     return uriArray;
       
   786     }
       
   787 
       
   788 // ----------------------------------------------------------------------------
       
   789 // Open stores. Synchronous version
       
   790 // ----------------------------------------------------------------------------
       
   791 void CHgCtxContactMatcher::OpenStoreL(const TDesC& (* const aFuncPtrs[])())
       
   792     {
       
   793     CVPbkContactStoreUriArray* uriArray = GetStoreArrayLC(aFuncPtrs);
       
   794 
       
   795     CHgCtxContactMatcher::OpenStoreL(*uriArray);
       
   796     CleanupStack::PopAndDestroy(uriArray);
       
   797     }
       
   798 
       
   799 // ----------------------------------------------------------------------------
       
   800 // Open stores. Asynchronous version
       
   801 // ----------------------------------------------------------------------------
       
   802 void CHgCtxContactMatcher::OpenStoreL(const TDesC& (* const aFuncPtrs[])(),
       
   803     TRequestStatus&  aStatus)
       
   804     {
       
   805     CVPbkContactStoreUriArray* uriArray = GetStoreArrayLC(aFuncPtrs);
       
   806 
       
   807     CHgCtxContactMatcher::OpenStoreL(*uriArray, aStatus);
       
   808     CleanupStack::PopAndDestroy(uriArray);
       
   809     }
       
   810 
       
   811 // ----------------------------------------------------------------------------
       
   812 // Called when the opening process is complete,
       
   813 // ie. all stores have been reported either failed or successfully opened.
       
   814 // ----------------------------------------------------------------------------
       
   815 //
       
   816 void CHgCtxContactMatcher::OpenComplete()
       
   817     {
       
   818     TInt error = KErrNone;
       
   819     if ( iStoreUris->Count() == 0 )
       
   820         {
       
   821         // unable to open any of the specified stores
       
   822         error = KErrNotSupported;
       
   823         }
       
   824     OperationComplete( error );
       
   825     }
       
   826 
       
   827 // ----------------------------------------------------------------------------
       
   828 // Called when a contact store is ready to use.
       
   829 // ----------------------------------------------------------------------------
       
   830 void CHgCtxContactMatcher::StoreReady( MVPbkContactStore& /*aContactStore*/ )
       
   831     {
       
   832     }
       
   833 
       
   834 // ----------------------------------------------------------------------------
       
   835 // Called when a contact store becomes unavailable.
       
   836 // Client may inspect the reason of the unavailability and decide whether or not
       
   837 // it will keep the store opened (ie. listen to the store events).
       
   838 // @param aContactStore The store that became unavailable.
       
   839 // @param aReason The reason why the store is unavailable.
       
   840 //                This is one of the system wide error codes.
       
   841 // ----------------------------------------------------------------------------
       
   842 void CHgCtxContactMatcher::StoreUnavailable( MVPbkContactStore& aContactStore,
       
   843     TInt /*aReason*/ )
       
   844     {
       
   845     // Remove contact store from uri list
       
   846     iStoreUris->Remove( aContactStore.StoreProperties().Uri() );
       
   847     }
       
   848 
       
   849 // ----------------------------------------------------------------------------
       
   850 // Called when changes occur in the contact store.
       
   851 // @see TVPbkContactStoreEvent
       
   852 //
       
   853 // @param aStoreEvent Event that has occured.
       
   854 // ----------------------------------------------------------------------------
       
   855 void CHgCtxContactMatcher::HandleStoreEventL(
       
   856         MVPbkContactStore& /*aContactStore*/,
       
   857         TVPbkContactStoreEvent aStoreEvent)
       
   858     {
       
   859     // Contact and group events can be ignored, but we pass backup events for the observer.
       
   860     switch ( aStoreEvent.iEventType )
       
   861         {
       
   862         case TVPbkContactStoreEvent::EStoreBackupBeginning:
       
   863         case TVPbkContactStoreEvent::EStoreRestoreBeginning:
       
   864             {
       
   865             iBackup = ETrue;
       
   866             break;
       
   867             }
       
   868         case TVPbkContactStoreEvent::EStoreBackupRestoreCompleted:
       
   869             {
       
   870             iBackup = EFalse;
       
   871             break;
       
   872             }
       
   873         case TVPbkContactStoreEvent::EContactAdded:
       
   874         case TVPbkContactStoreEvent::EContactDeleted:
       
   875         case TVPbkContactStoreEvent::EContactChanged:
       
   876             {
       
   877             for ( TInt i = 0, ie = iContactObservers.Count(); i != ie; ++i )
       
   878                 {
       
   879                 iContactObservers[i]->HandleContactEventL();
       
   880                 }
       
   881             break;
       
   882             }
       
   883         default:
       
   884             break;
       
   885         }
       
   886     }
       
   887 
       
   888 
       
   889 // ----------------------------------------------------------------------------
       
   890 // Called when find is complete. Callee takes ownership of the results.
       
   891 // In case of an error during find, the aResults may contain only
       
   892 // partial results of the find.
       
   893 //
       
   894 // @param aResults Array of contact links that matched the find.
       
   895 // ----------------------------------------------------------------------------
       
   896 void CHgCtxContactMatcher::FindCompleteL( MVPbkContactLinkArray* aResults )
       
   897     {
       
   898     __ASSERT_DEBUG( aResults, HgContactMatcherPanics::Panic(
       
   899         HgContactMatcherPanics::EPanNullPointer ));
       
   900 
       
   901     // Take the ownership of the result immediately
       
   902     CleanupDeletePushL( aResults );
       
   903 
       
   904     CopyFindResultsL( aResults );
       
   905 
       
   906     CleanupStack::PopAndDestroy(); // aResults
       
   907 
       
   908     if (!iResultContactLinkArray)
       
   909         {
       
   910         // No need to copy links. Only interested whether found or not
       
   911         OperationComplete( iResultContactLinkCnt ? KErrNone:KErrNotFound );
       
   912         }
       
   913     else
       
   914         {
       
   915         OperationComplete();
       
   916         iResultContactLinkArray = NULL;
       
   917         }
       
   918     }
       
   919 
       
   920 // ----------------------------------------------------------------------------
       
   921 // Called in case the find fails for some reason.
       
   922 //
       
   923 // @param aError One of the system wide error codes.
       
   924 // ----------------------------------------------------------------------------
       
   925 void CHgCtxContactMatcher::FindFailed( TInt aError )
       
   926     {
       
   927     OperationFailed( aError );
       
   928     iResultContactLinkArray = NULL;
       
   929     }
       
   930 
       
   931 // ----------------------------------------------------------------------------
       
   932 // Free old VPbk-operation.
       
   933 // ----------------------------------------------------------------------------
       
   934 void CHgCtxContactMatcher::FreeOldOperation()
       
   935     {
       
   936     delete iOperation;
       
   937     iOperation = NULL;
       
   938     }
       
   939 
       
   940 // ----------------------------------------------------------------------------
       
   941 // Called when operation is completed.
       
   942 // ----------------------------------------------------------------------------
       
   943 void CHgCtxContactMatcher::VPbkSingleContactOperationComplete(
       
   944         MVPbkContactOperationBase& /*aOperation*/, MVPbkStoreContact* aContact)
       
   945     {
       
   946     *iResultStoreContact = aContact;
       
   947     iResultStoreContact  = NULL;
       
   948     OperationComplete();
       
   949     }
       
   950 
       
   951 // ----------------------------------------------------------------------------
       
   952 // Called if the operation fails.
       
   953 // ----------------------------------------------------------------------------
       
   954 void CHgCtxContactMatcher::VPbkSingleContactOperationFailed(
       
   955     MVPbkContactOperationBase& /*aOperation*/, TInt aError)
       
   956     {
       
   957     OperationFailed( aError );
       
   958     }
       
   959 
       
   960 // ----------------------------------------------------------------------------
       
   961 // Set member variables for sync operation
       
   962 // ----------------------------------------------------------------------------
       
   963 void CHgCtxContactMatcher::InitOperationL( TMethodId aMethod )
       
   964     {
       
   965     if ( iBackup )
       
   966         {
       
   967         User::Leave( KErrAccessDenied );
       
   968         }
       
   969 
       
   970     // Check whether operation is in progress
       
   971     if ( iApiMethodStatus == EExecuting )
       
   972         {
       
   973         User::Leave( KErrInUse );
       
   974         }
       
   975 
       
   976     iSync  = ETrue;
       
   977     iError = KErrNone;
       
   978     iApiMethod = aMethod;
       
   979     iApiMethodStatus = EIdle;
       
   980     }
       
   981 
       
   982 // ----------------------------------------------------------------------------
       
   983 // Set member variables for async operation
       
   984 // ----------------------------------------------------------------------------
       
   985 void CHgCtxContactMatcher::InitOperationL( TMethodId aMethod, TRequestStatus* aStatus )
       
   986     {
       
   987     InitOperationL( aMethod );
       
   988 
       
   989     iSync  = EFalse;
       
   990     iClientStatus  = aStatus;
       
   991     *iClientStatus = KRequestPending;
       
   992     }
       
   993     
       
   994 // ----------------------------------------------------------------------------
       
   995 // Set member variables for async operation
       
   996 // ----------------------------------------------------------------------------
       
   997 void CHgCtxContactMatcher::InitOperation( TRequestStatus* aStatus )
       
   998     {
       
   999     iSync  = EFalse;
       
  1000     iClientStatus  = aStatus;
       
  1001     *iClientStatus = KRequestPending;
       
  1002     }
       
  1003 
       
  1004 // ----------------------------------------------------------------------------
       
  1005 // Sync/async operation finished succesfully, return results to method caller.
       
  1006 // ----------------------------------------------------------------------------
       
  1007 void CHgCtxContactMatcher::OperationComplete( TInt aErrorCode )
       
  1008     {
       
  1009     if (iSync)
       
  1010         {
       
  1011         if ( iASchedulerWait.IsStarted() )
       
  1012             {
       
  1013             iASchedulerWait.AsyncStop();
       
  1014             }
       
  1015         }
       
  1016     else
       
  1017         {
       
  1018         if ( iClientStatus )
       
  1019             {
       
  1020             User::RequestComplete( iClientStatus, aErrorCode );
       
  1021             iClientStatus = NULL;
       
  1022             }
       
  1023         }
       
  1024     iApiMethodStatus = EFinished;
       
  1025     }
       
  1026 
       
  1027 // ----------------------------------------------------------------------------
       
  1028 // Sync/async operation failed, return results to method caller.
       
  1029 // ----------------------------------------------------------------------------
       
  1030 void CHgCtxContactMatcher::OperationFailed( TInt aError )
       
  1031     {
       
  1032     iError = aError;
       
  1033     OperationComplete( aError );
       
  1034     }
       
  1035 
       
  1036 // ----------------------------------------------------------------------------
       
  1037 // Free resources allocated for number matching
       
  1038 // ----------------------------------------------------------------------------
       
  1039 void CHgCtxContactMatcher::CleanupNumberMatch()
       
  1040 {
       
  1041     delete iMatchStrategy;
       
  1042     iMatchStrategy = NULL;
       
  1043 
       
  1044     delete iStratConfig;
       
  1045     iStratConfig = NULL;
       
  1046 
       
  1047     // store uris are not deleted here - opened array remains valid
       
  1048     // until new set of stores is opened.
       
  1049 }
       
  1050 
       
  1051 // ---------------------------------------------------------------------------
       
  1052 // CHgCtxContactMatcher::GetContactStoresL
       
  1053 // ---------------------------------------------------------------------------
       
  1054 EXPORT_C MVPbkContactStoreList& CHgCtxContactMatcher::GetContactStoresL()
       
  1055     {
       
  1056     return iContactManager->ContactStoresL();
       
  1057     }
       
  1058 
       
  1059 
       
  1060 // -----------------------------------------------------------------------------
       
  1061 // TInt CHgCtxContactMatcher::GetName
       
  1062 //
       
  1063 // Returns the formatted name fo the contact
       
  1064 // -----------------------------------------------------------------------------
       
  1065 EXPORT_C HBufC* CHgCtxContactMatcher::GetNameL( MVPbkStoreContactFieldCollection&
       
  1066                                                                 aFieldCollection )
       
  1067     {
       
  1068     MPbk2ContactNameFormatter& nameFormatter = ContactNameFormatterL();
       
  1069     
       
  1070     HBufC* formattedName = nameFormatter.GetContactTitleOrNullL( aFieldCollection, 
       
  1071     						                                     MPbk2ContactNameFormatter::EUseSeparator );
       
  1072     return formattedName;
       
  1073     }
       
  1074 
       
  1075 // -----------------------------------------------------------------------------
       
  1076 // CVPbkContactManager& CHgCtxContactMatcher::GetContactManager( )
       
  1077 // -----------------------------------------------------------------------------
       
  1078 EXPORT_C CVPbkContactManager& CHgCtxContactMatcher::GetContactManager()
       
  1079     {
       
  1080     return *iContactManager;
       
  1081     }
       
  1082     
       
  1083 
       
  1084 // ----------------------------------------------------------------------------
       
  1085 // Synchronous version
       
  1086 // ----------------------------------------------------------------------------
       
  1087 EXPORT_C void CHgCtxContactMatcher::MatchDataL( const TDesC& aData,
       
  1088     const MVPbkFieldTypeList& aFieldTypes,
       
  1089     CVPbkContactLinkArray& aLinkArray)
       
  1090     {
       
  1091     InitOperationL( EMatchData );
       
  1092     iResultContactLinkArray = &aLinkArray;
       
  1093 
       
  1094     // Start asynchronous matching and wait until results are ready
       
  1095     FreeOldOperation();
       
  1096     iOperation = iContactManager->FindL(aData, aFieldTypes, *this);
       
  1097     if ( iApiMethodStatus != EFinished )
       
  1098         {
       
  1099         iApiMethodStatus = EExecuting;
       
  1100         iASchedulerWait.Start();
       
  1101         }
       
  1102 
       
  1103     User::LeaveIfError( iError );
       
  1104     RemoveSimilarEmailAddressesL( aData, aLinkArray, aFieldTypes );
       
  1105    	}
       
  1106 
       
  1107 // ----------------------------------------------------------------------------
       
  1108 // Remove contacts that do not have exactly the correct email address
       
  1109 // e.g. if cbd@test.com address is requested, the for example a contact with address abcd@test.com will be removed
       
  1110 // from the result.
       
  1111 // This filtering is done only in the syncronous version of MatchDataL
       
  1112 // ----------------------------------------------------------------------------
       
  1113 void CHgCtxContactMatcher::RemoveSimilarEmailAddressesL( const TDesC& aData, CVPbkContactLinkArray& aLinkArray, const MVPbkFieldTypeList& aFieldTypes )
       
  1114     {
       
  1115     TVPbkFieldVersitProperty prop;
       
  1116     prop.SetName( EVPbkVersitNameEMAIL );
       
  1117     // do extra checks for email addresses
       
  1118     
       
  1119     const MVPbkFieldType* foundType = NULL;
       
  1120     // Continue only if at least one type is EVPbkVersitNameEMAIL
       
  1121     TInt i;
       
  1122     for ( i = 0 ; i < aFieldTypes.FieldTypeCount() ; i++ )
       
  1123         {
       
  1124         foundType = &(aFieldTypes.FieldTypeAt( i ));
       
  1125         if ( foundType->VersitProperties().Count() > 0
       
  1126             && foundType->VersitProperties()[0].Name() == prop.Name() )
       
  1127             {
       
  1128             break;
       
  1129             }
       
  1130         }
       
  1131     if ( i == aFieldTypes.FieldTypeCount() )
       
  1132     	{
       
  1133     	// no email types
       
  1134     	return;
       
  1135     	}
       
  1136     
       
  1137     const MVPbkFieldTypeList& fieldTypeList = FieldTypes();
       
  1138 
       
  1139     TInt index = 0;
       
  1140 	TBool isExactMatch;
       
  1141     while( index < aLinkArray.Count() )
       
  1142     	{
       
  1143 	    MVPbkStoreContact* storeContact;
       
  1144 	    GetStoreContactL( aLinkArray.At( index ), &storeContact );
       
  1145 	    storeContact->PushL();
       
  1146 	    
       
  1147 	    isExactMatch = EFalse;
       
  1148         for ( TInt i = 0; i < fieldTypeList.FieldTypeCount(); i++ )
       
  1149             {
       
  1150             // find the email property
       
  1151             foundType = &(fieldTypeList.FieldTypeAt( i ));
       
  1152             if ( foundType->VersitProperties().Count() > 0
       
  1153                 && foundType->VersitProperties()[0].Name() == prop.Name() )
       
  1154                 {
       
  1155                 TPtrC src = GetFieldDataTextL(*storeContact, *foundType );
       
  1156                 if ( aData.CompareF( src ) == 0 )
       
  1157         	    	{
       
  1158         	    	isExactMatch = ETrue;
       
  1159         	    	}
       
  1160                 }
       
  1161             }
       
  1162 	    if ( isExactMatch )
       
  1163             {
       
  1164             // go for the next contact
       
  1165             index++;
       
  1166             }
       
  1167         else
       
  1168         	{
       
  1169             // remove the contact, because the email address does not match the one queried. 
       
  1170             // the next one will take plce of this contact in the list (=do not increase index)
       
  1171             aLinkArray.Delete( index ); 
       
  1172         	}
       
  1173 	    CleanupStack::PopAndDestroy( storeContact );
       
  1174     	}
       
  1175     }
       
  1176 
       
  1177 // ----------------------------------------------------------------------------
       
  1178 // Asynchronous version
       
  1179 // ----------------------------------------------------------------------------
       
  1180 EXPORT_C void CHgCtxContactMatcher::MatchDataL( const TDesC& aData,
       
  1181     const MVPbkFieldTypeList& aFieldTypes,
       
  1182     CVPbkContactLinkArray& aLinkArray,
       
  1183     TRequestStatus& aStatus)
       
  1184     {
       
  1185     InitOperationL( EMatchData );
       
  1186     iResultContactLinkArray = &aLinkArray;
       
  1187 
       
  1188     // Start asynchronous matching
       
  1189     FreeOldOperation();
       
  1190     iOperation = iContactManager->FindL(aData, aFieldTypes, *this);
       
  1191     InitOperation( &aStatus );
       
  1192     if ( iApiMethodStatus != EFinished )
       
  1193         {
       
  1194         iApiMethodStatus = EExecuting;
       
  1195         }
       
  1196     }
       
  1197 // ----------------------------------------------------------------------------
       
  1198 // MatchData for searchstrings
       
  1199 // ----------------------------------------------------------------------------
       
  1200 EXPORT_C void CHgCtxContactMatcher::MatchDataL( const MDesC16Array& aSearchStrings,
       
  1201     const MVPbkFieldTypeList& aFieldTypes,
       
  1202     CVPbkContactLinkArray& aLinkArray,
       
  1203     const TCallBack& aWordParserCallBack )
       
  1204     {
       
  1205     InitOperationL( EMatchData );
       
  1206     iResultContactLinkArray = &aLinkArray;
       
  1207 
       
  1208     // Start asynchronous matching and wait here until results are ready
       
  1209     FreeOldOperation();
       
  1210     iOperation = iContactManager->FindL( aSearchStrings, aFieldTypes,
       
  1211         *this, aWordParserCallBack );
       
  1212 
       
  1213     if ( iApiMethodStatus != EFinished )
       
  1214         {
       
  1215         iApiMethodStatus = EExecuting;
       
  1216         iASchedulerWait.Start();
       
  1217         }
       
  1218     User::LeaveIfError( iError );
       
  1219     }
       
  1220 
       
  1221 // ----------------------------------------------------------------------------
       
  1222 // CHgCtxContactMatcher::ContactNameFormatterL
       
  1223 // ----------------------------------------------------------------------------
       
  1224 EXPORT_C MPbk2ContactNameFormatter& CHgCtxContactMatcher::ContactNameFormatterL()
       
  1225     {
       
  1226     //first initialise, if not already initialised
       
  1227     if ( !iSortOrderManager )
       
  1228         {
       
  1229         iSortOrderManager = CPbk2SortOrderManager::NewL( FieldTypes() );
       
  1230         }
       
  1231         
       
  1232     if ( !iNameFormatter )
       
  1233         {
       
  1234         iNameFormatter = Pbk2ContactNameFormatterFactory::CreateL( FieldTypes(),
       
  1235                                                                   *iSortOrderManager );
       
  1236         }
       
  1237     return *iNameFormatter;
       
  1238     }
       
  1239 
       
  1240 
       
  1241 // ---------------------------------------------------------------------------
       
  1242 // HgContactMatcherPanics::Panic
       
  1243 //
       
  1244 // Panic function
       
  1245 // ---------------------------------------------------------------------------
       
  1246 void HgContactMatcherPanics::Panic( TPanic aPanic )
       
  1247     {
       
  1248     _LIT(KPanicCategory, "ContactMatcher");
       
  1249     User::Panic( KPanicCategory, aPanic );
       
  1250     }
       
  1251 
       
  1252 // ----------------------------------------------------------------------------
       
  1253 // CHgCtxContactMatcher::SplitAndMatchL
       
  1254 // ----------------------------------------------------------------------------
       
  1255 EXPORT_C void CHgCtxContactMatcher::SplitAndMatchL( const TDesC& aData,
       
  1256         const MVPbkFieldTypeList& aFieldTypes,
       
  1257         CVPbkContactLinkArray& aLinkArray)
       
  1258     {
       
  1259     CDesCArray* wordArray = SplitFindStringL( aData );
       
  1260     CleanupStack::PushL( wordArray );
       
  1261     TCallBack findParser( FindWordSplitterL );
       
  1262     MatchDataL( *wordArray, aFieldTypes, aLinkArray, findParser );
       
  1263     CleanupStack::PopAndDestroy( wordArray );
       
  1264     }
       
  1265 
       
  1266 // ----------------------------------------------------------------------------
       
  1267 // CHgCtxContactMatcher::RegisterContactObserverL
       
  1268 // ----------------------------------------------------------------------------
       
  1269 EXPORT_C void CHgCtxContactMatcher::RegisterContactObserverL(
       
  1270         MHgCtxContactObserver& aObserver )
       
  1271     {
       
  1272     if ( iContactObservers.Find( &aObserver ) == KErrNotFound )
       
  1273         {
       
  1274         iContactObservers.AppendL( &aObserver );
       
  1275         }
       
  1276     }
       
  1277 
       
  1278 // ----------------------------------------------------------------------------
       
  1279 // CHgCtxContactMatcher::UnregisterContactObserver
       
  1280 // ----------------------------------------------------------------------------
       
  1281 EXPORT_C void CHgCtxContactMatcher::UnregisterContactObserver(
       
  1282         MHgCtxContactObserver& aObserver )
       
  1283     {
       
  1284     TInt pos = iContactObservers.Find( &aObserver );
       
  1285     if ( pos >= 0 )
       
  1286         {
       
  1287         iContactObservers.Remove( pos );
       
  1288         }
       
  1289     }
       
  1290 
       
  1291 // ----------------------------------------------------------------------------
       
  1292 // CHgCtxContactMatcher::LookupL
       
  1293 // ----------------------------------------------------------------------------
       
  1294 EXPORT_C void CHgCtxContactMatcher::LookupL( const TDesC& aData,
       
  1295         CVPbkContactLinkArray& aLinkArray )
       
  1296     {
       
  1297     HGLOG_CONTEXT( LookupL, HGLOG_LOCAL );
       
  1298     HGLOG1_IN( "'%S'", &aData );
       
  1299 
       
  1300     // Take part_A from "part_A <part_B>"
       
  1301     // or part_A from "part_A".
       
  1302     TPtrC input( aData );
       
  1303     TInt ltPos = input.Locate( '<' );
       
  1304     TInt gtPos = input.Locate( '>' );
       
  1305     if ( ltPos != KErrNotFound && gtPos> ltPos )
       
  1306         {
       
  1307         input.Set( aData.Mid( 0, ltPos ) );
       
  1308         }
       
  1309     HBufC* trimmedInput = input.AllocLC();
       
  1310     trimmedInput->Des().Trim();
       
  1311 
       
  1312     TInt oldCount = aLinkArray.Count();
       
  1313     if ( IsPhoneNumberL( *trimmedInput ) )
       
  1314         {
       
  1315         TryNumberLookupL( *trimmedInput, aLinkArray );
       
  1316         }
       
  1317     else
       
  1318         {
       
  1319         TryTextLookupL( *trimmedInput, aLinkArray );
       
  1320         }
       
  1321 
       
  1322     CleanupStack::PopAndDestroy( trimmedInput );
       
  1323 
       
  1324     if ( aLinkArray.Count() == oldCount && ltPos != KErrNotFound && gtPos > ltPos )
       
  1325         {
       
  1326         // lookup for part_A was not successful so try part_B
       
  1327         trimmedInput = aData.Mid( ltPos + 1, gtPos - ltPos - 1 ).AllocLC();
       
  1328         trimmedInput->Des().Trim();
       
  1329         if ( IsPhoneNumberL( *trimmedInput ) )
       
  1330             {
       
  1331             TryNumberLookupL( *trimmedInput, aLinkArray );
       
  1332             }
       
  1333         else
       
  1334             {
       
  1335             TryTextLookupL( *trimmedInput, aLinkArray );
       
  1336             }
       
  1337         CleanupStack::PopAndDestroy( trimmedInput );
       
  1338         }
       
  1339         
       
  1340     HGLOG1_OUT( "got %d results", aLinkArray.Count() - oldCount );
       
  1341     }
       
  1342 
       
  1343 // ----------------------------------------------------------------------------
       
  1344 // CHgCtxContactMatcher::PreCreateNameFieldTypesL
       
  1345 // ----------------------------------------------------------------------------
       
  1346 void CHgCtxContactMatcher::PreCreateNameFieldTypesL()
       
  1347     {
       
  1348     HGLOG_CONTEXT( PreCreateNameFieldTypesL, HGLOG_LOCAL );
       
  1349     HGLOG_IN();
       
  1350 
       
  1351     iNameFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1352     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1353     TVPbkFieldVersitProperty prop;
       
  1354     const MVPbkFieldType* t;
       
  1355 
       
  1356     prop.SetName( EVPbkVersitNameFN );
       
  1357     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1358     t = types.FindMatch( prop, 0 );
       
  1359     if ( t )
       
  1360         {
       
  1361         iNameFieldTypes->AppendL( *t );
       
  1362         HGLOG0( HGLOG_INFO, "will try FN" );
       
  1363         }
       
  1364 
       
  1365     prop.SetName( EVPbkVersitNameN );
       
  1366     prop.SetSubField( EVPbkVersitSubFieldGivenName );
       
  1367     t = types.FindMatch( prop, 0 );
       
  1368     if ( t )
       
  1369         {
       
  1370         iNameFieldTypes->AppendL( *t );
       
  1371         HGLOG0( HGLOG_INFO, "will try given name" );
       
  1372         }
       
  1373     
       
  1374     prop.SetName( EVPbkVersitNameN );
       
  1375     prop.SetSubField( EVPbkVersitSubFieldFamilyName );
       
  1376     t = types.FindMatch( prop, 0 );
       
  1377     if ( t )
       
  1378         {
       
  1379         iNameFieldTypes->AppendL( *t );
       
  1380         HGLOG0( HGLOG_INFO, "will try family name" );
       
  1381         }
       
  1382     
       
  1383     prop.SetName( EVPbkVersitNameORG );
       
  1384     prop.SetSubField( EVPbkVersitSubFieldOrgName );
       
  1385     t = types.FindMatch( prop, 0 );
       
  1386     if ( t )
       
  1387         {
       
  1388         iNameFieldTypes->AppendL( *t );
       
  1389         HGLOG0( HGLOG_INFO, "will try org name" );
       
  1390         }
       
  1391         
       
  1392     HGLOG_OUT();
       
  1393     }
       
  1394 
       
  1395 // ----------------------------------------------------------------------------
       
  1396 // CHgCtxContactMatcher::PreCreateEmailFieldTypesL
       
  1397 // ----------------------------------------------------------------------------
       
  1398 void CHgCtxContactMatcher::PreCreateEmailFieldTypesL()
       
  1399     {
       
  1400     HGLOG_CONTEXT( PreCreateEmailFieldTypesL, HGLOG_LOCAL );
       
  1401     HGLOG_IN();
       
  1402 
       
  1403     iEmailFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1404     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1405     TVPbkFieldVersitProperty prop;
       
  1406     const MVPbkFieldType* t;
       
  1407 
       
  1408     prop.SetName( EVPbkVersitNameEMAIL );
       
  1409     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1410     prop.Parameters().Reset();
       
  1411     prop.Parameters().Add( EVPbkVersitParamINTERNET );
       
  1412     t = types.FindMatch( prop, 0 );
       
  1413     if ( t )
       
  1414         {
       
  1415         iEmailFieldTypes->AppendL( *t );
       
  1416         HGLOG0( HGLOG_INFO, "will try general email" );
       
  1417         }
       
  1418 
       
  1419     prop.SetName( EVPbkVersitNameEMAIL );
       
  1420     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1421     prop.Parameters().Reset();
       
  1422     prop.Parameters().Add( EVPbkVersitParamINTERNET );
       
  1423     prop.Parameters().Add( EVPbkVersitParamWORK );
       
  1424     t = types.FindMatch( prop, 0 );
       
  1425     if ( t )
       
  1426         {
       
  1427         iEmailFieldTypes->AppendL( *t );
       
  1428         HGLOG0( HGLOG_INFO, "will try work email" );
       
  1429         }
       
  1430 
       
  1431     prop.SetName( EVPbkVersitNameEMAIL );
       
  1432     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1433     prop.Parameters().Reset();
       
  1434     prop.Parameters().Add( EVPbkVersitParamINTERNET );
       
  1435     prop.Parameters().Add( EVPbkVersitParamHOME );
       
  1436     t = types.FindMatch( prop, 0 );
       
  1437     if ( t )
       
  1438         {
       
  1439         iEmailFieldTypes->AppendL( *t );
       
  1440         HGLOG0( HGLOG_INFO, "will try home email" );
       
  1441         }
       
  1442         
       
  1443     HGLOG_OUT();
       
  1444     }
       
  1445 
       
  1446 // ----------------------------------------------------------------------------
       
  1447 // CHgCtxContactMatcher::PreCreateXspIdFieldTypesL
       
  1448 // ----------------------------------------------------------------------------
       
  1449 void CHgCtxContactMatcher::PreCreateXspIdFieldTypesL()
       
  1450     {
       
  1451     HGLOG_CONTEXT( PreCreateXspIdFieldTypesL, HGLOG_LOCAL );
       
  1452     HGLOG_IN();
       
  1453 
       
  1454     iXspIdFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1455     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1456     TVPbkFieldVersitProperty prop;
       
  1457     const MVPbkFieldType* t;
       
  1458 
       
  1459     prop.SetName( EVPbkVersitNameIMPP );
       
  1460     t = types.FindMatch( prop, 0 );
       
  1461     if ( t )
       
  1462         {
       
  1463         iXspIdFieldTypes->AppendL( *t );
       
  1464         }
       
  1465         
       
  1466     HGLOG1_OUT( "found %d xsp id field types",
       
  1467         iXspIdFieldTypes->FieldTypeCount() );
       
  1468     }
       
  1469 
       
  1470 // ----------------------------------------------------------------------------
       
  1471 // CHgCtxContactMatcher::PreCreateNumberFieldTypesL
       
  1472 // ----------------------------------------------------------------------------
       
  1473 void CHgCtxContactMatcher::PreCreateNumberFieldTypesL()
       
  1474     {
       
  1475     HGLOG_CONTEXT( PreCreateNumberFieldTypesL, HGLOG_LOCAL );
       
  1476     HGLOG_IN();
       
  1477 
       
  1478     iNumberFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1479     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1480     TVPbkFieldVersitProperty prop;
       
  1481     const MVPbkFieldType* t;
       
  1482 
       
  1483     prop.SetName( EVPbkVersitNameTEL );
       
  1484     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1485     prop.Parameters().Reset();
       
  1486     prop.Parameters().Add( EVPbkVersitParamCELL );
       
  1487     prop.Parameters().Add( EVPbkVersitParamHOME );
       
  1488     t = types.FindMatch( prop, 0 );
       
  1489     if ( t )
       
  1490         {
       
  1491         iNumberFieldTypes->AppendL( *t );
       
  1492         HGLOG0( HGLOG_INFO, "will try home mobile" );
       
  1493         }
       
  1494 
       
  1495     prop.SetName( EVPbkVersitNameTEL );
       
  1496     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1497     prop.Parameters().Reset();
       
  1498     prop.Parameters().Add( EVPbkVersitParamCELL );
       
  1499     prop.Parameters().Add( EVPbkVersitParamWORK );
       
  1500     t = types.FindMatch( prop, 0 );
       
  1501     if ( t )
       
  1502         {
       
  1503         iNumberFieldTypes->AppendL( *t );
       
  1504         HGLOG0( HGLOG_INFO, "will try work mobile" );
       
  1505         }
       
  1506 
       
  1507     prop.SetName( EVPbkVersitNameTEL );
       
  1508     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1509     prop.Parameters().Reset();
       
  1510     prop.Parameters().Add( EVPbkVersitParamCELL );
       
  1511     t = types.FindMatch( prop, 0 );
       
  1512     if ( t )
       
  1513         {
       
  1514         iNumberFieldTypes->AppendL( *t );
       
  1515         HGLOG0( HGLOG_INFO, "will try general mobile" );
       
  1516         }
       
  1517 
       
  1518     prop.SetName( EVPbkVersitNameTEL );
       
  1519     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1520     prop.Parameters().Reset();
       
  1521     prop.Parameters().Add( EVPbkVersitParamHOME );
       
  1522     t = types.FindMatch( prop, 0 );
       
  1523     if ( t )
       
  1524         {
       
  1525         iNumberFieldTypes->AppendL( *t );
       
  1526         HGLOG0( HGLOG_INFO, "will try home landline" );
       
  1527         }
       
  1528 
       
  1529     prop.SetName( EVPbkVersitNameTEL );
       
  1530     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1531     prop.Parameters().Reset();
       
  1532     prop.Parameters().Add( EVPbkVersitParamWORK );
       
  1533     t = types.FindMatch( prop, 0 );
       
  1534     if ( t )
       
  1535         {
       
  1536         iNumberFieldTypes->AppendL( *t );
       
  1537         HGLOG0( HGLOG_INFO, "will try work landline" );
       
  1538         }
       
  1539 
       
  1540     prop.SetName( EVPbkVersitNameTEL );
       
  1541     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  1542     prop.Parameters().Reset();
       
  1543     t = types.FindMatch( prop, 0 );
       
  1544     if ( t )
       
  1545         {
       
  1546         iNumberFieldTypes->AppendL( *t );
       
  1547         HGLOG0( HGLOG_INFO, "will try general landline" );
       
  1548         }
       
  1549         
       
  1550     HGLOG_OUT();
       
  1551     }
       
  1552 
       
  1553 // ----------------------------------------------------------------------------
       
  1554 // CHgCtxContactMatcher::PreCreateAddressFieldTypesL
       
  1555 // ----------------------------------------------------------------------------
       
  1556 void CHgCtxContactMatcher::PreCreateAddressFieldTypesL()
       
  1557     {
       
  1558     HGLOG_CONTEXT( PreCreateAddressFieldTypesL, HGLOG_LOCAL );
       
  1559     HGLOG_IN();
       
  1560 
       
  1561     iAddressFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1562     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1563     TVPbkFieldVersitProperty prop;
       
  1564     const MVPbkFieldType* t;
       
  1565 
       
  1566     prop.SetName( EVPbkVersitNameADR );
       
  1567     prop.SetSubField( EVPbkVersitSubFieldCountry );
       
  1568     t = types.FindMatch( prop, 0 );
       
  1569     if ( t )
       
  1570         {
       
  1571         iAddressFieldTypes->AppendL( *t );
       
  1572         HGLOG0( HGLOG_INFO, "will try general country" );
       
  1573         }
       
  1574 
       
  1575     prop.SetName( EVPbkVersitNameADR );
       
  1576     prop.SetSubField( EVPbkVersitSubFieldRegion );
       
  1577     t = types.FindMatch( prop, 0 );
       
  1578     if ( t )
       
  1579         {
       
  1580         iAddressFieldTypes->AppendL( *t );
       
  1581         HGLOG0( HGLOG_INFO, "will try general region" );
       
  1582         }
       
  1583 
       
  1584     prop.SetName( EVPbkVersitNameADR );
       
  1585     prop.SetSubField( EVPbkVersitSubFieldLocality );
       
  1586     t = types.FindMatch( prop, 0 );
       
  1587     if ( t )
       
  1588         {
       
  1589         iAddressFieldTypes->AppendL( *t );
       
  1590         HGLOG0( HGLOG_INFO, "will try general locality" );
       
  1591         }
       
  1592 
       
  1593     prop.SetName( EVPbkVersitNameADR );
       
  1594     prop.SetSubField( EVPbkVersitSubFieldStreet );
       
  1595     t = types.FindMatch( prop, 0 );
       
  1596     if ( t )
       
  1597         {
       
  1598         iAddressFieldTypes->AppendL( *t );
       
  1599         HGLOG0( HGLOG_INFO, "will try general street" );
       
  1600         }
       
  1601         
       
  1602     HGLOG_OUT();
       
  1603     }
       
  1604 
       
  1605 
       
  1606 // ----------------------------------------------------------------------------
       
  1607 // CHgCtxContactMatcher::PreCreateWebAddressFieldTypesL
       
  1608 // ----------------------------------------------------------------------------
       
  1609 void CHgCtxContactMatcher::PreCreateWebAddressFieldTypesL()
       
  1610     {
       
  1611     HGLOG_CONTEXT( PreCreateWebAddressFieldTypesL, HGLOG_LOCAL );
       
  1612     HGLOG_IN();
       
  1613 
       
  1614     iWebAddressFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1615     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1616     TVPbkFieldVersitProperty prop;
       
  1617     const MVPbkFieldType* t;
       
  1618 
       
  1619     prop.Parameters().Add( EVPbkVersitParamPREF );
       
  1620     prop.SetName( EVPbkVersitNameURL );
       
  1621     t = types.FindMatch( prop, 0 );
       
  1622     if ( t )
       
  1623         {
       
  1624         iWebAddressFieldTypes->AppendL( *t );
       
  1625         HGLOG0( HGLOG_INFO, "will try prefered url" );
       
  1626         }        
       
  1627     
       
  1628     HGLOG_OUT();
       
  1629     }
       
  1630 
       
  1631 // ----------------------------------------------------------------------------
       
  1632 // CHgCtxContactMatcher::PreCreateWebAddressFieldTypesL
       
  1633 // ----------------------------------------------------------------------------
       
  1634 void CHgCtxContactMatcher::PreCreateWebAddressHomeFieldTypesL()
       
  1635     {
       
  1636     HGLOG_CONTEXT( PreCreateWebAddressHomeFieldTypesL, HGLOG_LOCAL );
       
  1637     HGLOG_IN();
       
  1638 
       
  1639     iWebAddressHomeFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1640     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1641     TVPbkFieldVersitProperty prop;
       
  1642     const MVPbkFieldType* t;
       
  1643 
       
  1644     prop.Parameters().Add( EVPbkVersitParamHOME );
       
  1645     prop.SetName( EVPbkVersitNameURL );
       
  1646     t = types.FindMatch( prop, 0 );
       
  1647     if ( t )
       
  1648         {
       
  1649         iWebAddressHomeFieldTypes->AppendL( *t );
       
  1650         HGLOG0( HGLOG_INFO, "will try home url" );
       
  1651         }   
       
  1652     
       
  1653     HGLOG_OUT();
       
  1654     }
       
  1655 
       
  1656 // ----------------------------------------------------------------------------
       
  1657 // CHgCtxContactMatcher::PreCreateWebAddressFieldTypesL
       
  1658 // ----------------------------------------------------------------------------
       
  1659 void CHgCtxContactMatcher::PreCreateWebAddressWorkFieldTypesL()
       
  1660     {
       
  1661     HGLOG_CONTEXT( PreCreateWebAddressWorkFieldTypesL, HGLOG_LOCAL );
       
  1662     HGLOG_IN();
       
  1663 
       
  1664     iWebAddressWorkFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1665     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1666     TVPbkFieldVersitProperty prop;
       
  1667     const MVPbkFieldType* t;
       
  1668 
       
  1669     prop.Parameters().Add( EVPbkVersitParamWORK );
       
  1670     prop.SetName( EVPbkVersitNameURL );
       
  1671     t = types.FindMatch( prop, 0 );
       
  1672     if ( t )
       
  1673         {
       
  1674         iWebAddressWorkFieldTypes->AppendL( *t );
       
  1675         HGLOG0( HGLOG_INFO, "will try work url" );
       
  1676         }      
       
  1677     
       
  1678     HGLOG_OUT();
       
  1679     }
       
  1680 
       
  1681 // ----------------------------------------------------------------------------
       
  1682 // CHgCtxContactMatcher::PreCreateHomeAddressFieldTypesL
       
  1683 // ----------------------------------------------------------------------------
       
  1684 void CHgCtxContactMatcher::PreCreateHomeAddressFieldTypesL()
       
  1685     {
       
  1686     HGLOG_CONTEXT( PreCreateHomeAddressFieldTypesL, HGLOG_LOCAL );
       
  1687     HGLOG_IN();
       
  1688 
       
  1689     iHomeAddressFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1690     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1691     TVPbkFieldVersitProperty prop;
       
  1692     const MVPbkFieldType* t;
       
  1693     prop.Parameters().Add( EVPbkVersitParamHOME );
       
  1694 
       
  1695     prop.SetName( EVPbkVersitNameADR );
       
  1696     prop.SetSubField( EVPbkVersitSubFieldCountry );
       
  1697     t = types.FindMatch( prop, 0 );
       
  1698     if ( t )
       
  1699         {
       
  1700         iHomeAddressFieldTypes->AppendL( *t );
       
  1701         HGLOG0( HGLOG_INFO, "will try home country" );
       
  1702         }
       
  1703 
       
  1704     prop.SetName( EVPbkVersitNameADR );
       
  1705     prop.SetSubField( EVPbkVersitSubFieldRegion );
       
  1706     t = types.FindMatch( prop, 0 );
       
  1707     if ( t )
       
  1708         {
       
  1709         iHomeAddressFieldTypes->AppendL( *t );
       
  1710         HGLOG0( HGLOG_INFO, "will try home region" );
       
  1711         }
       
  1712 
       
  1713     prop.SetName( EVPbkVersitNameADR );
       
  1714     prop.SetSubField( EVPbkVersitSubFieldLocality );
       
  1715     t = types.FindMatch( prop, 0 );
       
  1716     if ( t )
       
  1717         {
       
  1718         iHomeAddressFieldTypes->AppendL( *t );
       
  1719         HGLOG0( HGLOG_INFO, "will try home locality" );
       
  1720         }
       
  1721 
       
  1722     prop.SetName( EVPbkVersitNameADR );
       
  1723     prop.SetSubField( EVPbkVersitSubFieldStreet );
       
  1724     t = types.FindMatch( prop, 0 );
       
  1725     if ( t )
       
  1726         {
       
  1727         iHomeAddressFieldTypes->AppendL( *t );
       
  1728         HGLOG0( HGLOG_INFO, "will try home street" );
       
  1729         }
       
  1730         
       
  1731     HGLOG_OUT();
       
  1732     }
       
  1733 
       
  1734 // ----------------------------------------------------------------------------
       
  1735 // CHgCtxContactMatcher::PreCreateWorkAddressFieldTypesL
       
  1736 // ----------------------------------------------------------------------------
       
  1737 void CHgCtxContactMatcher::PreCreateWorkAddressFieldTypesL()
       
  1738     {
       
  1739     HGLOG_CONTEXT( PreCreateWorkAddressFieldTypesL, HGLOG_LOCAL );
       
  1740     HGLOG_IN();
       
  1741 
       
  1742     iWorkAddressFieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1743     const MVPbkFieldTypeList& types( FieldTypes() );
       
  1744     TVPbkFieldVersitProperty prop;
       
  1745     const MVPbkFieldType* t;
       
  1746     prop.Parameters().Add( EVPbkVersitParamWORK );
       
  1747 
       
  1748     prop.SetName( EVPbkVersitNameADR );
       
  1749     prop.SetSubField( EVPbkVersitSubFieldCountry );
       
  1750     t = types.FindMatch( prop, 0 );
       
  1751     if ( t )
       
  1752         {
       
  1753         iWorkAddressFieldTypes->AppendL( *t );
       
  1754         HGLOG0( HGLOG_INFO, "will try work country" );
       
  1755         }
       
  1756 
       
  1757     prop.SetName( EVPbkVersitNameADR );
       
  1758     prop.SetSubField( EVPbkVersitSubFieldRegion );
       
  1759     t = types.FindMatch( prop, 0 );
       
  1760     if ( t )
       
  1761         {
       
  1762         iWorkAddressFieldTypes->AppendL( *t );
       
  1763         HGLOG0( HGLOG_INFO, "will try work region" );
       
  1764         }
       
  1765 
       
  1766     prop.SetName( EVPbkVersitNameADR );
       
  1767     prop.SetSubField( EVPbkVersitSubFieldLocality );
       
  1768     t = types.FindMatch( prop, 0 );
       
  1769     if ( t )
       
  1770         {
       
  1771         iWorkAddressFieldTypes->AppendL( *t );
       
  1772         HGLOG0( HGLOG_INFO, "will try work locality" );
       
  1773         }
       
  1774 
       
  1775     prop.SetName( EVPbkVersitNameADR );
       
  1776     prop.SetSubField( EVPbkVersitSubFieldStreet );
       
  1777     t = types.FindMatch( prop, 0 );
       
  1778     if ( t )
       
  1779         {
       
  1780         iWorkAddressFieldTypes->AppendL( *t );
       
  1781         HGLOG0( HGLOG_INFO, "will try work street" );
       
  1782         }
       
  1783         
       
  1784     HGLOG_OUT();
       
  1785     }
       
  1786 
       
  1787 // ----------------------------------------------------------------------------
       
  1788 // CHgCtxContactMatcher::TryTextLookupL
       
  1789 // ----------------------------------------------------------------------------
       
  1790 void CHgCtxContactMatcher::TryTextLookupL( const TDesC& aName,
       
  1791         CVPbkContactLinkArray& aLinkArray )
       
  1792     {
       
  1793     HGLOG_CONTEXT( TryTextLookupL, HGLOG_LOCAL );
       
  1794     HGLOG_IN();
       
  1795 
       
  1796     CVPbkFieldTypeRefsList* fieldTypes = CVPbkFieldTypeRefsList::NewL();
       
  1797     CleanupStack::PushL( fieldTypes );
       
  1798 
       
  1799     // try name and email and ovi id fields
       
  1800     if ( !iNameFieldTypes )
       
  1801         {
       
  1802         PreCreateNameFieldTypesL();
       
  1803         }
       
  1804     for ( TInt i = 0, ie = iNameFieldTypes->FieldTypeCount(); i != ie; ++i )
       
  1805         {
       
  1806         fieldTypes->AppendL( iNameFieldTypes->FieldTypeAt( i ) );
       
  1807         }
       
  1808     if ( !iEmailFieldTypes )
       
  1809         {
       
  1810         PreCreateEmailFieldTypesL();
       
  1811         }
       
  1812     for ( TInt i = 0, ie = iEmailFieldTypes->FieldTypeCount(); i != ie; ++i )
       
  1813         {
       
  1814         fieldTypes->AppendL( iEmailFieldTypes->FieldTypeAt( i ) );
       
  1815         }
       
  1816     if ( !iXspIdFieldTypes )
       
  1817         {
       
  1818         PreCreateXspIdFieldTypesL();
       
  1819         }
       
  1820     for ( TInt i = 0, ie = iXspIdFieldTypes->FieldTypeCount(); i != ie; ++i )
       
  1821         {
       
  1822         fieldTypes->AppendL( iXspIdFieldTypes->FieldTypeAt( i ) );
       
  1823         }
       
  1824 
       
  1825     SplitAndMatchL( aName, *fieldTypes, aLinkArray );
       
  1826 
       
  1827     CleanupStack::PopAndDestroy( fieldTypes );
       
  1828     HGLOG_OUT();
       
  1829     }
       
  1830 
       
  1831 // ----------------------------------------------------------------------------
       
  1832 // CHgCtxContactMatcher::TryNumberLookupL
       
  1833 // ----------------------------------------------------------------------------
       
  1834 void CHgCtxContactMatcher::TryNumberLookupL( const TDesC& aNumber,
       
  1835         CVPbkContactLinkArray& aLinkArray )
       
  1836     {
       
  1837     HGLOG_CONTEXT( TryNumberLookupL, HGLOG_LOCAL );
       
  1838     HGLOG_IN();
       
  1839     
       
  1840     MatchPhoneNumberL( aNumber,
       
  1841         KNumberMatchLenFromRight,
       
  1842         CVPbkPhoneNumberMatchStrategy::EVPbkMatchFlagsNone,
       
  1843         aLinkArray );
       
  1844         
       
  1845     HGLOG_OUT();
       
  1846     }
       
  1847 
       
  1848 // ----------------------------------------------------------------------------
       
  1849 // CHgCtxContactMatcher::GetTextFieldsL
       
  1850 // ----------------------------------------------------------------------------
       
  1851 void CHgCtxContactMatcher::GetTextFieldsL(
       
  1852         const CVPbkFieldTypeRefsList& aList,
       
  1853         const MVPbkStoreContactFieldCollection& aFieldCollection,
       
  1854         CDesCArray& aArray )
       
  1855     {
       
  1856     HGLOG_CONTEXT( GetTextFieldsL, HGLOG_LOCAL );
       
  1857     HGLOG_IN();
       
  1858         
       
  1859     for ( TInt i = 0, ie = aFieldCollection.FieldCount(); i != ie; ++i )
       
  1860         {
       
  1861         const MVPbkStoreContactField& field( aFieldCollection.FieldAt( i ) );
       
  1862         const MVPbkFieldType* type = field.BestMatchingFieldType();
       
  1863         if ( type && aList.ContainsSame( *type ) )
       
  1864             {
       
  1865             const MVPbkContactFieldData& fdata( field.FieldData() );
       
  1866             if ( fdata.DataType() == EVPbkFieldStorageTypeText )
       
  1867                 {
       
  1868                 const MVPbkContactFieldTextData& fdata2 =
       
  1869                     MVPbkContactFieldTextData::Cast( fdata );
       
  1870                 const TDesC& text( fdata2.Text() );
       
  1871                 aArray.AppendL( text );
       
  1872                 HGLOG1( HGLOG_INFO, "found: '%S'", &text );
       
  1873                 }
       
  1874             }
       
  1875         }
       
  1876         
       
  1877     HGLOG_OUT();
       
  1878     }
       
  1879 
       
  1880 // ----------------------------------------------------------------------------
       
  1881 // CHgCtxContactMatcher::GetNumbersL
       
  1882 // ----------------------------------------------------------------------------
       
  1883 EXPORT_C void CHgCtxContactMatcher::GetNumbersL(
       
  1884         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  1885         CDesCArray& aArray )
       
  1886     {
       
  1887     HGLOG_CONTEXT( GetNumbersL, HGLOG_LOCAL );
       
  1888     HGLOG_IN();
       
  1889 
       
  1890     if ( !iNumberFieldTypes )
       
  1891         {
       
  1892         PreCreateNumberFieldTypesL();
       
  1893         }
       
  1894     GetTextFieldsL( *iNumberFieldTypes, aFieldCollection, aArray );
       
  1895 
       
  1896     HGLOG_OUT();
       
  1897     }
       
  1898 
       
  1899 // ----------------------------------------------------------------------------
       
  1900 // CHgCtxContactMatcher::GetEmailAddressesL
       
  1901 // ----------------------------------------------------------------------------
       
  1902 EXPORT_C void CHgCtxContactMatcher::GetEmailAddressesL(
       
  1903         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  1904         CDesCArray& aArray )
       
  1905     {
       
  1906     HGLOG_CONTEXT( GetEmailAddressesL, HGLOG_LOCAL );
       
  1907     HGLOG_IN();
       
  1908 
       
  1909     if ( !iEmailFieldTypes )
       
  1910         {
       
  1911         PreCreateEmailFieldTypesL();
       
  1912         }
       
  1913     GetTextFieldsL( *iEmailFieldTypes, aFieldCollection, aArray );
       
  1914 
       
  1915     HGLOG_OUT();
       
  1916     }
       
  1917 
       
  1918 // ----------------------------------------------------------------------------
       
  1919 // CHgCtxContactMatcher::GetAddressesL
       
  1920 // ----------------------------------------------------------------------------
       
  1921 EXPORT_C void CHgCtxContactMatcher::GetAddressesL(
       
  1922         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  1923         CDesCArray& aArray )
       
  1924     {
       
  1925     HGLOG_CONTEXT( GetAddressesL, HGLOG_LOCAL );
       
  1926     HGLOG_IN();
       
  1927     
       
  1928     CDesC16ArrayFlat* arr = new ( ELeave ) CDesC16ArrayFlat( KArrayGranularity );
       
  1929     CleanupStack::PushL( arr );
       
  1930 
       
  1931     if ( !iAddressFieldTypes )
       
  1932         {
       
  1933         PreCreateAddressFieldTypesL();
       
  1934         }
       
  1935     GetTextFieldsL( *iAddressFieldTypes, aFieldCollection, *arr );
       
  1936     if ( arr->Count() )
       
  1937         {
       
  1938         HBufC* combined = CombineStringsLC( *arr );
       
  1939         aArray.AppendL( *combined );
       
  1940         HGLOG1( HGLOG_INFO, "added '%S'", combined );
       
  1941         CleanupStack::PopAndDestroy( combined );
       
  1942         }
       
  1943 
       
  1944     arr->Reset();
       
  1945     if ( !iHomeAddressFieldTypes )
       
  1946         {
       
  1947         PreCreateHomeAddressFieldTypesL();
       
  1948         }
       
  1949     GetTextFieldsL( *iHomeAddressFieldTypes, aFieldCollection, *arr );
       
  1950     if ( arr->Count() )
       
  1951         {
       
  1952         HBufC* combined = CombineStringsLC( *arr );
       
  1953         aArray.AppendL( *combined );
       
  1954         HGLOG1( HGLOG_INFO, "added '%S'", combined );
       
  1955         CleanupStack::PopAndDestroy( combined );
       
  1956         }
       
  1957 
       
  1958     arr->Reset();
       
  1959     if ( !iWorkAddressFieldTypes )
       
  1960         {
       
  1961         PreCreateWorkAddressFieldTypesL();
       
  1962         }
       
  1963     GetTextFieldsL( *iWorkAddressFieldTypes, aFieldCollection, *arr );
       
  1964     if ( arr->Count() )
       
  1965         {
       
  1966         HBufC* combined = CombineStringsLC( *arr );
       
  1967         aArray.AppendL( *combined );
       
  1968         HGLOG1( HGLOG_INFO, "added '%S'", combined );
       
  1969         CleanupStack::PopAndDestroy( combined );
       
  1970         }
       
  1971 
       
  1972     CleanupStack::PopAndDestroy( arr );
       
  1973     HGLOG_OUT();
       
  1974     }
       
  1975 
       
  1976 
       
  1977 // ----------------------------------------------------------------------------
       
  1978 // CHgCtxContactMatcher::GetWebAddressesL
       
  1979 // ----------------------------------------------------------------------------
       
  1980 EXPORT_C void CHgCtxContactMatcher::GetWebAddressesL(
       
  1981         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  1982         CDesCArray& aArray,
       
  1983         TWebAddressesType aType  )
       
  1984     {
       
  1985     HGLOG_CONTEXT( GetWebAddressesL, HGLOG_LOCAL );
       
  1986     HGLOG_IN();
       
  1987     CVPbkFieldTypeRefsList* addressFieldTypes( NULL );
       
  1988     
       
  1989     switch ( aType )
       
  1990         {
       
  1991         case EWebAddresses:
       
  1992             {
       
  1993             if ( !iWebAddressFieldTypes )
       
  1994                {
       
  1995                PreCreateWebAddressFieldTypesL();
       
  1996                }
       
  1997             addressFieldTypes = iWebAddressFieldTypes;
       
  1998             }
       
  1999             break;
       
  2000             
       
  2001         case EWebAddressesHome:
       
  2002             {
       
  2003             if ( !iWebAddressHomeFieldTypes )
       
  2004                {
       
  2005                PreCreateWebAddressHomeFieldTypesL();
       
  2006                }
       
  2007             addressFieldTypes = iWebAddressHomeFieldTypes;
       
  2008             }
       
  2009             break;
       
  2010 
       
  2011         case EWebAddressesWork:
       
  2012             {
       
  2013             if ( !iWebAddressWorkFieldTypes )
       
  2014                 {
       
  2015                 PreCreateWebAddressWorkFieldTypesL();
       
  2016                 }
       
  2017             addressFieldTypes = iWebAddressWorkFieldTypes;
       
  2018             }
       
  2019             break;
       
  2020             
       
  2021         default:
       
  2022             break;
       
  2023         }
       
  2024     
       
  2025     if( addressFieldTypes )
       
  2026         {
       
  2027         GetTextFieldsL( *addressFieldTypes, aFieldCollection, aArray );
       
  2028         }
       
  2029     
       
  2030     HGLOG_OUT();
       
  2031     }
       
  2032 
       
  2033 // ----------------------------------------------------------------------------
       
  2034 // CHgCtxContactMatcher::GetThumbnailL
       
  2035 // ----------------------------------------------------------------------------
       
  2036 EXPORT_C CFbsBitmap* CHgCtxContactMatcher::GetThumbnailL(
       
  2037         MVPbkStoreContactFieldCollection& aFieldCollection )
       
  2038     {
       
  2039     HGLOG_CONTEXT( GetThumbnailL, HGLOG_LOCAL );
       
  2040     HGLOG_IN();
       
  2041     
       
  2042     CFbsBitmap* result = 0;
       
  2043     TVPbkFieldVersitProperty prop;
       
  2044     prop.SetName( EVPbkVersitNamePHOTO );
       
  2045     const MVPbkFieldType* t = FieldTypes().FindMatch( prop, 0 );
       
  2046     if ( t )
       
  2047         {
       
  2048         HGLOG0( HGLOG_INFO, "photo field type found" );
       
  2049         for ( TInt i = 0, ie = aFieldCollection.FieldCount(); i != ie; ++i )
       
  2050             {
       
  2051             const MVPbkStoreContactField& field( aFieldCollection.FieldAt( i ) );
       
  2052             const MVPbkFieldType* type = field.BestMatchingFieldType();
       
  2053             if ( type && type->IsSame( *t ) )
       
  2054                 {
       
  2055                 const MVPbkContactFieldData& fdata( field.FieldData() );
       
  2056                 if ( fdata.DataType() == EVPbkFieldStorageTypeBinary )
       
  2057                     {
       
  2058                     HGLOG0( HGLOG_INFO, "found thumbnail" );
       
  2059                     const MVPbkContactFieldBinaryData& fdata2 =
       
  2060                         MVPbkContactFieldBinaryData::Cast( fdata );
       
  2061                     TPtrC8 data( fdata2.BinaryData() );
       
  2062                     CImageDecoder* decoder = 0;
       
  2063                     // DataNewL does not seem to work properly with
       
  2064                     // EOptionAlwaysThread, it will hang in WaitForRequest
       
  2065                     // for ever, at least in the panel app.
       
  2066                     // So write the image to a temporary file (duhhh...)
       
  2067                     // and use FileNewL.
       
  2068                     RFile f;
       
  2069                     TFileName tempFileName;
       
  2070                     iFsSession->CreatePrivatePath( EDriveC );
       
  2071                     iFsSession->PrivatePath( tempFileName );
       
  2072                     _LIT( KDriveC, "C:" );
       
  2073                     _LIT( KTempName, "hgctxthumb" );
       
  2074                     tempFileName.Insert( 0, KDriveC );
       
  2075                     tempFileName.Append( KTempName );
       
  2076                     HGLOG1( HGLOG_INFO, "tempfn='%S'", &tempFileName );
       
  2077                     User::LeaveIfError( f.Replace( *iFsSession, tempFileName,
       
  2078                                     EFileWrite ) );
       
  2079                     f.Write( data, data.Length() );
       
  2080                     f.Close();
       
  2081                     TRAPD( err, decoder = CImageDecoder::FileNewL( *iFsSession,
       
  2082                                     tempFileName,
       
  2083                                     CImageDecoder::EOptionAlwaysThread ) );
       
  2084                     HGLOG1( HGLOG_INFO, "decoder NewL result: %d", err );
       
  2085                     if ( err == KErrNone )
       
  2086                         {
       
  2087                         CleanupStack::PushL( decoder );
       
  2088                         result = new ( ELeave ) CFbsBitmap;
       
  2089                         CleanupStack::PushL( result );
       
  2090                         TSize sz( decoder->FrameInfo().iOverallSizeInPixels );
       
  2091                         TDisplayMode mode( decoder->FrameInfo().iFrameDisplayMode );
       
  2092                         HGLOG3( HGLOG_INFO, "size=%dx%d, mode=%d", sz.iWidth,
       
  2093                                 sz.iHeight, mode );
       
  2094                         User::LeaveIfError( result->Create( sz, mode ) );
       
  2095         
       
  2096                         TRequestStatus status;
       
  2097                         HGLOG0( HGLOG_INFO, "starting to convert" );
       
  2098                         decoder->Convert( &status, *result );
       
  2099                         User::WaitForRequest( status );
       
  2100                         HGLOG1( HGLOG_INFO, "decoder Convert result: %d",
       
  2101                                 status.Int() );
       
  2102                         CleanupStack::Pop( result );
       
  2103                         CleanupStack::PopAndDestroy( decoder );
       
  2104         
       
  2105                         if ( status.Int() != KErrNone )
       
  2106                             {
       
  2107                             delete result;
       
  2108                             result = 0;
       
  2109                             }
       
  2110                         else
       
  2111                             {
       
  2112                             // stop and return the bitmap
       
  2113                             break;
       
  2114                             }
       
  2115                         }                    
       
  2116                     }
       
  2117                 }
       
  2118             }
       
  2119         }
       
  2120         
       
  2121     HGLOG_OUT();
       
  2122     return result;
       
  2123     }
       
  2124 
       
  2125 // ----------------------------------------------------------------------------
       
  2126 // CHgCtxContactMatcher::IsPhoneNumberL
       
  2127 // ----------------------------------------------------------------------------
       
  2128 EXPORT_C TBool CHgCtxContactMatcher::IsPhoneNumberL( const TDesC& aData )
       
  2129     {
       
  2130     TBool result = EFalse;
       
  2131     CFindItemEngine::SFoundItem item;
       
  2132     CFindItemEngine* search = CFindItemEngine::NewL( aData,
       
  2133         CFindItemEngine::EFindItemSearchPhoneNumberBin );
       
  2134     if ( search->ItemCount() )
       
  2135         {
       
  2136         search->Item( item );
       
  2137         result = item.iStartPos == 0;
       
  2138         }
       
  2139     delete search;
       
  2140     return result;
       
  2141     }
       
  2142 
       
  2143 // ----------------------------------------------------------------------------
       
  2144 // CHgCtxContactMatcher::IsEmailAddressL
       
  2145 // ----------------------------------------------------------------------------
       
  2146 EXPORT_C TBool CHgCtxContactMatcher::IsEmailAddressL( const TDesC& aData )
       
  2147     {
       
  2148     TBool result = EFalse;
       
  2149     CFindItemEngine::SFoundItem item;
       
  2150     CFindItemEngine* search = CFindItemEngine::NewL( aData,
       
  2151         CFindItemEngine::EFindItemSearchMailAddressBin );
       
  2152     if ( search->ItemCount() )
       
  2153         {
       
  2154         search->Item( item );
       
  2155         result = item.iStartPos == 0;
       
  2156         }
       
  2157     delete search;
       
  2158     return result;
       
  2159     }
       
  2160 
       
  2161 // ----------------------------------------------------------------------------
       
  2162 // CHgCtxContactMatcher::GetNamesForFindL
       
  2163 // ----------------------------------------------------------------------------
       
  2164 EXPORT_C void CHgCtxContactMatcher::GetNamesForFindL(
       
  2165         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  2166         CDesCArray& aArray )
       
  2167     {
       
  2168     CVPbkFieldTypeRefsList* nameTypes = CVPbkFieldTypeRefsList::NewL();
       
  2169     CleanupStack::PushL( nameTypes );
       
  2170     const MVPbkFieldTypeList& types( FieldTypes() );
       
  2171     TVPbkFieldVersitProperty prop;
       
  2172     const MVPbkFieldType* t;
       
  2173     
       
  2174     prop.SetName( EVPbkVersitNameN );
       
  2175     prop.SetSubField( EVPbkVersitSubFieldGivenName );
       
  2176     t = types.FindMatch( prop, 0 );
       
  2177     if ( t )
       
  2178         {
       
  2179         nameTypes->AppendL( *t );
       
  2180         }
       
  2181     
       
  2182     prop.SetName( EVPbkVersitNameN );
       
  2183     prop.SetSubField( EVPbkVersitSubFieldFamilyName );
       
  2184     t = types.FindMatch( prop, 0 );
       
  2185     if ( t )
       
  2186         {
       
  2187         nameTypes->AppendL( *t );
       
  2188         }
       
  2189     
       
  2190     for ( TInt i = 0, ie = aFieldCollection.FieldCount(); i != ie; ++i )
       
  2191         {
       
  2192         const MVPbkStoreContactField& field( aFieldCollection.FieldAt( i ) );
       
  2193         t = field.MatchFieldType( 0 );
       
  2194         if ( t && nameTypes->ContainsSame( *t ) )
       
  2195             {
       
  2196             const MVPbkContactFieldData& fdata( field.FieldData() );
       
  2197             if ( fdata.DataType() == EVPbkFieldStorageTypeText )
       
  2198                 {
       
  2199                 const MVPbkContactFieldTextData& fdata2 =
       
  2200                     MVPbkContactFieldTextData::Cast( fdata );
       
  2201                 aArray.AppendL( fdata2.Text() );
       
  2202                 }
       
  2203             }
       
  2204         }
       
  2205 
       
  2206     CleanupStack::PopAndDestroy( nameTypes );
       
  2207     }
       
  2208 
       
  2209 // ----------------------------------------------------------------------------
       
  2210 // CHgCtxContactMatcher::GetNamesForFindL
       
  2211 // ----------------------------------------------------------------------------
       
  2212 EXPORT_C HBufC* CHgCtxContactMatcher::GetNamesForFindL(
       
  2213         MVPbkStoreContactFieldCollection& aFieldCollection )
       
  2214     {
       
  2215     CDesC16ArrayFlat* arr = new ( ELeave ) CDesC16ArrayFlat( KArrayGranularity );
       
  2216     CleanupStack::PushL( arr );
       
  2217     GetNamesForFindL( aFieldCollection, *arr );
       
  2218     HBufC* result = CombineStringsLC( *arr );
       
  2219     CleanupStack::Pop( result );
       
  2220     CleanupStack::PopAndDestroy( arr );
       
  2221     return result;
       
  2222     }
       
  2223 
       
  2224 // ----------------------------------------------------------------------------
       
  2225 // CHgCtxContactMatcher::SplitFindStringL
       
  2226 // ----------------------------------------------------------------------------
       
  2227 EXPORT_C CDesCArray* CHgCtxContactMatcher::SplitFindStringL(const TDesC& aFindString)
       
  2228     {
       
  2229 	CDesCArray* wordArray = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
       
  2230 	CleanupStack::PushL( wordArray );	
       
  2231 	
       
  2232     TVPbkWordParserCallbackParam parser( &aFindString, wordArray );
       
  2233 	FindWordSplitterL( &parser );
       
  2234 	
       
  2235 	CleanupStack::Pop(); // wordArray
       
  2236 	return parser.iWordArray;
       
  2237     }
       
  2238 
       
  2239 // ----------------------------------------------------------------------------
       
  2240 // CHgCtxContactMatcher::SplitMsgContactL
       
  2241 // ----------------------------------------------------------------------------
       
  2242 EXPORT_C void CHgCtxContactMatcher::SplitMsgContactL( const TDesC& aString,
       
  2243         CDesCArray& aArray )
       
  2244     {
       
  2245     TInt pos = aString.Locate( '<' );
       
  2246     if ( pos >= 0 )
       
  2247         {
       
  2248         // skip spaces before '<'
       
  2249         TInt endPos = pos - 1;
       
  2250         while ( endPos > 0 && TChar( aString[endPos] ).IsSpace() )
       
  2251             {
       
  2252             --endPos;
       
  2253             }
       
  2254         // take the text before '<'
       
  2255         aArray.AppendL( aString.Left( endPos + 1 ) );
       
  2256         // take the text between '<' and '>'
       
  2257         TInt closePos = aString.Locate( '>' );
       
  2258         if ( closePos > pos )
       
  2259             {
       
  2260             aArray.AppendL( aString.Mid( pos + 1, closePos - pos - 1 ) );
       
  2261             }
       
  2262         }
       
  2263     else
       
  2264         {
       
  2265         aArray.AppendL( aString );
       
  2266         }
       
  2267     }
       
  2268 
       
  2269 // ----------------------------------------------------------------------------
       
  2270 // CHgCtxContactMatcher::GetCustomFieldL
       
  2271 // ----------------------------------------------------------------------------
       
  2272 EXPORT_C void CHgCtxContactMatcher::GetCustomFieldL(
       
  2273         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  2274         CDesCArray& aArray,
       
  2275         TVPbkFieldTypeName aVersitName,
       
  2276         TVPbkFieldTypeParameter aVersitParam )
       
  2277     {
       
  2278     HGLOG_CONTEXT( GetCustomFieldL, HGLOG_LOCAL );
       
  2279     HGLOG_IN();
       
  2280     
       
  2281     CVPbkFieldTypeRefsList* typeList = GetCustomFieldTypeLC(
       
  2282         aVersitName, aVersitParam );
       
  2283 
       
  2284     GetTextFieldsL( *typeList, aFieldCollection, aArray );
       
  2285     
       
  2286     CleanupStack::PopAndDestroy( typeList );
       
  2287     HGLOG_OUT();
       
  2288     }
       
  2289 
       
  2290 // ----------------------------------------------------------------------------
       
  2291 // CHgCtxContactMatcher::GetCustomFieldTypeLC
       
  2292 // ----------------------------------------------------------------------------
       
  2293 EXPORT_C CVPbkFieldTypeRefsList* CHgCtxContactMatcher::GetCustomFieldTypeLC(
       
  2294         TVPbkFieldTypeName aVersitName,
       
  2295         TVPbkFieldTypeParameter aVersitParam )
       
  2296     {
       
  2297     HGLOG_CONTEXT( GetCustomFieldTypeLC, HGLOG_LOCAL );
       
  2298     HGLOG_IN();
       
  2299     
       
  2300     CVPbkFieldTypeRefsList* typeList = CVPbkFieldTypeRefsList::NewL();
       
  2301     CleanupStack::PushL( typeList );
       
  2302     const MVPbkFieldTypeList& types( FieldTypes() );
       
  2303     TVPbkFieldVersitProperty prop;
       
  2304     const MVPbkFieldType* t;
       
  2305 
       
  2306     prop.SetName( aVersitName );
       
  2307     prop.Parameters().Add( aVersitParam );
       
  2308     t = types.FindMatch( prop, 0 );
       
  2309     if ( t )
       
  2310         {
       
  2311         typeList->AppendL( *t );
       
  2312         HGLOG0( HGLOG_INFO, "field found" );
       
  2313         }
       
  2314 
       
  2315     HGLOG_OUT();
       
  2316     return typeList;
       
  2317     }
       
  2318 
       
  2319 // ----------------------------------------------------------------------------
       
  2320 // CHgCtxContactMatcher::GetImppFieldL
       
  2321 // ----------------------------------------------------------------------------
       
  2322 EXPORT_C void CHgCtxContactMatcher::GetImppFieldL(
       
  2323         MVPbkStoreContactFieldCollection& aFieldCollection,
       
  2324         CDesCArray* aSchemeOnlyArray,
       
  2325         CDesCArray* aUriOnlyArray,
       
  2326         CDesCArray* aFullArray )
       
  2327     {
       
  2328     HGLOG_CONTEXT( GetImppFieldL, HGLOG_LOCAL );
       
  2329     HGLOG_IN();
       
  2330 
       
  2331     // this function will not build on TUBE
       
  2332     CVPbkFieldTypeRefsList* typeList = CVPbkFieldTypeRefsList::NewL();
       
  2333     CleanupStack::PushL( typeList );
       
  2334     const MVPbkFieldTypeList& types( FieldTypes() );
       
  2335     TVPbkFieldVersitProperty prop;
       
  2336     const MVPbkFieldType* t;
       
  2337     prop.SetName( EVPbkVersitNameIMPP );
       
  2338     t = types.FindMatch( prop, 0 );
       
  2339     if ( t )
       
  2340         {
       
  2341         typeList->AppendL( *t );
       
  2342         HGLOG0( HGLOG_INFO, "type found" );
       
  2343         }
       
  2344     for ( TInt i = 0, ie = aFieldCollection.FieldCount(); i != ie; ++i )
       
  2345         {
       
  2346         const MVPbkStoreContactField& field( aFieldCollection.FieldAt( i ) );
       
  2347         const MVPbkFieldType* type = field.BestMatchingFieldType();
       
  2348         if ( type && typeList->ContainsSame( *type ) )
       
  2349             {
       
  2350             const MVPbkContactFieldData& fdata( field.FieldData() );
       
  2351             HGLOG1( HGLOG_INFO, "field found %d", fdata.DataType() );
       
  2352             if ( fdata.DataType() == EVPbkFieldStorageTypeUri )
       
  2353                 {
       
  2354                 const MVPbkContactFieldUriData& fdata2 =
       
  2355                     MVPbkContactFieldUriData::Cast( fdata );
       
  2356                 const TDesC& schemeOnly( fdata2.Scheme() );
       
  2357                 const TDesC& uriOnly( fdata2.Text() );
       
  2358                 const TDesC& fullText( fdata2.Uri() );
       
  2359                 HGLOG3( HGLOG_INFO, "'%S' + '%S' = '%S'",
       
  2360                     &schemeOnly, &uriOnly, &fullText );
       
  2361                 if ( aSchemeOnlyArray )
       
  2362                     {
       
  2363                     aSchemeOnlyArray->AppendL( schemeOnly );
       
  2364                     }
       
  2365                 if ( aUriOnlyArray )
       
  2366                     {
       
  2367                     aUriOnlyArray->AppendL( uriOnly );
       
  2368                     }
       
  2369                 if ( aFullArray )
       
  2370                     {
       
  2371                     aFullArray->AppendL( fullText );
       
  2372                     }
       
  2373                 }
       
  2374             }
       
  2375         }                    
       
  2376     CleanupStack::PopAndDestroy( typeList );
       
  2377     
       
  2378     HGLOG_OUT();
       
  2379     }
       
  2380 
       
  2381 // ----------------------------------------------------------------------------
       
  2382 // CHgCtxContactMatcher::FindContactWithBirthdayL
       
  2383 // ----------------------------------------------------------------------------
       
  2384 EXPORT_C void CHgCtxContactMatcher::FindContactWithBirthdayL(
       
  2385         const TTime& aDate,
       
  2386         CVPbkContactLinkArray& aLinkArray )
       
  2387     {
       
  2388     HGLOG_CONTEXT( FindContactWithBirthdayL, HGLOG_LOCAL );
       
  2389     HGLOG1_IN( "%Ld", aDate.Int64() );
       
  2390 
       
  2391     // extract month and day
       
  2392     TDateTime dt = aDate.DateTime();
       
  2393     TInt month = dt.Month();
       
  2394     TInt day = dt.Day();
       
  2395     HGLOG2( HGLOG_INFO, "wanted month = %d day = %d", month, day );
       
  2396 
       
  2397     CVPbkFieldTypeRefsList* emptyList = CVPbkFieldTypeRefsList::NewL();
       
  2398     CleanupStack::PushL( emptyList );
       
  2399 
       
  2400     // create view with all contacts
       
  2401     CVPbkContactViewDefinition* def = CVPbkContactViewDefinition::NewLC();
       
  2402     def->SetType( EVPbkContactsView );
       
  2403     def->SetUriL( VPbkContactStoreUris::DefaultCntDbUri() );
       
  2404     MVPbkContactViewBase* view = iContactManager->CreateContactViewLC(
       
  2405         *this, *def, *emptyList );
       
  2406 
       
  2407     HGLOG0( HGLOG_INFO, "starting wait" );
       
  2408     iASchedulerWait.Start();
       
  2409     HGLOG0( HGLOG_INFO, "after wait" );
       
  2410 
       
  2411     // view is ready
       
  2412     TInt ctCount = view->ContactCountL();
       
  2413     HGLOG1( HGLOG_INFO, "contact count: %d", ctCount );
       
  2414 
       
  2415     // find the birthday field type
       
  2416     const MVPbkFieldTypeList& types( FieldTypes() );
       
  2417     TVPbkFieldVersitProperty prop;
       
  2418     const MVPbkFieldType* bdayFt;
       
  2419     prop.SetName( EVPbkVersitNameBDAY );
       
  2420     prop.SetSubField( EVPbkVersitSubFieldNone );
       
  2421     bdayFt = types.FindMatch( prop, 0 );
       
  2422 
       
  2423     if ( bdayFt && ctCount )
       
  2424         {
       
  2425         HGLOG0( HGLOG_INFO, "found bday field type" );
       
  2426         TTime nullTime( KNullTime );
       
  2427         // go through all contacts and check birthday field values
       
  2428         for ( TInt i = 0; i < ctCount; ++i )
       
  2429             {
       
  2430             MVPbkContactLink* link( view->CreateLinkLC( i ) );
       
  2431             MVPbkStoreContact* contact = 0;
       
  2432             GetStoreContactL( *link, &contact );
       
  2433             if ( contact )
       
  2434                 {
       
  2435                 HGLOG1( HGLOG_INFO, "got contact, idx %d", i );
       
  2436                 contact->PushL();
       
  2437                 TTime bday;
       
  2438                 bday = GetFieldDataDateTimeL( *contact, *bdayFt );
       
  2439                 if ( bday != nullTime )
       
  2440                     {
       
  2441                     HGLOG1( HGLOG_INFO, "found bday %Ld", bday.Int64() );
       
  2442                     dt = bday.DateTime();
       
  2443                     TInt thisMonth = dt.Month();
       
  2444                     TInt thisDay = dt.Day();
       
  2445                     HGLOG2( HGLOG_INFO, "for this contact month = %d day = %d",
       
  2446                         thisMonth, thisDay );
       
  2447                     if ( thisMonth == month && thisDay == day )
       
  2448                         {
       
  2449                         HGLOG0( HGLOG_INFO, "match" );
       
  2450                         aLinkArray.AppendL( link );
       
  2451                         link = 0;
       
  2452                         }
       
  2453                     }
       
  2454                 CleanupStack::PopAndDestroy(); // contact
       
  2455                 }
       
  2456             CleanupStack::Pop(); // if matched then no ownership and link is NULL by now
       
  2457             delete link;
       
  2458             }
       
  2459         }
       
  2460 
       
  2461     CleanupStack::PopAndDestroy(); // view
       
  2462     CleanupStack::PopAndDestroy( def );
       
  2463     CleanupStack::PopAndDestroy( emptyList );
       
  2464 
       
  2465     HGLOG_OUT();
       
  2466     }
       
  2467 
       
  2468 // ----------------------------------------------------------------------------
       
  2469 // CHgCtxContactMatcher::ContactViewReady
       
  2470 // ----------------------------------------------------------------------------
       
  2471 void CHgCtxContactMatcher::ContactViewReady(
       
  2472         MVPbkContactViewBase& aView ) 
       
  2473     {
       
  2474     HGLOG_CONTEXT( ContactViewReady, HGLOG_LOCAL );
       
  2475     HGLOG_IN();
       
  2476 
       
  2477     if ( iASchedulerWait.IsStarted() )
       
  2478         {
       
  2479         iASchedulerWait.AsyncStop();
       
  2480         }
       
  2481 
       
  2482     aView.RemoveObserver( *this ); 
       
  2483 
       
  2484     HGLOG_OUT();
       
  2485     }
       
  2486 
       
  2487 // ----------------------------------------------------------------------------
       
  2488 // CHgCtxContactMatcher::ContactViewUnavailable
       
  2489 // ----------------------------------------------------------------------------
       
  2490 void CHgCtxContactMatcher::ContactViewUnavailable(
       
  2491         MVPbkContactViewBase& /*aView*/ )
       
  2492     {
       
  2493     // means that view is unavailable for now
       
  2494     // but ContactViewReady will be called at some point
       
  2495     }
       
  2496 
       
  2497 // ----------------------------------------------------------------------------
       
  2498 // CHgCtxContactMatcher::ContactAddedToView
       
  2499 // ----------------------------------------------------------------------------
       
  2500 void CHgCtxContactMatcher::ContactAddedToView(
       
  2501         MVPbkContactViewBase& /*aView*/, 
       
  2502         TInt /*aIndex*/,
       
  2503         const MVPbkContactLink& /*aContactLink*/ )
       
  2504     {
       
  2505     }
       
  2506 
       
  2507 // ----------------------------------------------------------------------------
       
  2508 // CHgCtxContactMatcher::ContactRemovedFromView
       
  2509 // ----------------------------------------------------------------------------
       
  2510  void CHgCtxContactMatcher::ContactRemovedFromView(
       
  2511         MVPbkContactViewBase& /*aView*/, 
       
  2512         TInt /*aIndex*/, 
       
  2513         const MVPbkContactLink& /*aContactLink*/ )
       
  2514     {
       
  2515     }
       
  2516 
       
  2517 // ----------------------------------------------------------------------------
       
  2518 // CHgCtxContactMatcher::ContactViewError
       
  2519 // ----------------------------------------------------------------------------
       
  2520  void CHgCtxContactMatcher::ContactViewError(
       
  2521         MVPbkContactViewBase& aView, 
       
  2522         TInt aError, 
       
  2523         TBool /*aErrorNotified*/ )
       
  2524     {
       
  2525     HGLOG_CONTEXT( ContactViewError, HGLOG_LOCAL );
       
  2526     HGLOG1_IN( "aError = %d", aError );
       
  2527 
       
  2528     if ( iASchedulerWait.IsStarted() )
       
  2529         {
       
  2530         iASchedulerWait.AsyncStop();
       
  2531         }
       
  2532 
       
  2533     aView.RemoveObserver( *this ); 
       
  2534     
       
  2535     HGLOG_OUT();
       
  2536     }
       
  2537 
       
  2538 
       
  2539 // End of File