phonebookui/Phonebook2/UIPolicy/src/CPbk2ContactFindPolicy.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Phonebook 2 contact find policy.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CPbk2ContactFindPolicy.h"
       
    20 
       
    21 // Phonebook2 includes
       
    22 #include <CPbk2SortOrderManager.h>
       
    23 #include <MPbk2ContactNameFormatter.h>
       
    24 #include <MPbk2ContactNameFormatter2.h>
       
    25 #include <Pbk2ContactNameFormatterFactory.h>
       
    26 
       
    27 // Virtual phonebook includes
       
    28 #include <MVPbkBaseContact.h>
       
    29 #include <CVPbkFieldTypeRefsList.h>
       
    30 #include <CVPbkContactFieldIterator.h>
       
    31 #include <MVPbkContactFieldTextData.h>
       
    32 #include <VPbkContactStoreUris.h>
       
    33 #include <VPbkEng.rsg>
       
    34 #include <MVPbkContactFieldTextData.h>
       
    35 #include <MVPbkBaseContactFieldCollection.h>
       
    36 
       
    37 // System includes
       
    38 #include <FindUtil.h>
       
    39 #include <featmgr.h>
       
    40 
       
    41 // Constants
       
    42 const TInt KCountOfWords = 1;
       
    43 const TInt KMaxLengthOfTwoNameFields = 100;
       
    44 const TInt KDefaultTitleFormatting =
       
    45         MPbk2ContactNameFormatter::EPreserveLeadingSpaces;
       
    46 
       
    47 #ifdef _DEBUG
       
    48 enum TPanicCode
       
    49     {
       
    50     EPanicNullArray = 1
       
    51     };
       
    52 
       
    53 void Panic( TPanicCode aReason )
       
    54     {
       
    55     _LIT( KPanicText, "CPbk2ContactFindPolicy" );
       
    56     User::Panic( KPanicText, aReason );
       
    57     }
       
    58 #endif // _DEBUG
       
    59 
       
    60 // --------------------------------------------------------------------------
       
    61 // CPbk2ContactFindPolicy::CPbk2ContactFindPolicy
       
    62 // --------------------------------------------------------------------------
       
    63 //
       
    64 CPbk2ContactFindPolicy::CPbk2ContactFindPolicy()
       
    65     {
       
    66     }
       
    67 
       
    68 // --------------------------------------------------------------------------
       
    69 // CPbk2ContactFindPolicy::~CPbk2ContactFindPolicy
       
    70 // --------------------------------------------------------------------------
       
    71 //
       
    72 CPbk2ContactFindPolicy::~CPbk2ContactFindPolicy()
       
    73     {
       
    74     delete iFindUtil;
       
    75     delete iSortOrderManager;
       
    76     delete iNameFormatter;
       
    77     delete iFieldTypeRefsList;
       
    78     FeatureManager::UnInitializeLib();
       
    79     }
       
    80 
       
    81 // --------------------------------------------------------------------------
       
    82 // CPbk2ContactFindPolicy::NewL
       
    83 // --------------------------------------------------------------------------
       
    84 //
       
    85 CPbk2ContactFindPolicy* CPbk2ContactFindPolicy::NewL( TParam* aParam )
       
    86     {
       
    87     CPbk2ContactFindPolicy* self = new ( ELeave ) CPbk2ContactFindPolicy();
       
    88     CleanupStack::PushL( self );
       
    89     self->ConstructL( aParam );
       
    90     CleanupStack::Pop( self );
       
    91     return self;
       
    92     }
       
    93 
       
    94 // --------------------------------------------------------------------------
       
    95 // CPbk2ContactFindPolicy::ConstructL
       
    96 // --------------------------------------------------------------------------
       
    97 //
       
    98 inline void CPbk2ContactFindPolicy::ConstructL( TParam* aParam )
       
    99     {
       
   100     iFindUtil = CFindUtil::NewL();
       
   101     
       
   102     if ( aParam )
       
   103         {
       
   104         // Create sort order manager
       
   105         iSortOrderManager = CPbk2SortOrderManager::NewL(
       
   106             aParam->iFieldTypeList, &aParam->iRFs );
       
   107         
       
   108         // Create contact name formatter
       
   109         iNameFormatter = Pbk2ContactNameFormatterFactory::CreateL(
       
   110             aParam->iFieldTypeList, *iSortOrderManager, &aParam->iRFs );
       
   111             
       
   112         //Create field type list
       
   113         iFieldTypeRefsList = CVPbkFieldTypeRefsList::NewL();
       
   114         }
       
   115     FeatureManager::InitializeLibL();
       
   116     }
       
   117 
       
   118 // --------------------------------------------------------------------------
       
   119 // CPbk2ContactFindPolicy::Match
       
   120 // --------------------------------------------------------------------------
       
   121 //
       
   122 TBool CPbk2ContactFindPolicy::Match
       
   123         ( const TDesC& aText, const TDesC& aSearchString )
       
   124     {
       
   125     return iFindUtil->Interface()->Match( aText, aSearchString );
       
   126     }
       
   127 
       
   128 // --------------------------------------------------------------------------
       
   129 // CPbk2ContactFindPolicy::MatchContactNameL
       
   130 // --------------------------------------------------------------------------
       
   131 //
       
   132 TBool CPbk2ContactFindPolicy::MatchContactNameL( 
       
   133     const MDesCArray& aFindWords,
       
   134     const MVPbkBaseContact& aContact )
       
   135     {
       
   136     // This class constructed without aParam, so iNameFormatter
       
   137     // doesn't exist. Let's leave.
       
   138     if ( !iNameFormatter )
       
   139         {
       
   140         User::Leave( KErrNotSupported );
       
   141         }
       
   142     
       
   143     TBool match( ETrue );
       
   144     TInt findWordsCount = aFindWords.MdcaCount();
       
   145     const TInt KGranularity = 4; 
       
   146     CDesCArrayFlat* allNamesArray = new ( ELeave ) CDesCArrayFlat
       
   147         ( KGranularity );
       
   148     CleanupStack::PushL( allNamesArray );
       
   149 
       
   150     HBufC* title = NULL;
       
   151     if( FeatureManager::FeatureSupported(KFeatureIdFfContactsCompanyNames) )
       
   152         {
       
   153         MPbk2ContactNameFormatter2* nameformatterExtension =
       
   154             reinterpret_cast<MPbk2ContactNameFormatter2*>(iNameFormatter->
       
   155                     ContactNameFormatterExtension( MPbk2ContactNameFormatterExtension2Uid ) );
       
   156         title = nameformatterExtension->GetContactTitleWithCompanyNameL( aContact.Fields(),
       
   157                 KDefaultTitleFormatting );
       
   158         } 
       
   159     else
       
   160         {
       
   161         title = iNameFormatter->GetContactTitleL( aContact.Fields(), 
       
   162                 KDefaultTitleFormatting );
       
   163         }
       
   164 
       
   165     CleanupStack::PushL( title );
       
   166         
       
   167     if ( title->Length() )
       
   168     	{
       
   169     	SplitContactFieldTextIntoArrayL( allNamesArray, *title );
       
   170     	}
       
   171     else 
       
   172     	{
       
   173     	//If FDN contact, no name, use phonenumber as title if exists
       
   174     	GetTitleFromFDNNumberL( aContact, *allNamesArray );
       
   175     	}   
       
   176 
       
   177     CleanupStack::PopAndDestroy( title );
       
   178 
       
   179     // Match every search word in contact's fields. 
       
   180     if ( findWordsCount <= allNamesArray->MdcaCount() )
       
   181         {
       
   182         for ( TInt i = 0; i < findWordsCount && match; ++i )
       
   183             {
       
   184             for ( TInt j = 0; j < allNamesArray->MdcaCount(); ++j )   
       
   185                 {
       
   186                 // Match refine
       
   187                 if ( !MatchRefineL( allNamesArray->MdcaPoint( j ), 
       
   188                         aFindWords.MdcaPoint( i ) ) )
       
   189                     {
       
   190                     match = EFalse;
       
   191                     }
       
   192                 else
       
   193                     {
       
   194                     // Match is found, delete it from array to prevent 
       
   195                     // matching with the same word again
       
   196                     match = ETrue;
       
   197                     allNamesArray->Delete( j );
       
   198                     break;
       
   199                     }  
       
   200                 }            
       
   201             }   
       
   202         }
       
   203     else
       
   204         {
       
   205         // More search words than name fields, can't match
       
   206         match = EFalse;
       
   207         }
       
   208     
       
   209         
       
   210     // Special case when searching names in China variant:
       
   211     // Last and first names are merged and search must find
       
   212     // names without typing space between them.
       
   213     if ( findWordsCount == KCountOfWords && !match )
       
   214         {
       
   215         FeatureManager::InitializeLibL();
       
   216         TBool chinese = FeatureManager::FeatureSupported( KFeatureIdChinese );
       
   217         FeatureManager::UnInitializeLib();
       
   218         
       
   219         TBool korean = (User::Language() == ELangKorean);
       
   220 
       
   221         if ( chinese || korean )
       
   222             {
       
   223             match = MatchChineseContactNameL( aFindWords, aContact );
       
   224             }
       
   225         }
       
   226     
       
   227     CleanupStack::PopAndDestroy( allNamesArray );
       
   228     return match;
       
   229     }
       
   230 
       
   231 
       
   232 // --------------------------------------------------------------------------
       
   233 // CPbk2ContactFindPolicy::MatchChineseContactNameL
       
   234 // --------------------------------------------------------------------------
       
   235 //
       
   236 TBool CPbk2ContactFindPolicy::MatchChineseContactNameL( 
       
   237     const MDesCArray& aFindWords,
       
   238     const MVPbkBaseContact& aContact )
       
   239     {
       
   240     HBufC* nameFields = HBufC::NewLC( KMaxLengthOfTwoNameFields );
       
   241     TPtr nameFieldsPtr = nameFields->Des();
       
   242     TBool match;
       
   243     
       
   244     // Create iterator
       
   245     MVPbkBaseContactFieldIterator* iterator = iNameFormatter->
       
   246     ActualTitleFieldsLC( *iFieldTypeRefsList, aContact.Fields() );
       
   247     
       
   248     // Loop iterator
       
   249     while ( iterator->HasNext() )
       
   250         {
       
   251         const MVPbkBaseContactField* field = iterator->Next();
       
   252 
       
   253         // Check field's type
       
   254         if ( field->FieldData().DataType() == EVPbkFieldStorageTypeText )
       
   255             {
       
   256             const MVPbkContactFieldTextData& data =
       
   257                 MVPbkContactFieldTextData::Cast( field->FieldData() );
       
   258             // Catenate contact's name fields
       
   259             nameFieldsPtr.Append( data.Text() );
       
   260             }
       
   261         }
       
   262     // Match refine
       
   263     if ( !MatchRefineL( nameFieldsPtr, aFindWords.MdcaPoint( 0 ) ) )
       
   264         {
       
   265         match = EFalse;
       
   266         }
       
   267     else
       
   268         {
       
   269         match = ETrue;
       
   270         }
       
   271     CleanupStack::PopAndDestroy(); // iterator
       
   272     CleanupStack::PopAndDestroy( nameFields );
       
   273     
       
   274     return match;
       
   275     }
       
   276 
       
   277 
       
   278 // --------------------------------------------------------------------------
       
   279 // CPbk2ContactFindPolicy::MatchRefineL
       
   280 // --------------------------------------------------------------------------
       
   281 //
       
   282 TBool CPbk2ContactFindPolicy::MatchRefineL
       
   283         ( const TDesC& aText, const TDesC &aSearchString )
       
   284     {
       
   285     TBool ret = iFindUtil->Interface()->MatchRefineL( aText, aSearchString );
       
   286 
       
   287     return ret;
       
   288     }
       
   289 
       
   290 // --------------------------------------------------------------------------
       
   291 // CPbk2ContactFindPolicy::IsWordValidForMatching
       
   292 // --------------------------------------------------------------------------
       
   293 //
       
   294 TBool CPbk2ContactFindPolicy::IsWordValidForMatching
       
   295         ( const TDesC& aWord )
       
   296     {
       
   297     return iFindUtil->Interface()->IsWordValidForMatching(aWord);
       
   298     }
       
   299 
       
   300 //----------------------------------------------------------------------------
       
   301 // CPbk2ContactFindPolicy::SplitContactFieldTextIntoArrayL
       
   302 //----------------------------------------------------------------------------
       
   303 //
       
   304 void CPbk2ContactFindPolicy::SplitContactFieldTextIntoArrayL(
       
   305 		CDesCArray* aArray,
       
   306         const TDesC& aText )
       
   307     {
       
   308     __ASSERT_DEBUG( aArray, Panic( EPanicNullArray ) );
       
   309 
       
   310     TBool firstWord = ETrue; // To avoid ignoring space from first word in contact field
       
   311     const TInt textLength = aText.Length();
       
   312     for ( TInt beg = 0; beg < textLength; ++beg )
       
   313         {
       
   314         // Skip separators before next word
       
   315         if ( !iNameFormatter->IsFindSeparatorChar( aText[beg] ) )
       
   316             {
       
   317             // Scan the end of the word
       
   318             TInt end = beg;
       
   319             for (; end < textLength &&
       
   320                    !iNameFormatter->IsFindSeparatorChar( aText[end] );
       
   321                 ++end )
       
   322                 {
       
   323                 }
       
   324             const TInt len = end - beg;
       
   325             // Append found word to the array
       
   326             if (firstWord)
       
   327 	            {
       
   328 	            aArray->AppendL( aText.Mid( 0,end ) );
       
   329 	            firstWord = EFalse;
       
   330 	            }
       
   331             else
       
   332             	{
       
   333             	aArray->AppendL( aText.Mid( beg,len ) );
       
   334             	}
       
   335             // Scan for next word
       
   336             beg = end;
       
   337             }
       
   338         }
       
   339 
       
   340     if ( aArray->MdcaCount() == 0 && textLength > 0 )
       
   341         {
       
   342         // aText is all word separator characters
       
   343         // -> make a "word" out of those
       
   344         aArray->AppendL( aText );
       
   345         }
       
   346     }
       
   347 
       
   348 //----------------------------------------------------------------------------
       
   349 // CPbk2ContactFindPolicy::GetTitleFromFDNNumber
       
   350 //----------------------------------------------------------------------------
       
   351 //
       
   352 void CPbk2ContactFindPolicy::GetTitleFromFDNNumberL( const MVPbkBaseContact& aContact, CDesC16Array& aAllNamesArray )
       
   353 	{    
       
   354     //Check if it's a SIM FDN contact
       
   355     if( aContact.MatchContactStore( VPbkContactStoreUris::SimGlobalFdnUri() ) )
       
   356         {
       
   357         const MVPbkBaseContactFieldCollection& fieldCollection = aContact.Fields(); 
       
   358         
       
   359         for(TInt i = 0; i < fieldCollection.FieldCount(); i++ )
       
   360             {
       
   361             const MVPbkBaseContactField& contactField = fieldCollection.FieldAt( i );
       
   362             const MVPbkFieldType* fieldType = contactField.BestMatchingFieldType();
       
   363             
       
   364             //Check if mobile number is used in the view
       
   365             if( fieldType->FieldTypeResId() == R_VPBK_FIELD_TYPE_MOBILEPHONEGEN )
       
   366                 {
       
   367                 const MVPbkContactFieldTextData* textData =
       
   368                                                &MVPbkContactFieldTextData::Cast
       
   369                                                    ( contactField.FieldData() );
       
   370                 aAllNamesArray.AppendL( textData->Text() );
       
   371                 break;
       
   372                 }
       
   373             }
       
   374         }    
       
   375 	}
       
   376     
       
   377 // End of File