ipsservices/ipssosplugin/src/ipsplgmsgkey.cpp
changeset 0 8466d47a6819
child 20 efd4f1afd43e
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     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:  Key class for message sorting
       
    15 *
       
    16 */
       
    17 
       
    18 // <cmail>
       
    19 #include <AknUtils.h>
       
    20 // </cmail>
       
    21 
       
    22 #include "emailtrace.h"
       
    23 #include "ipsplgheaders.h"
       
    24 
       
    25 const TInt KLessThan = -1;
       
    26 const TInt KMoreThan = 1;
       
    27 const TInt KEqual = 0;
       
    28 
       
    29 _LIT(KDefaultSubjectPrefixSeparator,": ");
       
    30 // <cmail>
       
    31 _LIT( KCharsToReplace, "\r\n\t\x2028\x2029" );
       
    32 // </cmail>
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // Basic sonstructor
       
    36 // ---------------------------------------------------------------------------
       
    37 
       
    38 TIpsPlgMsgKey::TIpsPlgMsgKey( 
       
    39     CMsvEntry& aFolderEntry,
       
    40     const RArray<TFSMailSortCriteria>& aSortCriteria )
       
    41     : iFolderEntry( aFolderEntry ), 
       
    42       iSortingCriteria( aSortCriteria ),
       
    43       iSubjectPrefixSeparator( KDefaultSubjectPrefixSeparator )
       
    44     {
       
    45     FUNC_LOG;
       
    46     // none
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // Compares the messages under the folder entry according to the sorting
       
    51 // criteria.
       
    52 // ---------------------------------------------------------------------------
       
    53 
       
    54 TInt TIpsPlgMsgKey::Compare( TInt aLeft, TInt aRight ) const
       
    55     {
       
    56     FUNC_LOG;
       
    57     TInt result( KEqual );
       
    58     TInt childCount( iFolderEntry.Count() );
       
    59     if ( aLeft >= childCount || aRight >= childCount  )
       
    60         {
       
    61         return result;
       
    62         }
       
    63     const TMsvEmailEntry leftEntry( iFolderEntry[aLeft] );
       
    64     const TMsvEmailEntry rightEntry( iFolderEntry[aRight] );
       
    65     
       
    66     // Loop over the sorting criteria until the comparison result is known
       
    67     TInt i(0);
       
    68     while ( ( result == KEqual ) && ( i < iSortingCriteria.Count() ) )
       
    69         {
       
    70         switch ( iSortingCriteria[i].iField )
       
    71             {
       
    72             case EFSMailDontCare:
       
    73                 {
       
    74                 // If the client does not care, we can return immediately
       
    75                 return result;
       
    76                 }
       
    77             case EFSMailSortByDate:
       
    78                 {
       
    79                 if ( leftEntry.iDate < rightEntry.iDate ) 
       
    80                     {
       
    81                     result = KLessThan;
       
    82                     }
       
    83                 else if ( leftEntry.iDate > rightEntry.iDate ) 
       
    84                     {
       
    85                     result = KMoreThan;
       
    86                     }
       
    87                 break;
       
    88                 }
       
    89             case EFSMailSortBySender:
       
    90                 {
       
    91                 result = 
       
    92                     leftEntry.iDetails.CompareC( rightEntry.iDetails );
       
    93                 break;
       
    94                 }
       
    95             case EFSMailSortByRecipient:
       
    96                 {                
       
    97                 result = 
       
    98                     leftEntry.iDetails.CompareC( rightEntry.iDetails );
       
    99                 break;
       
   100                 }
       
   101             case EFSMailSortBySubject:
       
   102                 {
       
   103                 // <cmail> due to changes in CompareSubject method
       
   104                 TRAP_IGNORE( result = CompareSubjectsL( 
       
   105                     leftEntry.iDescription, rightEntry.iDescription ) );
       
   106                 // </cmail>
       
   107                 break;
       
   108                 }
       
   109             case EFSMailSortByPriority:
       
   110                 // The values of TMsvPriority are defined so that the highest
       
   111                 // priority has the smallest value
       
   112                 if ( leftEntry.Priority() > rightEntry.Priority() ) 
       
   113                     {
       
   114                     result = KLessThan;
       
   115                     }
       
   116                 else if ( leftEntry.Priority() < rightEntry.Priority() ) 
       
   117                     {
       
   118                     result = KMoreThan;
       
   119                     }
       
   120                 break;
       
   121             case EFSMailSortByFlagStatus:
       
   122                 {
       
   123                 // The 'flagged' state is supported only in IMAP4
       
   124                 if ( leftEntry.iMtm == KUidMsgTypeIMAP4 )
       
   125                     {
       
   126                     if ( !leftEntry.FlaggedIMAP4Flag() && 
       
   127                          rightEntry.FlaggedIMAP4Flag() ) 
       
   128                         {
       
   129                         result = KLessThan;
       
   130                         }
       
   131                     else if ( leftEntry.FlaggedIMAP4Flag() && 
       
   132                               !rightEntry.FlaggedIMAP4Flag() ) 
       
   133                         {
       
   134                         result = KMoreThan;
       
   135                         }
       
   136                     }
       
   137                 break;
       
   138                 }
       
   139             case EFSMailSortByUnread:
       
   140                 {
       
   141                 // In this context, an read message is 'greater' than
       
   142                 // a read one
       
   143                 if ( !leftEntry.Unread() && rightEntry.Unread() ) 
       
   144                     {
       
   145                     result = KMoreThan; // <cmail> changed from KLessThan 
       
   146                     }
       
   147                 else if ( leftEntry.Unread() && !rightEntry.Unread() ) 
       
   148                     {
       
   149                     result = KLessThan; // <cmail> changed from KMoreThan
       
   150                     }
       
   151                 break;
       
   152                 }
       
   153             case EFSMailSortBySize:
       
   154                 {
       
   155                 if ( leftEntry.iSize < rightEntry.iSize ) 
       
   156                     {
       
   157                     result = KLessThan;
       
   158                     }
       
   159                 else if ( leftEntry.iSize > rightEntry.iSize ) 
       
   160                     {
       
   161                     result = KMoreThan;
       
   162                     }
       
   163                 break;
       
   164                 }
       
   165             case EFSMailSortByAttachment:
       
   166                 {
       
   167                 // In this context, a message with an attachment is 'greater'
       
   168                 // than one without an attachment
       
   169                 if ( !leftEntry.Attachment() && rightEntry.Attachment() ) 
       
   170                     {
       
   171                     result = KLessThan;
       
   172                     }
       
   173                 else if ( leftEntry.Attachment() && !rightEntry.Attachment() ) 
       
   174                     {
       
   175                     result = KMoreThan;
       
   176                     }
       
   177                 break;
       
   178                 }
       
   179             default:
       
   180                 break;
       
   181             }
       
   182             
       
   183         // Switch the order if the messages are sorted in the descending order
       
   184         if ( iSortingCriteria[i].iOrder == EFSMailDescending ) 
       
   185             {
       
   186             result = -result;
       
   187             }
       
   188         
       
   189         i++;
       
   190         }
       
   191     
       
   192     return result;
       
   193     }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // Returns a message based on the index.
       
   197 // Note, that KIndexPtr index value is not supported as the class is not 
       
   198 // intended to be used with User::BinarySearch().
       
   199 // ---------------------------------------------------------------------------
       
   200 
       
   201 TAny* TIpsPlgMsgKey::At( TInt anIndex ) const
       
   202     {
       
   203     FUNC_LOG;
       
   204     return (TAny*) &iFolderEntry[ anIndex ];
       
   205     }
       
   206 
       
   207 // ---------------------------------------------------------------------------
       
   208 // Strips the subject prefixes before comparing the strings
       
   209 // ---------------------------------------------------------------------------
       
   210 
       
   211 TInt TIpsPlgMsgKey::CompareSubjectsL( 
       
   212     const TDesC& aLeft, 
       
   213     const TDesC& aRight ) const
       
   214     {
       
   215     FUNC_LOG;
       
   216     TInt  result( KEqual );
       
   217     TPtrC leftPtr( aLeft );
       
   218     TPtrC rightPtr( aRight );
       
   219     TInt  leftOffset( FindSubjectStart( aLeft ) );
       
   220     TInt  rightOffset( FindSubjectStart( aRight ) );
       
   221     
       
   222     leftPtr.Set( 
       
   223         leftPtr.Ptr() + leftOffset, leftPtr.Length() - leftOffset );
       
   224     rightPtr.Set( 
       
   225         rightPtr.Ptr() + rightOffset, rightPtr.Length() - rightOffset );
       
   226     
       
   227     // <cmail> for unifying with UI - remove all white spaces
       
   228     HBufC* croppedLeft = leftPtr.AllocLC();
       
   229     TPtr croppedLeftPtr = croppedLeft->Des();
       
   230     HBufC* croppedRight = rightPtr.AllocLC();
       
   231     TPtr croppedRightPtr = croppedRight->Des();
       
   232         
       
   233     AknTextUtils::ReplaceCharacters( croppedLeftPtr, KCharsToReplace, ' ' );
       
   234     croppedLeftPtr.TrimAll();
       
   235     AknTextUtils::ReplaceCharacters( croppedRightPtr, KCharsToReplace, ' ' );
       
   236     croppedRightPtr.TrimAll();
       
   237     
       
   238     result = croppedLeftPtr.CompareC( croppedRightPtr );
       
   239     
       
   240     CleanupStack::PopAndDestroy( croppedRight );
       
   241     CleanupStack::PopAndDestroy( croppedLeft );
       
   242     // </cmail>
       
   243         
       
   244     return result;
       
   245     }
       
   246     
       
   247 // ---------------------------------------------------------------------------
       
   248 // Finds the starting point of the actual subject text after the subject
       
   249 // prefixes (Re:, Fwd: etc).
       
   250 // The algorithm search the last separator string (': ') in most western
       
   251 // languages and returns the offset from the beginnig of the string to
       
   252 // the first character following the last separator.
       
   253 // ---------------------------------------------------------------------------
       
   254 
       
   255 TInt TIpsPlgMsgKey::FindSubjectStart( const TDesC& aSubject ) const
       
   256     {
       
   257     FUNC_LOG;
       
   258     TInt offset(0);
       
   259     // <cmail> removed and replaced with the code from UI
       
   260     // TFsEmailUiUtility::CreateSubjectWithoutLocalisedPrefixLC
       
   261     // to have the same subject here and there
       
   262     // there was sorting problem when subjects where handled
       
   263     // different here and in UI while creating mails' list.  
       
   264     
       
   265     /*TPtrC ptr(aSubject);
       
   266     TInt current(0);
       
   267     TInt skipLength = iSubjectPrefixSeparator.Length();
       
   268     
       
   269     // Loop while separators are found
       
   270     do
       
   271         {
       
   272         current = ptr.FindF( iSubjectPrefixSeparator );
       
   273 
       
   274         if ( current != KErrNotFound )
       
   275             {
       
   276             offset += current + skipLength;
       
   277             ptr.Set( aSubject.Ptr() + offset, aSubject.Length() - offset );
       
   278             }
       
   279         } while ( current != KErrNotFound );*/
       
   280     
       
   281     TBool prefixFound = EFalse;
       
   282     TPtrC croppedSubject;
       
   283     croppedSubject.Set( aSubject );
       
   284     
       
   285     do
       
   286         {
       
   287         prefixFound = EFalse;
       
   288     
       
   289         // Remove leading white space before trying to find the prefix
       
   290         while( croppedSubject.Length() && 
       
   291                TChar( croppedSubject[0] ).IsSpace() )
       
   292             {
       
   293             croppedSubject.Set( croppedSubject.Mid(1) );
       
   294             offset++;
       
   295             }
       
   296     
       
   297         // try to find ":" at the beginning
       
   298         // Locate : character on location 1,2 and 3
       
   299         static const TInt KPrefixMinLength = 1;
       
   300         static const TInt KPrefixMaxLength = 3;
       
   301         static const TText KPrefixSeparator = ':';
       
   302         TInt separatorPosition = croppedSubject.Locate( KPrefixSeparator );
       
   303         if ( separatorPosition >= KPrefixMinLength &&
       
   304              separatorPosition <= KPrefixMaxLength )
       
   305             {
       
   306             TPtrC prefixCandidate = croppedSubject.Left( separatorPosition );
       
   307             // Only fully alphabetic prefixes are cropped
       
   308             TBool isAlpha = ETrue;
       
   309             for ( TInt i = 0 ; i < prefixCandidate.Length() ; ++i )
       
   310                 {
       
   311                 if ( !TChar( prefixCandidate[i] ).IsAlpha() )
       
   312                     {
       
   313                     isAlpha = EFalse;
       
   314                     }
       
   315                 }
       
   316             if ( isAlpha )
       
   317                 {
       
   318                 croppedSubject.Set( croppedSubject.Mid( 
       
   319                         separatorPosition + 1 ) );
       
   320                 offset += separatorPosition + 1;
       
   321                 prefixFound = ETrue;
       
   322                 }
       
   323             }
       
   324         }
       
   325     while ( prefixFound );
       
   326     // </cmail>
       
   327 
       
   328     return offset;
       
   329     }