predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Utils.cpp
branchRCL_3
changeset 20 f4a778e096c2
child 21 9da50d567e3c
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Supports initial search feature. 
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDES
       
    19 #include "CPcsAlgorithm2Utils.h"
       
    20 #include "CPsData.h"
       
    21 #include "CPsQuery.h"
       
    22 #include "CPcsDefs.h"
       
    23 #include "CPcsCache.h"
       
    24 #include <collate.h>
       
    25 // CONSTANTS
       
    26 _LIT(KSpace, ' ');
       
    27 // Search contacts in a group URI template
       
    28 _LIT(KGroupIdUri, "cntdb://c:contacts.gdb?id=");
       
    29 
       
    30 // ============================== MEMBER FUNCTIONS ============================
       
    31 
       
    32 // ----------------------------------------------------------------------------
       
    33 // CPcsAlgorithm2Utils::FormCompleteSearchResultsL()
       
    34 // Merges all the respective data store result sets to single set in sorted order.
       
    35 // ----------------------------------------------------------------------------
       
    36 void CPcsAlgorithm2Utils::FormCompleteSearchResultsL(RPointerArray<CPSDATA_R_PTR_ARRAY>& aSearchResultsArr,
       
    37                                                      RPointerArray<CPsData>& aSearchResults)
       
    38     {
       
    39     TInt maxIndex = 0;
       
    40     TInt maxValue = aSearchResultsArr[maxIndex]->Count();
       
    41     TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder);
       
    42 
       
    43     // Find the largest array in aSearchResultsArr
       
    44     const TInt searchResultsArrCount = aSearchResultsArr.Count(); 
       
    45     for (TInt i = 1; i < searchResultsArrCount; i++)
       
    46         {
       
    47         if (aSearchResultsArr[i]->Count() > maxValue)
       
    48             {
       
    49             maxIndex = i;
       
    50             maxValue = aSearchResultsArr[i]->Count();
       
    51             }
       
    52         }
       
    53 
       
    54     // Assign the largets array to searchresults 
       
    55     const TInt cnt = aSearchResultsArr[maxIndex]->Count();
       
    56     for (TInt i = 0; i < cnt; i++)
       
    57         {
       
    58         aSearchResults.Append((*(aSearchResultsArr[maxIndex]))[i]);
       
    59         }
       
    60 
       
    61     // Merge the remaining result arrays to the largest array in sequential order
       
    62 
       
    63     for (TInt i = 0; i < searchResultsArrCount; i++)
       
    64         {
       
    65         // Check if we are not copying again the largest array
       
    66         if ((i != maxIndex) && ((aSearchResultsArr[i])->Count() != 0))
       
    67             {
       
    68             TInt numElements = (aSearchResultsArr[i])->Count();
       
    69             for (TInt j = 0; j < numElements; j++)
       
    70                 {
       
    71                 aSearchResults.InsertInOrderAllowRepeatsL((*(aSearchResultsArr[i]))[j], rule);
       
    72                 }
       
    73             }
       
    74         }
       
    75     }
       
    76 
       
    77 // ----------------------------------------------------------------------------
       
    78 // CPcsAlgorithm2Utils::MyCompareC()
       
    79 // Lang specific MyCompareC
       
    80 // ----------------------------------------------------------------------------
       
    81 TInt CPcsAlgorithm2Utils::MyCompareC(const TDesC& aLeft, const TDesC& aRight)
       
    82     {
       
    83     // Get the current language
       
    84     TLanguage lang = User::Language();
       
    85 
       
    86     // Get the standard method
       
    87     TCollationMethod meth = *Mem::CollationMethodByIndex(0);
       
    88     meth.iFlags |= TCollationMethod::EIgnoreNone;
       
    89     meth.iFlags |= TCollationMethod::EFoldCase;
       
    90 
       
    91     if (lang == ELangHindi || lang == ELangMarathi)
       
    92         {
       
    93         meth.iFlags |= TCollationMethod::EIgnoreCombining;
       
    94         }
       
    95 
       
    96     // Collation level 3 is used
       
    97     TInt comparison(aLeft.CompareC(aRight, 3, &meth));
       
    98     return comparison;
       
    99     }
       
   100 
       
   101 // ----------------------------------------------------------------------------
       
   102 // CPcsAlgorithm2Utils::CompareDataBySortOrder()
       
   103 // TLinearOrder rule for comparison of data objects
       
   104 // ----------------------------------------------------------------------------
       
   105 TInt CPcsAlgorithm2Utils::CompareDataBySortOrder(const CPsData& aObject1,
       
   106                                                  const CPsData& aObject2)
       
   107     {
       
   108     _LIT(KSpace, " ");
       
   109 
       
   110     // Fetch the cache list stored in TLS to recover the sort order
       
   111     typedef RPointerArray<CPcsCache> PTR;
       
   112     PTR* pcsCache = static_cast<PTR*> (Dll::Tls());
       
   113 
       
   114     // Data1
       
   115     TBuf<255> data1(KNullDesC);
       
   116     TInt uriId1 = aObject1.UriId();
       
   117     CPcsCache* cache = (*pcsCache)[uriId1];
       
   118 
       
   119     RArray<TInt> indexOrder;
       
   120 
       
   121     // Get the index order based on sort order from the cache
       
   122     cache->GetIndexOrder(indexOrder);
       
   123 
       
   124     // Append sort order elements first
       
   125     const TInt indexOrderCount1 = indexOrder.Count();
       
   126     for (int i = 0; i < indexOrderCount1; i++)
       
   127         {
       
   128         TInt index = indexOrder[i];
       
   129         if (index < aObject1.DataElementCount() && aObject1.Data(index))
       
   130             {
       
   131             // Trim the unnecessary white spaces/special chars before we compare
       
   132             TBuf<255> str(KNullDesC);
       
   133 
       
   134             str = aObject1.Data(index)->Des();
       
   135             CPcsAlgorithm2Utils::MyTrim(str);
       
   136 
       
   137             data1 += str;
       
   138             data1 += KSpace;
       
   139             }
       
   140         }
       
   141 
       
   142     /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED ---
       
   143      // Append remaining elements in order
       
   144      for ( int i = 0; i < aObject1.DataElementCount(); i++ )
       
   145      {
       
   146      if ( indexOrder.Find(i) == KErrNone && aObject1.Data(i) )
       
   147      {
       
   148      data1 += aObject1.Data(i)->Des();
       
   149      data1 += KSpace;
       
   150      }	     
       
   151      }
       
   152      */
       
   153 
       
   154     // Data2
       
   155     TBuf<255> data2(KNullDesC);
       
   156     TInt uriId2 = aObject2.UriId();
       
   157     cache = (*pcsCache)[uriId2];
       
   158 
       
   159     indexOrder.Reset();
       
   160 
       
   161     // Get the index order based on sort order from the cache
       
   162     cache->GetIndexOrder(indexOrder);
       
   163     const TInt indexOrderCount2 = indexOrder.Count();
       
   164 
       
   165     // Append sort order elements first
       
   166     for (int i = 0; i < indexOrderCount2; i++)
       
   167         {
       
   168         TInt index = indexOrder[i];
       
   169         if (index < aObject2.DataElementCount() && aObject2.Data(index))
       
   170             {
       
   171             // Trim the unnecessary white spaces/special chars before we compare
       
   172             TBuf<255> str(KNullDesC);
       
   173 
       
   174             str = aObject2.Data(index)->Des();
       
   175             CPcsAlgorithm2Utils::MyTrim(str);
       
   176 
       
   177             data2 += str;
       
   178             data2 += KSpace;
       
   179             }
       
   180         }
       
   181 
       
   182     /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED ---
       
   183      // Append remaining elements in order
       
   184      for ( int i = 0; i < aObject2.DataElementCount(); i++ )
       
   185      {
       
   186      if ( indexOrder.Find(i) == KErrNone && aObject2.Data(i) )
       
   187      {
       
   188      data2 += aObject2.Data(i)->Des();
       
   189      data2 += KSpace;
       
   190      }	     
       
   191      }
       
   192      */
       
   193 
       
   194     indexOrder.Reset();
       
   195     data1.TrimAll();
       
   196     data2.TrimAll();
       
   197     return (CPcsAlgorithm2Utils::MyCompareC(data1, data2));
       
   198     }
       
   199 
       
   200 // ----------------------------------------------------------------------------
       
   201 // CPcsAlgorithm2Utils::CompareExact()
       
   202 // 
       
   203 // ----------------------------------------------------------------------------
       
   204 TBool CPcsAlgorithm2Utils::CompareExact(const TDesC& aFirst, const TDesC& aSecond)
       
   205     {
       
   206     return aFirst == aSecond;
       
   207     }
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // CPcsAlgorithm2Utils::CompareLength()
       
   211 // 
       
   212 // ----------------------------------------------------------------------------
       
   213 TInt CPcsAlgorithm2Utils::CompareLength(const CPsQuery& aFirst, const CPsQuery& aSecond)
       
   214     {
       
   215     CPsQuery& first = const_cast<CPsQuery&> (aFirst);
       
   216     CPsQuery& second = const_cast<CPsQuery&> (aSecond);
       
   217     
       
   218     return (first.Count() - second.Count());
       
   219     }
       
   220 
       
   221 // ----------------------------------------------------------------------------
       
   222 // CPcsAlgorithm2Utils::MyTrim()
       
   223 // Trim off all white spaces and special characters
       
   224 // This behavior is required to mimic the current phonebook sort sequence
       
   225 // ----------------------------------------------------------------------------
       
   226 void CPcsAlgorithm2Utils::MyTrim(TDes& aString)
       
   227     {
       
   228     for (TInt i = aString.Length(); --i >= 0;)
       
   229         {
       
   230         TChar c = (TChar) aString[i];
       
   231 
       
   232         if (!c.IsAlphaDigit())
       
   233             {
       
   234             aString.Replace(i, 1, KSpace);
       
   235             }
       
   236         }
       
   237 
       
   238     aString.TrimAll();
       
   239     }
       
   240 
       
   241 // ----------------------------------------------------------------------------
       
   242 // CPcsAlgorithm2Utils::IsGroupUri()
       
   243 // Check if the input URI is of contact search in a group template form
       
   244 // ----------------------------------------------------------------------------                         
       
   245 TBool CPcsAlgorithm2Utils::IsGroupUri(TDesC& aURI)
       
   246     {
       
   247     TBuf<255> uri(aURI);
       
   248     uri.LowerCase();
       
   249 
       
   250     TInt index = uri.FindF(KGroupIdUri);
       
   251 
       
   252     if (index == KErrNotFound)
       
   253         {
       
   254         return EFalse;
       
   255         }
       
   256 
       
   257     return ETrue;
       
   258     }
       
   259 
       
   260 // ----------------------------------------------------------------------------
       
   261 // CPcsAlgorithm1Helper::FilterDataFieldsL()
       
   262 // Constructs a bit pattern using the required/supported data fields
       
   263 // For example, 6, 4 and 27 are supported fields <-- 00000111
       
   264 //              6 and 4 are required fields      <-- 00000011
       
   265 // Bit pattern returned is 00000011.
       
   266 // ----------------------------------------------------------------------------
       
   267 TUint8 CPcsAlgorithm2Utils::FilterDataFieldsL(const RArray<TInt>& aRequiredDataFields,
       
   268                                               const RArray<TInt>& aSupportedDataFields)
       
   269 {
       
   270     TUint8 filteredMatch = 0x0;
       
   271    const TInt supportedDataFieldsCount = aSupportedDataFields.Count();
       
   272    const TInt requiredDataFieldsCount = aRequiredDataFields.Count(); 
       
   273     for ( TInt i = 0; i < supportedDataFieldsCount; i++ )
       
   274     {
       
   275         for ( TInt j = 0; j < requiredDataFieldsCount; j++ )
       
   276         {
       
   277             if ( aSupportedDataFields[i] == aRequiredDataFields[j] )
       
   278             {
       
   279                 TUint8 val = 1 << i;
       
   280                 filteredMatch |= val;
       
   281             }
       
   282         }
       
   283     }
       
   284 
       
   285     return filteredMatch;
       
   286 }
       
   287 
       
   288 // ----------------------------------------------------------------------------
       
   289 // CPcsAlgorithm2Utils::AppendMatchToSeqL
       
   290 // ----------------------------------------------------------------------------
       
   291 void CPcsAlgorithm2Utils::AppendMatchToSeqL( 
       
   292         RPointerArray<TDesC>& aMatchSeq, const TDesC& aMatch )
       
   293     {
       
   294     HBufC* seq = aMatch.AllocLC();
       
   295     seq->Des().UpperCase();
       
   296     TIdentityRelation<TDesC> rule(CompareExact);
       
   297     if ( aMatchSeq.Find(seq, rule) == KErrNotFound )
       
   298         {
       
   299         aMatchSeq.AppendL(seq);
       
   300         CleanupStack::Pop( seq );
       
   301         }
       
   302     else 
       
   303         {
       
   304         CleanupStack::PopAndDestroy( seq );
       
   305         }
       
   306     }
       
   307 
       
   308 // ----------------------------------------------------------------------------
       
   309 // CPcsAlgorithm2Utils::MatchesOverlap
       
   310 // Check if two match location items have overlapping indices.
       
   311 // ----------------------------------------------------------------------------
       
   312 TBool CPcsAlgorithm2Utils::MatchesOverlap( const TPsMatchLocation& aFirst, 
       
   313                                            const TPsMatchLocation& aSecond )
       
   314     {
       
   315     TBool overlap = EFalse;
       
   316     
       
   317     if ( aFirst.index == aSecond.index )
       
   318         {
       
   319         overlap = ETrue;
       
   320         }
       
   321     else
       
   322         {
       
   323         // give arguments alias names where first begins before the second
       
   324         TInt firstPos( aFirst.index );
       
   325         TInt firstLen( aFirst.length );
       
   326         TInt secondPos( aSecond.index );
       
   327         if ( firstPos > secondPos )
       
   328             {
       
   329             firstPos = aSecond.index;
       
   330             firstLen = aSecond.length;
       
   331             secondPos = aFirst.index;
       
   332             }
       
   333         
       
   334         // there is an overlap if the end of the first comes after
       
   335         // beginning of the second
       
   336         if ( firstPos + firstLen > secondPos )
       
   337             {
       
   338             overlap = ETrue;
       
   339             }
       
   340         }
       
   341     
       
   342     return overlap;
       
   343     }
       
   344 
       
   345 // End of File
       
   346