messagingfw/msgcommonutils/src/contactmatcher.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 /*
       
     2 * Copyright (c) 2005-2006 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:   CContactMatcher class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // System includes
       
    21 #include <e32base.h>
       
    22 #include <bamdesca.h>
       
    23 #include <cntitem.h>
       
    24 #include <eikenv.h>
       
    25 #include <bautils.h>
       
    26 #include <data_caging_path_literals.hrh>
       
    27 
       
    28 #include <contactmatcher.h>
       
    29 
       
    30 #include <CVPbkContactManager.h>
       
    31 #include <MVPbkContactStoreList.h>
       
    32 #include <MVPbkContactStore.h>
       
    33 #include <CVPbkContactStoreUriArray.h>
       
    34 #include <MVPbkContactLinkArray.h>
       
    35 #include <MVPbkContactLink.h>
       
    36 #include <MVPbkFieldType.h>
       
    37 #include <MVPbkStoreContact.h>
       
    38 #include <MVPbkStoreContactField.h>
       
    39 #include <MVPbkStoreContactFieldCollection.h>
       
    40 #include <MVPbkContactFieldData.h>
       
    41 #include <MVPbkContactFieldTextData.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 
       
    53 #include <coemain.h>
       
    54 #include <CPbk2SortOrderManager.h>
       
    55 #include <Pbk2ContactNameFormatterFactory.h>
       
    56 
       
    57 #include <msgcommonutils.rsg>
       
    58 
       
    59 
       
    60 // ================= Static Constant Data ===================
       
    61 
       
    62 typedef const TDesC& (*UriFuncPtr)();
       
    63 
       
    64 // Number match store URIs in priority order.
       
    65 // When doing number matching, order of the stores in the uri array will
       
    66 // determine which stores are searched first (sequential match). We stop
       
    67 // the search when first match is found.
       
    68 static const UriFuncPtr NumberMatchStoreUris[] =
       
    69     {
       
    70     VPbkContactStoreUris::DefaultCntDbUri,
       
    71     // If we don't manage to open some store, we remove it from our array
       
    72     VPbkContactStoreUris::SimGlobalAdnUri,
       
    73     VPbkContactStoreUris::SimGlobalSdnUri,
       
    74     NULL,   // end marker
       
    75     };
       
    76 
       
    77 // All store URIs except own number store
       
    78 static const UriFuncPtr AllStoreUris[] =
       
    79     {
       
    80     VPbkContactStoreUris::DefaultCntDbUri,
       
    81     // If we don't manage to open some store, we remove it from our array
       
    82     VPbkContactStoreUris::SimGlobalAdnUri,
       
    83     VPbkContactStoreUris::SimGlobalSdnUri,
       
    84     VPbkContactStoreUris::SimGlobalFdnUri,
       
    85     NULL,   // end marker
       
    86     };
       
    87 
       
    88 // Own number store URIs
       
    89 static const UriFuncPtr OwnNumberStoreUris[] =
       
    90     {
       
    91     VPbkContactStoreUris::SimGlobalOwnNumberUri,
       
    92     NULL,   // end marker
       
    93     };
       
    94 
       
    95 _LIT(KMsgCommonUtilsResourceFileName, "msgcommonutils.rsc");
       
    96 
       
    97 // ================= MEMBER FUNCTIONS =======================
       
    98 
       
    99 // ----------------------------------------------------------------------------
       
   100 // Two-phase constructor for CContactMatcher class.
       
   101 // ----------------------------------------------------------------------------
       
   102 EXPORT_C CContactMatcher* CContactMatcher::NewL(
       
   103     RFs* aFsSession )
       
   104     {
       
   105     CContactMatcher* self = CContactMatcher::NewLC( aFsSession );
       
   106     CleanupStack::Pop(self);
       
   107     return self;
       
   108     }
       
   109 
       
   110 // ----------------------------------------------------------------------------
       
   111 // Two-phase constructor for CContactMatcher class.
       
   112 // ----------------------------------------------------------------------------
       
   113 EXPORT_C CContactMatcher* CContactMatcher::NewLC(
       
   114     RFs* aFsSession )
       
   115     {
       
   116     CContactMatcher* self = new ( ELeave ) CContactMatcher( aFsSession );
       
   117     CleanupStack::PushL(self);
       
   118     self->ConstructL();
       
   119     return self;
       
   120     }
       
   121 
       
   122 // ----------------------------------------------------------------------------
       
   123 // C++ destructor.
       
   124 // ----------------------------------------------------------------------------
       
   125 EXPORT_C CContactMatcher::~CContactMatcher()
       
   126     {
       
   127     FreeOldOperation();
       
   128     CleanupNumberMatch();
       
   129     delete iStoreUris;
       
   130     delete iContactManager;
       
   131     delete iSortOrderManager;
       
   132     delete iNameFormatter;
       
   133     iResourceFile.Close();
       
   134 
       
   135     if ( iClientStatus )
       
   136         {
       
   137         User::RequestComplete( iClientStatus, KErrCancel );
       
   138         }
       
   139     if ( iASchedulerWait.IsStarted() )
       
   140         {
       
   141         iASchedulerWait.AsyncStop();
       
   142         }
       
   143     }
       
   144 
       
   145 // ----------------------------------------------------------------------------
       
   146 // C++ Constructor.
       
   147 // ----------------------------------------------------------------------------
       
   148 CContactMatcher::CContactMatcher( RFs* aFsSession) : iFsSession( aFsSession )
       
   149     {
       
   150     }
       
   151 
       
   152 // ----------------------------------------------------------------------------
       
   153 // Second phase constructor
       
   154 // ----------------------------------------------------------------------------
       
   155 void CContactMatcher::ConstructL()
       
   156     {
       
   157     iContactManager = CVPbkContactManager::NewL(
       
   158         *CVPbkContactStoreUriArray::NewLC(), iFsSession );
       
   159     CleanupStack::PopAndDestroy(); // CVPbkContactStoreUriArray
       
   160 
       
   161     // No stores open yet
       
   162     iStoreUris = CVPbkContactStoreUriArray::NewL();
       
   163     }
       
   164 
       
   165 //******************* API-methods *********************************************
       
   166 
       
   167 // ----------------------------------------------------------------------------
       
   168 // Synchronous version
       
   169 // ----------------------------------------------------------------------------
       
   170 EXPORT_C void CContactMatcher::OpenStoreL(
       
   171     const CVPbkContactStoreUriArray& aUriArray )
       
   172     {
       
   173     InitOperationL( EOpenStore );
       
   174     OpenStoreCommonL( aUriArray );
       
   175     if ( iApiMethodStatus != EFinished )
       
   176         {
       
   177         iApiMethodStatus = EExecuting;
       
   178         // Wait until stores are open
       
   179         iASchedulerWait.Start();
       
   180         }
       
   181     User::LeaveIfError( iError );
       
   182     }
       
   183 
       
   184 // ----------------------------------------------------------------------------
       
   185 // Asynchronous version
       
   186 // ----------------------------------------------------------------------------
       
   187 EXPORT_C void CContactMatcher::OpenStoreL(
       
   188     const CVPbkContactStoreUriArray& aUriArray, TRequestStatus&  aStatus )
       
   189     {
       
   190     InitOperationL( EOpenStore );
       
   191     OpenStoreCommonL( aUriArray );
       
   192     InitOperation( &aStatus );
       
   193 
       
   194     if ( iApiMethodStatus != EFinished )
       
   195         {
       
   196         iApiMethodStatus = EExecuting;
       
   197         }
       
   198     }
       
   199 
       
   200 
       
   201 // ----------------------------------------------------------------------------
       
   202 // Common code to sync/async versions.
       
   203 // ----------------------------------------------------------------------------
       
   204 void CContactMatcher::OpenStoreCommonL(
       
   205     const CVPbkContactStoreUriArray& aUriArray )
       
   206     {
       
   207     if (iStoreUris->Count())
       
   208         {
       
   209         // Opening more stores when some stores are already open is not
       
   210         // supported. Support would require managing iStoreUris properly
       
   211         // so that it contains all open stores.
       
   212         User::Leave(KErrGeneral);
       
   213         }
       
   214 
       
   215     const TInt count = aUriArray.Count();
       
   216     
       
   217     for (TInt i = 0; i < count; ++i)
       
   218         {
       
   219         // Appended Uri:s to the array. If store fails to open it is removed
       
   220         // from the array. This keeps Uri's in priority order in the array.
       
   221         TVPbkContactStoreUriPtr uriPtr = aUriArray[i];
       
   222         iStoreUris->AppendL( uriPtr );
       
   223 
       
   224         iContactManager->LoadContactStoreL( uriPtr );
       
   225         }
       
   226     MVPbkContactStoreList& storeList = iContactManager->ContactStoresL();
       
   227     storeList.OpenAllL( *this );
       
   228     }
       
   229 
       
   230 // ----------------------------------------------------------------------------
       
   231 // Synchronous version
       
   232 // ----------------------------------------------------------------------------
       
   233 EXPORT_C void CContactMatcher::OpenAllStoresL()
       
   234     {
       
   235     OpenStoreL(AllStoreUris);
       
   236     }
       
   237 
       
   238 // ----------------------------------------------------------------------------
       
   239 // Asynchronous version
       
   240 // ----------------------------------------------------------------------------
       
   241 EXPORT_C void CContactMatcher::OpenAllStoresL( TRequestStatus& aStatus )
       
   242     {
       
   243     OpenStoreL(AllStoreUris, aStatus);
       
   244     }
       
   245 
       
   246 // ----------------------------------------------------------------------------
       
   247 // Synchronous version
       
   248 // ----------------------------------------------------------------------------
       
   249 EXPORT_C void CContactMatcher::OpenDefaultMatchStoresL()
       
   250     {
       
   251     OpenStoreL(NumberMatchStoreUris);
       
   252     }
       
   253 
       
   254 // ----------------------------------------------------------------------------
       
   255 // Asynchronous version
       
   256 // ----------------------------------------------------------------------------
       
   257 EXPORT_C void CContactMatcher::OpenDefaultMatchStoresL( TRequestStatus& aStatus )
       
   258     {
       
   259     OpenStoreL(NumberMatchStoreUris, aStatus);
       
   260     }
       
   261 
       
   262 // ----------------------------------------------------------------------------
       
   263 // Open OwnNumber stores.
       
   264 // Synchronous version
       
   265 // ----------------------------------------------------------------------------
       
   266 EXPORT_C void CContactMatcher::OpenOwnNumberStoresL()
       
   267     {
       
   268     OpenStoreL(OwnNumberStoreUris);
       
   269     }
       
   270 
       
   271 // ----------------------------------------------------------------------------
       
   272 // Open OwnNumber stores.
       
   273 // Asynchronous version
       
   274 // ----------------------------------------------------------------------------
       
   275 EXPORT_C void CContactMatcher::OpenOwnNumberStoresL( TRequestStatus& aStatus )
       
   276     {
       
   277     OpenStoreL(OwnNumberStoreUris, aStatus);
       
   278     }
       
   279 
       
   280 // ----------------------------------------------------------------------------
       
   281 // Close all open stores.
       
   282 // ----------------------------------------------------------------------------
       
   283 EXPORT_C void CContactMatcher::CloseStoresL()
       
   284     {
       
   285     // Closing stores does not work. MatchDataL() finds contacts from
       
   286     // closed stores.
       
   287 
       
   288     InitOperationL( ECloseStores );
       
   289 
       
   290     iApiMethodStatus = EExecuting;
       
   291     TRAPD( err, iContactManager->ContactStoresL().CloseAll( *this ) );
       
   292     iApiMethodStatus = EFinished;
       
   293     if ( err == KErrNone)
       
   294         {
       
   295         delete iStoreUris; iStoreUris = NULL;
       
   296         iStoreUris = CVPbkContactStoreUriArray::NewL();        
       
   297         }
       
   298     else
       
   299         {
       
   300         User::Leave(err);
       
   301         }
       
   302     }
       
   303 
       
   304 // ----------------------------------------------------------------------------
       
   305 // Synchronous version
       
   306 // ----------------------------------------------------------------------------
       
   307 EXPORT_C void CContactMatcher::MatchPhoneNumberL(
       
   308     const TDesC& aData, TInt aDigits,
       
   309     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags,
       
   310     CVPbkContactLinkArray& aLinkArray )
       
   311     {
       
   312     InitOperationL( EMatchPhoneNumber );
       
   313     iResultContactLinkArray = &aLinkArray;
       
   314 
       
   315     // Start asynchronous matching and wait until results are ready
       
   316     MatchPhoneNumberCommonL( aData, aDigits, aFlags );
       
   317     if ( iApiMethodStatus != EFinished )
       
   318         {
       
   319         iApiMethodStatus = EExecuting;
       
   320         iASchedulerWait.Start();
       
   321         }
       
   322     User::LeaveIfError( iError );
       
   323     }
       
   324 
       
   325 
       
   326 // ----------------------------------------------------------------------------
       
   327 // Asynchronous version
       
   328 // ----------------------------------------------------------------------------
       
   329 EXPORT_C void CContactMatcher::MatchPhoneNumberL(
       
   330     const TDesC& aData, TInt aDigits,
       
   331     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags,
       
   332     CVPbkContactLinkArray& aLinkArray, TRequestStatus& aStatus )
       
   333     {
       
   334     InitOperationL( EMatchPhoneNumber );
       
   335     iResultContactLinkArray = &aLinkArray;
       
   336     // Start asynchronous matching
       
   337     MatchPhoneNumberCommonL( aData, aDigits, aFlags );
       
   338     InitOperation( &aStatus );
       
   339     if ( iApiMethodStatus != EFinished )
       
   340         {
       
   341         iApiMethodStatus = EExecuting;
       
   342         }
       
   343     }
       
   344 
       
   345 // ----------------------------------------------------------------------------
       
   346 // Common code for sync and async versions
       
   347 // ----------------------------------------------------------------------------
       
   348 void CContactMatcher::MatchPhoneNumberCommonL(
       
   349     const TDesC& aData, TInt aDigits,
       
   350     CVPbkPhoneNumberMatchStrategy::TVPbkPhoneNumberMatchFlags aFlags )
       
   351     {
       
   352     // Delete resources allocated for previous match
       
   353     CleanupNumberMatch();
       
   354 
       
   355     // iStoreUris is filled when stores are opened
       
   356 
       
   357     iStratConfig = new (ELeave) CVPbkPhoneNumberMatchStrategy::TConfig(
       
   358         aDigits,
       
   359         *iStoreUris,
       
   360         CVPbkPhoneNumberMatchStrategy::EVPbkSequentialMatch,
       
   361         aFlags);
       
   362     iMatchStrategy = CVPbkPhoneNumberMatchStrategy::NewL(
       
   363                 *iStratConfig,
       
   364                 *iContactManager,
       
   365                 *this);
       
   366     // Start asynchronous matching
       
   367     iMatchStrategy->MatchL( aData );
       
   368     }
       
   369 
       
   370 
       
   371 // ----------------------------------------------------------------------------
       
   372 // Find from a store succeeded
       
   373 // ----------------------------------------------------------------------------
       
   374 void CContactMatcher::FindFromStoreSucceededL( MVPbkContactStore& /*aStore*/,
       
   375         MVPbkContactLinkArray* aResultsFromStore )
       
   376     {
       
   377     __ASSERT_DEBUG( aResultsFromStore, ContactMatcherPanics::Panic(
       
   378         ContactMatcherPanics::EPanNullPointer ));
       
   379 
       
   380     // Take the ownership of the result immediately
       
   381     CleanupDeletePushL( aResultsFromStore );
       
   382 
       
   383     CopyFindResultsL( aResultsFromStore );
       
   384 
       
   385     CleanupStack::PopAndDestroy(); // aResultsFromStore
       
   386     }
       
   387 
       
   388 // ----------------------------------------------------------------------------
       
   389 // Copy the found results for a store into array
       
   390 // ----------------------------------------------------------------------------
       
   391 void CContactMatcher::CopyFindResultsL( MVPbkContactLinkArray*
       
   392     aResults )
       
   393     {
       
   394     const TInt count = aResults->Count();
       
   395     if ( iResultContactLinkArray )
       
   396         {
       
   397         // Copy links to the member array
       
   398         for ( TInt i = 0; i < count; ++i )
       
   399             {
       
   400             iResultContactLinkArray->AppendL( aResults->At( i ).CloneLC() );
       
   401             CleanupStack::Pop(); // cloned link
       
   402             }
       
   403         }
       
   404     else
       
   405         {
       
   406         iResultContactLinkCnt += count;
       
   407         }
       
   408     }
       
   409 
       
   410 
       
   411 // ----------------------------------------------------------------------------
       
   412 // Find failed
       
   413 // ----------------------------------------------------------------------------
       
   414 void CContactMatcher::FindFromStoreFailed( MVPbkContactStore& /*aStore*/, TInt /*aError*/ )
       
   415     {
       
   416     //no operation, search to continue from the other stores
       
   417     }
       
   418 
       
   419 
       
   420 // ----------------------------------------------------------------------------
       
   421 // Find complete
       
   422 // ----------------------------------------------------------------------------
       
   423 void CContactMatcher::FindFromStoresOperationComplete()
       
   424     {
       
   425     if (!iResultContactLinkArray)
       
   426         {
       
   427         // Links were not copied. Result is whether any links found or not.
       
   428         OperationComplete( iResultContactLinkCnt ? KErrNone:KErrNotFound );
       
   429         }
       
   430     else
       
   431         {
       
   432         OperationComplete();
       
   433         iResultContactLinkArray = NULL;
       
   434         }
       
   435     }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 // Return global list of field types.
       
   439 // ----------------------------------------------------------------------------
       
   440 EXPORT_C const MVPbkFieldTypeList& CContactMatcher::FieldTypes() const
       
   441     {
       
   442     return iContactManager->FieldTypes();
       
   443     }
       
   444 
       
   445 // ----------------------------------------------------------------------------
       
   446 // Synchronous version
       
   447 // ----------------------------------------------------------------------------
       
   448 EXPORT_C void CContactMatcher::GetStoreContactL(
       
   449     const MVPbkContactLink& aLink, MVPbkStoreContact** aStoreContact )
       
   450     {
       
   451     InitOperationL( EGetStoreContact );
       
   452     iResultStoreContact = aStoreContact;
       
   453 
       
   454     // Start asynchronous operation and wait until results are ready
       
   455     FreeOldOperation();
       
   456     iOperation = iContactManager->RetrieveContactL( aLink, *this );
       
   457     if ( iApiMethodStatus != EFinished )
       
   458         {
       
   459         iApiMethodStatus = EExecuting;
       
   460         iASchedulerWait.Start();
       
   461         }
       
   462     User::LeaveIfError( iError );
       
   463     }
       
   464 
       
   465 // ----------------------------------------------------------------------------
       
   466 // Asynchronous version
       
   467 // ----------------------------------------------------------------------------
       
   468 EXPORT_C void CContactMatcher::GetStoreContactL(
       
   469     const MVPbkContactLink& aLink, MVPbkStoreContact** aStoreContact,
       
   470     TRequestStatus& aStatus )
       
   471     {
       
   472     InitOperationL( EGetStoreContact );
       
   473     iResultStoreContact = aStoreContact;
       
   474     // Start asynchronous operation
       
   475     FreeOldOperation();
       
   476     iOperation = iContactManager->RetrieveContactL( aLink, *this );
       
   477     InitOperation( &aStatus );
       
   478     if ( iApiMethodStatus != EFinished )
       
   479         {
       
   480         iApiMethodStatus = EExecuting;
       
   481         }
       
   482     }
       
   483 
       
   484 // ----------------------------------------------------------------------------
       
   485 // Synchronous version
       
   486 // ----------------------------------------------------------------------------
       
   487 EXPORT_C void CContactMatcher::IsOwnNumberL( const TDesC& aNumber, TBool& aResult )
       
   488     {
       
   489     InitOperationL( EMatchPhoneNumber );
       
   490 
       
   491      // Not interested in links, only whether found or not
       
   492     iResultContactLinkArray = NULL;
       
   493     iResultContactLinkCnt = 0;
       
   494 
       
   495     // Start asynchronous matching and wait until results are ready
       
   496     MatchPhoneNumberCommonL( aNumber, aNumber.Length(),
       
   497         CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag );
       
   498     if ( iApiMethodStatus != EFinished )
       
   499         {
       
   500         iApiMethodStatus = EExecuting;
       
   501         iASchedulerWait.Start();
       
   502         }
       
   503     User::LeaveIfError( iError );
       
   504 
       
   505     aResult = iResultContactLinkCnt > 0;
       
   506     }
       
   507 
       
   508 // ----------------------------------------------------------------------------
       
   509 // Asynchronous version
       
   510 // ----------------------------------------------------------------------------
       
   511 EXPORT_C void CContactMatcher::IsOwnNumberL( const TDesC& aNumber,
       
   512     TRequestStatus& aStatus )
       
   513     {
       
   514     InitOperationL( EMatchPhoneNumber );
       
   515 
       
   516      // Not interested in links, only whether found or not
       
   517     iResultContactLinkArray = NULL;
       
   518     iResultContactLinkCnt = 0;
       
   519 
       
   520     // Start asynchronous matching
       
   521     MatchPhoneNumberCommonL( aNumber, aNumber.Length(),
       
   522         CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag );
       
   523     InitOperation( &aStatus );
       
   524     if ( iApiMethodStatus != EFinished )
       
   525         {
       
   526         iApiMethodStatus = EExecuting;
       
   527         }
       
   528     }
       
   529 
       
   530 // ----------------------------------------------------------------------------
       
   531 // Cancel asynchronous operation
       
   532 // ----------------------------------------------------------------------------
       
   533 EXPORT_C void CContactMatcher::CancelOperation()
       
   534     {
       
   535     if (iApiMethodStatus != EExecuting)
       
   536         {
       
   537         return;
       
   538         }
       
   539 
       
   540     __ASSERT_DEBUG(!iSync, ContactMatcherPanics::Panic(
       
   541         ContactMatcherPanics::EPanInvalidOp));
       
   542 
       
   543     switch(iApiMethod)
       
   544         {
       
   545         case EMatchData:
       
   546         case EGetStoreContact:
       
   547             FreeOldOperation(); // deleting the operation cancels it
       
   548             break;
       
   549         case EMatchPhoneNumber:
       
   550             CleanupNumberMatch();
       
   551             break;
       
   552         default:
       
   553             ;
       
   554         }
       
   555 
       
   556     User::RequestComplete( iClientStatus, KErrCancel );
       
   557 
       
   558     iApiMethod = ENoMethod;
       
   559     iApiMethodStatus = EFinished;
       
   560     }
       
   561 
       
   562 // ----------------------------------------------------------------------------
       
   563 // GetFieldData, for EVPbkFieldStorageTypeText
       
   564 // ----------------------------------------------------------------------------
       
   565 EXPORT_C TPtrC CContactMatcher::GetFieldDataTextL(
       
   566     const MVPbkStoreContact& aContact,
       
   567     const MVPbkFieldType& aFType ) const
       
   568     {
       
   569     TPtrC ret(KNullDesC);
       
   570     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   571     if (field)
       
   572         {
       
   573         const MVPbkContactFieldData& fdata = field->FieldData();
       
   574         if (fdata.DataType() == EVPbkFieldStorageTypeText)
       
   575             {
       
   576             const MVPbkContactFieldTextData& fdata2 =
       
   577                 MVPbkContactFieldTextData::Cast(fdata);
       
   578             ret.Set( fdata2.Text() );
       
   579             }
       
   580         else
       
   581             {
       
   582             User::Leave( KErrArgument );
       
   583             }
       
   584         }
       
   585     return ret;
       
   586     }
       
   587 
       
   588 // ----------------------------------------------------------------------------
       
   589 // GetFieldData, for EVPbkFieldStorageTypeDateTime
       
   590 // ----------------------------------------------------------------------------
       
   591 EXPORT_C TTime CContactMatcher::GetFieldDataDateTimeL(
       
   592     const MVPbkStoreContact& aContact,
       
   593     const MVPbkFieldType& aFType ) const
       
   594     {
       
   595     //               YYYYMMDD:HHMMSS.MMMMMM
       
   596     _LIT(KNullTime, "11110000:010101.00000");
       
   597     TTime ret(KNullTime);
       
   598     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   599     if (field)
       
   600         {
       
   601         const MVPbkContactFieldData& fdata = field->FieldData();
       
   602         if (fdata.DataType() == EVPbkFieldStorageTypeDateTime)
       
   603             {
       
   604             const MVPbkContactFieldDateTimeData& fdata2 =
       
   605                 MVPbkContactFieldDateTimeData::Cast( fdata );
       
   606             ret = fdata2.DateTime();
       
   607             }
       
   608         else
       
   609             {
       
   610             User::Leave( KErrArgument );
       
   611             }
       
   612         }
       
   613     return ret;
       
   614     }
       
   615 
       
   616 // ----------------------------------------------------------------------------
       
   617 // GetFieldData, for EVPbkFieldStorageTypeBinary
       
   618 // ----------------------------------------------------------------------------
       
   619 EXPORT_C TPtrC8 CContactMatcher::GetFieldDataBinaryL(
       
   620     const MVPbkStoreContact& aContact,
       
   621     const MVPbkFieldType& aFType ) const
       
   622     {
       
   623     TPtrC8 ret(KNullDesC8);
       
   624     const MVPbkStoreContactField* field = FindField( aContact, aFType);
       
   625     if (field)
       
   626         {
       
   627         const MVPbkContactFieldData& fdata = field->FieldData();
       
   628         if (fdata.DataType() == EVPbkFieldStorageTypeBinary)
       
   629             {
       
   630             const MVPbkContactFieldBinaryData& fdata2 =
       
   631                 MVPbkContactFieldBinaryData::Cast( fdata );
       
   632             ret.Set( fdata2.BinaryData() );
       
   633             }
       
   634         else
       
   635             {
       
   636             User::Leave( KErrArgument );
       
   637             }
       
   638         }
       
   639     return ret;
       
   640     }
       
   641 
       
   642 
       
   643 //******************************** Private Methods ***************************
       
   644 
       
   645 // ----------------------------------------------------------------------------
       
   646 // Finds a field of given type from contact.
       
   647 // Returns pointer to field or NULL if not found.
       
   648 // ----------------------------------------------------------------------------
       
   649  const MVPbkStoreContactField* CContactMatcher::FindField(
       
   650     const MVPbkStoreContact& aContact,
       
   651     const MVPbkFieldType& aFType ) const
       
   652     {
       
   653     const MVPbkStoreContactFieldCollection& coll = aContact.Fields();
       
   654     TInt n = coll.FieldCount();
       
   655 
       
   656     const MVPbkStoreContactField* field = NULL;
       
   657     TBool bFound = EFalse;
       
   658     for(TInt i=0; i < n && !bFound; ++i)
       
   659         {
       
   660         field = &coll.FieldAt( i );
       
   661         const MVPbkFieldType* ftype = field->MatchFieldType( 0 );
       
   662         if ( ftype )
       
   663             {
       
   664             if ( ftype->IsSame( aFType ))
       
   665                 {
       
   666                 bFound = ETrue;
       
   667                 }
       
   668             }
       
   669         }
       
   670     if ( !bFound )
       
   671         {
       
   672         field = NULL;
       
   673         }
       
   674     return field;
       
   675     }
       
   676 
       
   677 // ----------------------------------------------------------------------------
       
   678 // Get URI array with stores
       
   679 // ----------------------------------------------------------------------------
       
   680 CVPbkContactStoreUriArray* CContactMatcher::GetStoreArrayLC(
       
   681     const TDesC& (* const aFuncPtrs[])() )
       
   682     {
       
   683     CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC();
       
   684 
       
   685     // Add stores
       
   686     for(TInt i = 0; aFuncPtrs[i]; i++)
       
   687         {
       
   688         TVPbkContactStoreUriPtr uriPtr(aFuncPtrs[i]());
       
   689         uriArray->AppendL(uriPtr);
       
   690         }
       
   691     return uriArray;
       
   692     }
       
   693 
       
   694 // ----------------------------------------------------------------------------
       
   695 // Open stores. Synchronous version
       
   696 // ----------------------------------------------------------------------------
       
   697 void CContactMatcher::OpenStoreL(const TDesC& (* const aFuncPtrs[])())
       
   698     {
       
   699     CVPbkContactStoreUriArray* uriArray = GetStoreArrayLC(aFuncPtrs);
       
   700 
       
   701     CContactMatcher::OpenStoreL(*uriArray);
       
   702     CleanupStack::PopAndDestroy(uriArray);
       
   703     }
       
   704 
       
   705 // ----------------------------------------------------------------------------
       
   706 // Open stores. Asynchronous version
       
   707 // ----------------------------------------------------------------------------
       
   708 void CContactMatcher::OpenStoreL(const TDesC& (* const aFuncPtrs[])(),
       
   709     TRequestStatus&  aStatus)
       
   710     {
       
   711     CVPbkContactStoreUriArray* uriArray = GetStoreArrayLC(aFuncPtrs);
       
   712 
       
   713     CContactMatcher::OpenStoreL(*uriArray, aStatus);
       
   714     CleanupStack::PopAndDestroy(uriArray);
       
   715     }
       
   716 
       
   717 // ----------------------------------------------------------------------------
       
   718 // Called when the opening process is complete,
       
   719 // ie. all stores have been reported either failed or successfully opened.
       
   720 // ----------------------------------------------------------------------------
       
   721 //
       
   722 void CContactMatcher::OpenComplete()
       
   723     {
       
   724     TInt error = KErrNone;
       
   725     if ( iStoreUris->Count() == 0 )
       
   726         {
       
   727         // unable to open any of the specified stores
       
   728         error = KErrNotSupported;
       
   729         }
       
   730     OperationComplete( error );
       
   731     }
       
   732 
       
   733 // ----------------------------------------------------------------------------
       
   734 // Called when a contact store is ready to use.
       
   735 // ----------------------------------------------------------------------------
       
   736 void CContactMatcher::StoreReady( MVPbkContactStore& /*aContactStore*/ )
       
   737     {
       
   738     }
       
   739 
       
   740 // ----------------------------------------------------------------------------
       
   741 // Called when a contact store becomes unavailable.
       
   742 // Client may inspect the reason of the unavailability and decide whether or not
       
   743 // it will keep the store opened (ie. listen to the store events).
       
   744 // @param aContactStore The store that became unavailable.
       
   745 // @param aReason The reason why the store is unavailable.
       
   746 //                This is one of the system wide error codes.
       
   747 // ----------------------------------------------------------------------------
       
   748 void CContactMatcher::StoreUnavailable( MVPbkContactStore& aContactStore,
       
   749     TInt /*aReason*/ )
       
   750     {
       
   751     // Remove contact store from uri list
       
   752     iStoreUris->Remove( aContactStore.StoreProperties().Uri() );
       
   753     }
       
   754 
       
   755 // ----------------------------------------------------------------------------
       
   756 // Called when changes occur in the contact store.
       
   757 // @see TVPbkContactStoreEvent
       
   758 //
       
   759 // @param aStoreEvent Event that has occured.
       
   760 // ----------------------------------------------------------------------------
       
   761 void CContactMatcher::HandleStoreEventL(
       
   762         MVPbkContactStore& /*aContactStore*/,
       
   763         TVPbkContactStoreEvent aStoreEvent)
       
   764     {
       
   765     // Contact and group events can be ignored, but we pass backup events for the observer.
       
   766     switch ( aStoreEvent.iEventType )
       
   767         {
       
   768         case TVPbkContactStoreEvent::EStoreBackupBeginning:
       
   769         case TVPbkContactStoreEvent::EStoreRestoreBeginning:
       
   770             {
       
   771             iBackup = ETrue;
       
   772             break;
       
   773             }
       
   774         case TVPbkContactStoreEvent::EStoreBackupRestoreCompleted:
       
   775             {
       
   776             iBackup = EFalse;
       
   777             break;
       
   778             }
       
   779         default:
       
   780             break;
       
   781         }
       
   782     }
       
   783 
       
   784 
       
   785 // ----------------------------------------------------------------------------
       
   786 // Called when find is complete. Callee takes ownership of the results.
       
   787 // In case of an error during find, the aResults may contain only
       
   788 // partial results of the find.
       
   789 //
       
   790 // @param aResults Array of contact links that matched the find.
       
   791 // ----------------------------------------------------------------------------
       
   792 void CContactMatcher::FindCompleteL( MVPbkContactLinkArray* aResults )
       
   793     {
       
   794     __ASSERT_DEBUG( aResults, ContactMatcherPanics::Panic(
       
   795         ContactMatcherPanics::EPanNullPointer ));
       
   796 
       
   797     // Take the ownership of the result immediately
       
   798     CleanupDeletePushL( aResults );
       
   799 
       
   800     CopyFindResultsL( aResults );
       
   801 
       
   802     CleanupStack::PopAndDestroy(); // aResults
       
   803 
       
   804     if (!iResultContactLinkArray)
       
   805         {
       
   806         // No need to copy links. Only interested whether found or not
       
   807         OperationComplete( iResultContactLinkCnt ? KErrNone:KErrNotFound );
       
   808         }
       
   809     else
       
   810         {
       
   811         OperationComplete();
       
   812         iResultContactLinkArray = NULL;
       
   813         }
       
   814     }
       
   815 
       
   816 // ----------------------------------------------------------------------------
       
   817 // Called in case the find fails for some reason.
       
   818 //
       
   819 // @param aError One of the system wide error codes.
       
   820 // ----------------------------------------------------------------------------
       
   821 void CContactMatcher::FindFailed( TInt aError )
       
   822     {
       
   823     OperationFailed( aError );
       
   824     iResultContactLinkArray = NULL;
       
   825     }
       
   826 
       
   827 // ----------------------------------------------------------------------------
       
   828 // Free old VPbk-operation.
       
   829 // ----------------------------------------------------------------------------
       
   830 void CContactMatcher::FreeOldOperation()
       
   831     {
       
   832     delete iOperation;
       
   833     iOperation = NULL;
       
   834     }
       
   835 
       
   836 // ----------------------------------------------------------------------------
       
   837 // Called when operation is completed.
       
   838 // ----------------------------------------------------------------------------
       
   839 void CContactMatcher::VPbkSingleContactOperationComplete(
       
   840         MVPbkContactOperationBase& /*aOperation*/, MVPbkStoreContact* aContact)
       
   841     {
       
   842     *iResultStoreContact = aContact;
       
   843     iResultStoreContact  = NULL;
       
   844     OperationComplete();
       
   845     }
       
   846 
       
   847 // ----------------------------------------------------------------------------
       
   848 // Called if the operation fails.
       
   849 // ----------------------------------------------------------------------------
       
   850 void CContactMatcher::VPbkSingleContactOperationFailed(
       
   851     MVPbkContactOperationBase& /*aOperation*/, TInt aError)
       
   852     {
       
   853     OperationFailed( aError );
       
   854     }
       
   855 
       
   856 // ----------------------------------------------------------------------------
       
   857 // Set member variables for sync operation
       
   858 // ----------------------------------------------------------------------------
       
   859 void CContactMatcher::InitOperationL( TMethodId aMethod )
       
   860     {
       
   861     if ( iBackup )
       
   862         {
       
   863         User::Leave( KErrAccessDenied );
       
   864         }
       
   865 
       
   866     // Check whether operation is in progress
       
   867     if ( iApiMethodStatus == EExecuting )
       
   868         {
       
   869         User::Leave( KErrInUse );
       
   870         }
       
   871 
       
   872     iSync  = ETrue;
       
   873     iError = KErrNone;
       
   874     iApiMethod = aMethod;
       
   875     iApiMethodStatus = EIdle;
       
   876     }
       
   877 
       
   878 // ----------------------------------------------------------------------------
       
   879 // Set member variables for async operation
       
   880 // ----------------------------------------------------------------------------
       
   881 void CContactMatcher::InitOperationL( TMethodId aMethod, TRequestStatus* aStatus )
       
   882     {
       
   883     InitOperationL( aMethod );
       
   884 
       
   885     iSync  = EFalse;
       
   886     iClientStatus  = aStatus;
       
   887     *iClientStatus = KRequestPending;
       
   888     }
       
   889     
       
   890 // ----------------------------------------------------------------------------
       
   891 // Set member variables for async operation
       
   892 // ----------------------------------------------------------------------------
       
   893 void CContactMatcher::InitOperation( TRequestStatus* aStatus )
       
   894     {
       
   895     iSync  = EFalse;
       
   896     iClientStatus  = aStatus;
       
   897     *iClientStatus = KRequestPending;
       
   898     }
       
   899 
       
   900 // ----------------------------------------------------------------------------
       
   901 // Sync/async operation finished succesfully, return results to method caller.
       
   902 // ----------------------------------------------------------------------------
       
   903 void CContactMatcher::OperationComplete( TInt aErrorCode )
       
   904     {
       
   905     if (iSync)
       
   906         {
       
   907         if ( iASchedulerWait.IsStarted() )
       
   908             {
       
   909             iASchedulerWait.AsyncStop();
       
   910             }
       
   911         }
       
   912     else
       
   913         {
       
   914         if ( iClientStatus )
       
   915             {
       
   916             User::RequestComplete( iClientStatus, aErrorCode );
       
   917             iClientStatus = NULL;
       
   918             }
       
   919         }
       
   920     iApiMethodStatus = EFinished;
       
   921     }
       
   922 
       
   923 // ----------------------------------------------------------------------------
       
   924 // Sync/async operation failed, return results to method caller.
       
   925 // ----------------------------------------------------------------------------
       
   926 void CContactMatcher::OperationFailed( TInt aError )
       
   927     {
       
   928     iError = aError;
       
   929     OperationComplete( aError );
       
   930     }
       
   931 
       
   932 // ----------------------------------------------------------------------------
       
   933 // Free resources allocated for number matching
       
   934 // ----------------------------------------------------------------------------
       
   935 void CContactMatcher::CleanupNumberMatch()
       
   936 {
       
   937     delete iMatchStrategy;
       
   938     iMatchStrategy = NULL;
       
   939 
       
   940     delete iStratConfig;
       
   941     iStratConfig = NULL;
       
   942 
       
   943     // store uris are not deleted here - opened array remains valid
       
   944     // until new set of stores is opened.
       
   945 }
       
   946 
       
   947 // ---------------------------------------------------------------------------
       
   948 // CContactMatcher::GetContactStoresL
       
   949 // ---------------------------------------------------------------------------
       
   950 EXPORT_C MVPbkContactStoreList& CContactMatcher::GetContactStoresL()
       
   951     {
       
   952     return iContactManager->ContactStoresL();
       
   953     }
       
   954 
       
   955 
       
   956 // -----------------------------------------------------------------------------
       
   957 // TInt CContactMatcher::GetName
       
   958 //
       
   959 // Returns the formatted name fo the contact
       
   960 // -----------------------------------------------------------------------------
       
   961 EXPORT_C HBufC* CContactMatcher::GetNameL( MVPbkStoreContactFieldCollection&
       
   962                                                                 aFieldCollection )
       
   963     {
       
   964     MPbk2ContactNameFormatter& nameFormatter = ContactNameFormatterL();
       
   965     
       
   966     HBufC* formattedName = nameFormatter.GetContactTitleOrNullL( aFieldCollection, 
       
   967     						                                     MPbk2ContactNameFormatter::EUseSeparator );
       
   968     return formattedName;
       
   969     }
       
   970 
       
   971 // -----------------------------------------------------------------------------
       
   972 // TInt CContactMatcher::ContactHasFieldOfTypeL( )
       
   973 // -----------------------------------------------------------------------------
       
   974 EXPORT_C TInt CContactMatcher::ContactHasFieldOfTypeL
       
   975         ( TAiwAddressSelectType aAddressSelectType,  const MVPbkStoreContact& aContact )
       
   976   {
       
   977     TInt resId = 0;
       
   978 
       
   979     switch ( aAddressSelectType )
       
   980         {
       
   981       case EAiwPhoneNumberSelect:
       
   982           resId = R_PHONE_NUMBER_SELECTOR;
       
   983           break;
       
   984       case EAiwEMailSelect:
       
   985           resId = R_EMAIL_ADDRESS_SELECTOR;
       
   986           break;
       
   987       case EAiwMMSSelect:
       
   988           resId = R_MMS_ADDRESS_SELECTOR;
       
   989           break;
       
   990       default:
       
   991           resId = R_PHONE_NUMBER_SELECTOR;
       
   992           break;
       
   993         }
       
   994 
       
   995     MVPbkContactFieldSelector* fieldTypeSelector =
       
   996           CreateFieldTypeSelectorLC( resId );
       
   997 
       
   998     // Check if the specified field type is included in the contact
       
   999     const MVPbkStoreContactFieldCollection& fields = aContact.Fields();
       
  1000   TInt fieldCount = fields.FieldCount();
       
  1001 
       
  1002   TInt ret = KErrNotFound;
       
  1003   for ( TInt i = 0; i < fieldCount && ret == KErrNotFound; ++i )
       
  1004     {
       
  1005     const MVPbkBaseContactField& field = fields.FieldAt( i );
       
  1006     if ( fieldTypeSelector->IsFieldIncluded( field ) )
       
  1007       {
       
  1008       ret = i;
       
  1009       }
       
  1010     }
       
  1011 
       
  1012   CleanupStack::PopAndDestroy(); // fieldTypeSelector
       
  1013 
       
  1014   return ret;
       
  1015   }
       
  1016 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CVPbkContactManager& CContactMatcher::GetContactManager( )
       
  1019 // -----------------------------------------------------------------------------
       
  1020 EXPORT_C CVPbkContactManager& CContactMatcher::GetContactManager()
       
  1021     {
       
  1022     return *iContactManager;
       
  1023     }
       
  1024     
       
  1025 
       
  1026 // ----------------------------------------------------------------------------
       
  1027 // Synchronous version
       
  1028 // ----------------------------------------------------------------------------
       
  1029 EXPORT_C void CContactMatcher::MatchDataL( const TDesC& aData,
       
  1030     const MVPbkFieldTypeList& aFieldTypes,
       
  1031     CVPbkContactLinkArray& aLinkArray)
       
  1032     {
       
  1033     InitOperationL( EMatchData );
       
  1034     iResultContactLinkArray = &aLinkArray;
       
  1035 
       
  1036     // Start asynchronous matching and wait until results are ready
       
  1037     FreeOldOperation();
       
  1038     iOperation = iContactManager->FindL(aData, aFieldTypes, *this);
       
  1039     if ( iApiMethodStatus != EFinished )
       
  1040         {
       
  1041         iApiMethodStatus = EExecuting;
       
  1042         iASchedulerWait.Start();
       
  1043         }
       
  1044 
       
  1045     User::LeaveIfError( iError );
       
  1046     RemoveSimilarEmailAddressesL( aData, aLinkArray, aFieldTypes );
       
  1047    	}
       
  1048 
       
  1049 // ----------------------------------------------------------------------------
       
  1050 // Remove contacts that do not have exactly the correct email address
       
  1051 // e.g. if cbd@test.com address is requested, the for example a contact with address abcd@test.com will be removed
       
  1052 // from the result.
       
  1053 // This filtering is done only in the syncronous version of MatchDataL
       
  1054 // ----------------------------------------------------------------------------
       
  1055 void CContactMatcher::RemoveSimilarEmailAddressesL( const TDesC& aData, CVPbkContactLinkArray& aLinkArray, const MVPbkFieldTypeList& aFieldTypes )
       
  1056     {
       
  1057     TVPbkFieldVersitProperty prop;
       
  1058     prop.SetName( EVPbkVersitNameEMAIL );
       
  1059     // do extra checks for email addresses
       
  1060     
       
  1061     const MVPbkFieldType* foundType = NULL;
       
  1062     // Continue only if at least one type is EVPbkVersitNameEMAIL
       
  1063     TInt i;
       
  1064     for ( i = 0 ; i < aFieldTypes.FieldTypeCount() ; i++ )
       
  1065         {
       
  1066         foundType = &(aFieldTypes.FieldTypeAt( i ));
       
  1067         if ( foundType->VersitProperties().Count() > 0
       
  1068             && foundType->VersitProperties()[0].Name() == prop.Name() )
       
  1069             {
       
  1070             break;
       
  1071             }
       
  1072         }
       
  1073     if ( i == aFieldTypes.FieldTypeCount() )
       
  1074     	{
       
  1075     	// no email types
       
  1076     	return;
       
  1077     	}
       
  1078     
       
  1079     const MVPbkFieldTypeList& fieldTypeList = FieldTypes();
       
  1080 
       
  1081     TInt index = 0;
       
  1082 	TBool isExactMatch;
       
  1083     while( index < aLinkArray.Count() )
       
  1084     	{
       
  1085 	    MVPbkStoreContact* storeContact;
       
  1086 	    GetStoreContactL( aLinkArray.At( index ), &storeContact );
       
  1087 	    storeContact->PushL();
       
  1088 	    
       
  1089 	    isExactMatch = EFalse;
       
  1090         for ( TInt i = 0; i < fieldTypeList.FieldTypeCount(); i++ )
       
  1091             {
       
  1092             // find the email property
       
  1093             foundType = &(fieldTypeList.FieldTypeAt( i ));
       
  1094             if ( foundType->VersitProperties().Count() > 0
       
  1095                 && foundType->VersitProperties()[0].Name() == prop.Name() )
       
  1096                 {
       
  1097                 TPtrC src = GetFieldDataTextL(*storeContact, *foundType );
       
  1098                 if ( aData.CompareF( src ) == 0 )
       
  1099         	    	{
       
  1100         	    	isExactMatch = ETrue;
       
  1101         	    	}
       
  1102                 }
       
  1103             }
       
  1104 	    if ( isExactMatch )
       
  1105             {
       
  1106             // go for the next contact
       
  1107             index++;
       
  1108             }
       
  1109         else
       
  1110         	{
       
  1111             // remove the contact, because the email address does not match the one queried. 
       
  1112             // the next one will take plce of this contact in the list (=do not increase index)
       
  1113             aLinkArray.Delete( index ); 
       
  1114         	}
       
  1115 	    CleanupStack::PopAndDestroy( storeContact );
       
  1116     	}
       
  1117     }
       
  1118 
       
  1119 // ----------------------------------------------------------------------------
       
  1120 // Asynchronous version
       
  1121 // ----------------------------------------------------------------------------
       
  1122 EXPORT_C void CContactMatcher::MatchDataL( const TDesC& aData,
       
  1123     const MVPbkFieldTypeList& aFieldTypes,
       
  1124     CVPbkContactLinkArray& aLinkArray,
       
  1125     TRequestStatus& aStatus)
       
  1126     {
       
  1127     InitOperationL( EMatchData );
       
  1128     iResultContactLinkArray = &aLinkArray;
       
  1129 
       
  1130     // Start asynchronous matching
       
  1131     FreeOldOperation();
       
  1132     iOperation = iContactManager->FindL(aData, aFieldTypes, *this);
       
  1133     InitOperation( &aStatus );
       
  1134     if ( iApiMethodStatus != EFinished )
       
  1135         {
       
  1136         iApiMethodStatus = EExecuting;
       
  1137         }
       
  1138     }
       
  1139 // ----------------------------------------------------------------------------
       
  1140 // MatchData for searchstrings
       
  1141 // ----------------------------------------------------------------------------
       
  1142 EXPORT_C void CContactMatcher::MatchDataL( const MDesC16Array& aSearchStrings,
       
  1143     const MVPbkFieldTypeList& aFieldTypes,
       
  1144     CVPbkContactLinkArray& aLinkArray,
       
  1145     const TCallBack& aWordParserCallBack )
       
  1146     {
       
  1147     InitOperationL( EMatchData );
       
  1148     iResultContactLinkArray = &aLinkArray;
       
  1149 
       
  1150     // Start asynchronous matching and wait here until results are ready
       
  1151     FreeOldOperation();
       
  1152     iOperation = iContactManager->FindL( aSearchStrings, aFieldTypes,
       
  1153         *this, aWordParserCallBack );
       
  1154 
       
  1155     if ( iApiMethodStatus != EFinished )
       
  1156         {
       
  1157         iApiMethodStatus = EExecuting;
       
  1158         iASchedulerWait.Start();
       
  1159         }
       
  1160     User::LeaveIfError( iError );
       
  1161     }
       
  1162 
       
  1163 // ----------------------------------------------------------------------------
       
  1164 // CContactMatcher::ContactNameFormatterL
       
  1165 // ----------------------------------------------------------------------------
       
  1166 EXPORT_C MPbk2ContactNameFormatter& CContactMatcher::ContactNameFormatterL()
       
  1167     {
       
  1168     //first initialise, if not already initialised
       
  1169     if ( !iSortOrderManager )
       
  1170         {
       
  1171         iSortOrderManager = CPbk2SortOrderManager::NewL( FieldTypes() );
       
  1172         }
       
  1173         
       
  1174     if ( !iNameFormatter )
       
  1175         {
       
  1176         iNameFormatter = Pbk2ContactNameFormatterFactory::CreateL( FieldTypes(),
       
  1177                                                                   *iSortOrderManager );
       
  1178         }
       
  1179     return *iNameFormatter;
       
  1180     }
       
  1181 
       
  1182 
       
  1183 // -----------------------------------------------------------------------------
       
  1184 // MVPbkContactFieldSelector* CContactMatcher::CreateFieldTypeSelectorLC( )
       
  1185 // -----------------------------------------------------------------------------
       
  1186 MVPbkContactFieldSelector* CContactMatcher::CreateFieldTypeSelectorLC
       
  1187   ( TInt aResId )
       
  1188   {
       
  1189     if ( !iResourceFileInitialized )
       
  1190         {
       
  1191         TFileName tmpName;
       
  1192         // Append the Resource Files Directory
       
  1193         tmpName.Append( KDC_RESOURCE_FILES_DIR );     
       
  1194         // Append the Ressource File Name
       
  1195         tmpName.Append( KMsgCommonUtilsResourceFileName );
       
  1196   
       
  1197         // Obtain the drive where the DLL is installed
       
  1198         TFileName dllDrive;
       
  1199         Dll::FileName( dllDrive );
       
  1200   
       
  1201         // Obtain the Complete path for the Resource File
       
  1202         TParse parse;
       
  1203         parse.Set( dllDrive, NULL, NULL );
       
  1204         parse.Set( parse.Drive(), &tmpName, NULL );
       
  1205         TFileName fileName;
       
  1206         fileName.Append( parse.FullName());
       
  1207 
       
  1208         iResourceFile.OpenL( *iFsSession, fileName );
       
  1209         iResourceFile.ConfirmSignatureL( 0 );
       
  1210         iResourceFileInitialized = ETrue;
       
  1211         }
       
  1212 
       
  1213     HBufC8* dataBuffer = iResourceFile.AllocReadLC( aResId );
       
  1214 
       
  1215     TResourceReader reader;
       
  1216     reader.SetBuffer( dataBuffer );
       
  1217 
       
  1218     CVPbkFieldTypeSelector* fieldTypeSelector =
       
  1219         CVPbkFieldTypeSelector::NewL( reader,
       
  1220                     FieldTypes() );
       
  1221 
       
  1222     CleanupStack::PopAndDestroy( dataBuffer );
       
  1223 
       
  1224     CleanupStack::PushL( fieldTypeSelector );
       
  1225     return fieldTypeSelector;
       
  1226     }
       
  1227 
       
  1228 // ---------------------------------------------------------------------------
       
  1229 // ContactMatcherPanics::Panic
       
  1230 //
       
  1231 // Panic function
       
  1232 // ---------------------------------------------------------------------------
       
  1233 void ContactMatcherPanics::Panic( TPanic aPanic )
       
  1234     {
       
  1235     _LIT(KPanicCategory, "ContactMatcher");
       
  1236     User::Panic( KPanicCategory, aPanic );
       
  1237     }
       
  1238 
       
  1239 // End of File