--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosplugin/src/ipsplgmsgkey.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Key class for message sorting
+*
+*/
+
+// <cmail>
+#include <AknUtils.h>
+// </cmail>
+
+#include "emailtrace.h"
+#include "ipsplgheaders.h"
+
+const TInt KLessThan = -1;
+const TInt KMoreThan = 1;
+const TInt KEqual = 0;
+
+_LIT(KDefaultSubjectPrefixSeparator,": ");
+// <cmail>
+_LIT( KCharsToReplace, "\r\n\t\x2028\x2029" );
+// </cmail>
+
+// ---------------------------------------------------------------------------
+// Basic sonstructor
+// ---------------------------------------------------------------------------
+
+TIpsPlgMsgKey::TIpsPlgMsgKey(
+ CMsvEntry& aFolderEntry,
+ const RArray<TFSMailSortCriteria>& aSortCriteria )
+ : iFolderEntry( aFolderEntry ),
+ iSortingCriteria( aSortCriteria ),
+ iSubjectPrefixSeparator( KDefaultSubjectPrefixSeparator )
+ {
+ FUNC_LOG;
+ // none
+ }
+
+// ---------------------------------------------------------------------------
+// Compares the messages under the folder entry according to the sorting
+// criteria.
+// ---------------------------------------------------------------------------
+
+TInt TIpsPlgMsgKey::Compare( TInt aLeft, TInt aRight ) const
+ {
+ FUNC_LOG;
+ TInt result( KEqual );
+ TInt childCount( iFolderEntry.Count() );
+ if ( aLeft >= childCount || aRight >= childCount )
+ {
+ return result;
+ }
+ const TMsvEmailEntry leftEntry( iFolderEntry[aLeft] );
+ const TMsvEmailEntry rightEntry( iFolderEntry[aRight] );
+
+ // Loop over the sorting criteria until the comparison result is known
+ TInt i(0);
+ while ( ( result == KEqual ) && ( i < iSortingCriteria.Count() ) )
+ {
+ switch ( iSortingCriteria[i].iField )
+ {
+ case EFSMailDontCare:
+ {
+ // If the client does not care, we can return immediately
+ return result;
+ }
+ case EFSMailSortByDate:
+ {
+ if ( leftEntry.iDate < rightEntry.iDate )
+ {
+ result = KLessThan;
+ }
+ else if ( leftEntry.iDate > rightEntry.iDate )
+ {
+ result = KMoreThan;
+ }
+ break;
+ }
+ case EFSMailSortBySender:
+ {
+ result =
+ leftEntry.iDetails.CompareC( rightEntry.iDetails );
+ break;
+ }
+ case EFSMailSortByRecipient:
+ {
+ result =
+ leftEntry.iDetails.CompareC( rightEntry.iDetails );
+ break;
+ }
+ case EFSMailSortBySubject:
+ {
+ // <cmail> due to changes in CompareSubject method
+ TRAP_IGNORE( result = CompareSubjectsL(
+ leftEntry.iDescription, rightEntry.iDescription ) );
+ // </cmail>
+ break;
+ }
+ case EFSMailSortByPriority:
+ // The values of TMsvPriority are defined so that the highest
+ // priority has the smallest value
+ if ( leftEntry.Priority() > rightEntry.Priority() )
+ {
+ result = KLessThan;
+ }
+ else if ( leftEntry.Priority() < rightEntry.Priority() )
+ {
+ result = KMoreThan;
+ }
+ break;
+ case EFSMailSortByFlagStatus:
+ {
+ // The 'flagged' state is supported only in IMAP4
+ if ( leftEntry.iMtm == KUidMsgTypeIMAP4 )
+ {
+ if ( !leftEntry.FlaggedIMAP4Flag() &&
+ rightEntry.FlaggedIMAP4Flag() )
+ {
+ result = KLessThan;
+ }
+ else if ( leftEntry.FlaggedIMAP4Flag() &&
+ !rightEntry.FlaggedIMAP4Flag() )
+ {
+ result = KMoreThan;
+ }
+ }
+ break;
+ }
+ case EFSMailSortByUnread:
+ {
+ // In this context, an read message is 'greater' than
+ // a read one
+ if ( !leftEntry.Unread() && rightEntry.Unread() )
+ {
+ result = KMoreThan; // <cmail> changed from KLessThan
+ }
+ else if ( leftEntry.Unread() && !rightEntry.Unread() )
+ {
+ result = KLessThan; // <cmail> changed from KMoreThan
+ }
+ break;
+ }
+ case EFSMailSortBySize:
+ {
+ if ( leftEntry.iSize < rightEntry.iSize )
+ {
+ result = KLessThan;
+ }
+ else if ( leftEntry.iSize > rightEntry.iSize )
+ {
+ result = KMoreThan;
+ }
+ break;
+ }
+ case EFSMailSortByAttachment:
+ {
+ // In this context, a message with an attachment is 'greater'
+ // than one without an attachment
+ if ( !leftEntry.Attachment() && rightEntry.Attachment() )
+ {
+ result = KLessThan;
+ }
+ else if ( leftEntry.Attachment() && !rightEntry.Attachment() )
+ {
+ result = KMoreThan;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Switch the order if the messages are sorted in the descending order
+ if ( iSortingCriteria[i].iOrder == EFSMailDescending )
+ {
+ result = -result;
+ }
+
+ i++;
+ }
+
+ return result;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns a message based on the index.
+// Note, that KIndexPtr index value is not supported as the class is not
+// intended to be used with User::BinarySearch().
+// ---------------------------------------------------------------------------
+
+TAny* TIpsPlgMsgKey::At( TInt anIndex ) const
+ {
+ FUNC_LOG;
+ return (TAny*) &iFolderEntry[ anIndex ];
+ }
+
+// ---------------------------------------------------------------------------
+// Strips the subject prefixes before comparing the strings
+// ---------------------------------------------------------------------------
+
+TInt TIpsPlgMsgKey::CompareSubjectsL(
+ const TDesC& aLeft,
+ const TDesC& aRight ) const
+ {
+ FUNC_LOG;
+ TInt result( KEqual );
+ TPtrC leftPtr( aLeft );
+ TPtrC rightPtr( aRight );
+ TInt leftOffset( FindSubjectStart( aLeft ) );
+ TInt rightOffset( FindSubjectStart( aRight ) );
+
+ leftPtr.Set(
+ leftPtr.Ptr() + leftOffset, leftPtr.Length() - leftOffset );
+ rightPtr.Set(
+ rightPtr.Ptr() + rightOffset, rightPtr.Length() - rightOffset );
+
+ // <cmail> for unifying with UI - remove all white spaces
+ HBufC* croppedLeft = leftPtr.AllocLC();
+ TPtr croppedLeftPtr = croppedLeft->Des();
+ HBufC* croppedRight = rightPtr.AllocLC();
+ TPtr croppedRightPtr = croppedRight->Des();
+
+ AknTextUtils::ReplaceCharacters( croppedLeftPtr, KCharsToReplace, ' ' );
+ croppedLeftPtr.TrimAll();
+ AknTextUtils::ReplaceCharacters( croppedRightPtr, KCharsToReplace, ' ' );
+ croppedRightPtr.TrimAll();
+
+ result = croppedLeftPtr.CompareC( croppedRightPtr );
+
+ CleanupStack::PopAndDestroy( croppedRight );
+ CleanupStack::PopAndDestroy( croppedLeft );
+ // </cmail>
+
+ return result;
+ }
+
+// ---------------------------------------------------------------------------
+// Finds the starting point of the actual subject text after the subject
+// prefixes (Re:, Fwd: etc).
+// The algorithm search the last separator string (': ') in most western
+// languages and returns the offset from the beginnig of the string to
+// the first character following the last separator.
+// ---------------------------------------------------------------------------
+
+TInt TIpsPlgMsgKey::FindSubjectStart( const TDesC& aSubject ) const
+ {
+ FUNC_LOG;
+ TInt offset(0);
+ // <cmail> removed and replaced with the code from UI
+ // TFsEmailUiUtility::CreateSubjectWithoutLocalisedPrefixLC
+ // to have the same subject here and there
+ // there was sorting problem when subjects where handled
+ // different here and in UI while creating mails' list.
+
+ /*TPtrC ptr(aSubject);
+ TInt current(0);
+ TInt skipLength = iSubjectPrefixSeparator.Length();
+
+ // Loop while separators are found
+ do
+ {
+ current = ptr.FindF( iSubjectPrefixSeparator );
+
+ if ( current != KErrNotFound )
+ {
+ offset += current + skipLength;
+ ptr.Set( aSubject.Ptr() + offset, aSubject.Length() - offset );
+ }
+ } while ( current != KErrNotFound );*/
+
+ TBool prefixFound = EFalse;
+ TPtrC croppedSubject;
+ croppedSubject.Set( aSubject );
+
+ do
+ {
+ prefixFound = EFalse;
+
+ // Remove leading white space before trying to find the prefix
+ while( croppedSubject.Length() &&
+ TChar( croppedSubject[0] ).IsSpace() )
+ {
+ croppedSubject.Set( croppedSubject.Mid(1) );
+ offset++;
+ }
+
+ // try to find ":" at the beginning
+ // Locate : character on location 1,2 and 3
+ static const TInt KPrefixMinLength = 1;
+ static const TInt KPrefixMaxLength = 3;
+ static const TText KPrefixSeparator = ':';
+ TInt separatorPosition = croppedSubject.Locate( KPrefixSeparator );
+ if ( separatorPosition >= KPrefixMinLength &&
+ separatorPosition <= KPrefixMaxLength )
+ {
+ TPtrC prefixCandidate = croppedSubject.Left( separatorPosition );
+ // Only fully alphabetic prefixes are cropped
+ TBool isAlpha = ETrue;
+ for ( TInt i = 0 ; i < prefixCandidate.Length() ; ++i )
+ {
+ if ( !TChar( prefixCandidate[i] ).IsAlpha() )
+ {
+ isAlpha = EFalse;
+ }
+ }
+ if ( isAlpha )
+ {
+ croppedSubject.Set( croppedSubject.Mid(
+ separatorPosition + 1 ) );
+ offset += separatorPosition + 1;
+ prefixFound = ETrue;
+ }
+ }
+ }
+ while ( prefixFound );
+ // </cmail>
+
+ return offset;
+ }