diff -r 000000000000 -r 8466d47a6819 ipsservices/ipssosplugin/src/ipsplgsearch.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ipsservices/ipssosplugin/src/ipsplgsearch.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,986 @@ +/* +* 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: This file implements classes TMsgContainer, Search, Search, Search. +* +*/ + + +#include "emailtrace.h" +#include "ipsplgheaders.h" + + +// To skip deleted folder +_LIT( KIpsPlgDeleted, "Deleted" ); + +// ======== CLASS TSEARCHPARAMS ======== + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TSearchParams::operator==() +// --------------------------------------------------------------------------- +// +TBool CIpsPlgSearch::TSearchParams::operator==( + const TSearchParams& aParams ) const + { + FUNC_LOG; + // This variable indicates if the search is same as previous search or + // not. If the search is new, previous data can be reused. + TBool isNew = EFalse; + + // Search strings must have an exact match + TInt newCnt = aParams.iSearchStrings->Count(); + TInt oldCnt = iSearchStrings ? iSearchStrings->Count() : KErrNotFound; + if ( newCnt == oldCnt ) + { + while ( !isNew && --newCnt >= 0 ) + { + while ( !isNew && --oldCnt >= 0 ) + { + // Even if one of the items fails, the search is different. + if ( ( *aParams.iSearchStrings )[newCnt].Compare( + ( *iSearchStrings )[oldCnt] ) ) + { + isNew = ETrue; + } + } + } + } + else + { + // This search has different + isNew = ETrue; + } + + // Search strings are the same than in previous round. If search + // folders are added, but not removed, then search can continue + // from last location. + if ( !isNew ) + { + isNew = EFalse; + newCnt = aParams.iFolderIds.Count(); + oldCnt = iFolderIds.Count(); + + // If folder count has been added, look for added folders. + // If there is folder removed, search has to be started again. + if ( newCnt >= oldCnt ) + { + TInt hits = 0; + TBool found = EFalse; + + // All of the old folders must be found from the new folders. + for ( TInt old = 0; old < oldCnt; old++ ) + { + found = EFalse; + + for ( TInt item = 0; !found && item < newCnt; item++ ) + { + found = iFolderIds[old] == aParams.iFolderIds[item]; + hits += found; + } + } + + isNew = hits != oldCnt; + } + } + // Test is about: "is the new search the same as previous?" + // so if the result of the above analyze is "new search", in that + // case we must return the answer: "no, search is not the same". + // Confusing huh? + return !isNew; + } + +// ======== CLASS TMSGCONTAINER ======== + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::TMsgContainer() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch::TMsgContainer::TMsgContainer( + const TMsvId& aId, + const TFSMailSortCriteria& aCriteria, + CMsvSession& aMsvSession ) + : + iId( aId ), + iCriteria( aCriteria ), + iMsvSession( aMsvSession ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::TMsgContainer() +// --------------------------------------------------------------------------- +// +TBool CIpsPlgSearch::TMsgContainer::operator>( + const TMsgContainer& aMsgContainer ) const + { + FUNC_LOG; + TBool result = EFalse; + + switch ( iCriteria.iField ) + { + default: + case EFSMailDontCare: + break; + + case EFSMailSortByDate: + result = Entry( iId ).iDate > Entry( aMsgContainer.Id() ).iDate; + break; + + case EFSMailSortBySender: + { + HBufC* leftSender = NULL; + HBufC* rightSender = NULL; + + GetSenderStringsCC( + iId, + aMsgContainer.Id(), + leftSender, + rightSender ); + + result = *leftSender > *rightSender; + CleanupStack::PopAndDestroy( 2, leftSender ); + } + break; + + case EFSMailSortBySubject: + { + HBufC* leftSubject = NULL; + HBufC* rightSubject = NULL; + + GetSubjectStringsCC( + iId, + aMsgContainer.Id(), + leftSubject, + rightSubject ); + + result = *leftSubject > *rightSubject; + CleanupStack::PopAndDestroy( 2, leftSubject ); + } + break; + + case EFSMailSortByPriority: + result = Entry( iId ).Priority() > Entry( aMsgContainer.Id() ).Priority(); + break; + + case EFSMailSortByFlagStatus: + result = Entry( iId ).New() > Entry( aMsgContainer.Id() ).New(); + break; + + case EFSMailSortByUnread: + result = Entry( iId ).Unread() > Entry( aMsgContainer.Id() ).Unread(); + break; + + case EFSMailSortBySize: + result = Entry( iId ).iSize > Entry( aMsgContainer.Id() ).iSize; + break; + + case EFSMailSortByAttachment: + result = Entry( iId ).iDate > Entry( aMsgContainer.Id() ).iDate; + break; + } + + return result; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::TMsgContainer() +// --------------------------------------------------------------------------- +// +TBool CIpsPlgSearch::TMsgContainer::operator>=( + const TMsgContainer& aMsgContainer ) const + { + FUNC_LOG; + TBool result = EFalse; + + switch ( iCriteria.iField ) + { + default: + case EFSMailDontCare: + break; + + case EFSMailSortByDate: + result = Entry( iId ).iDate >= Entry( aMsgContainer.Id() ).iDate; + break; + + case EFSMailSortBySender: + { + HBufC* leftSender = NULL; + HBufC* rightSender = NULL; + + GetSenderStringsCC( + iId, + aMsgContainer.Id(), + leftSender, + rightSender ); + + result = *leftSender >= *rightSender; + CleanupStack::PopAndDestroy( 2, leftSender ); + } + break; + + case EFSMailSortBySubject: + { + HBufC* leftSubject = NULL; + HBufC* rightSubject = NULL; + + GetSubjectStringsCC( + iId, + aMsgContainer.Id(), + leftSubject, + rightSubject ); + + result = *leftSubject >= *rightSubject; + CleanupStack::PopAndDestroy( 2, leftSubject ); + } + break; + + case EFSMailSortByPriority: + result = Entry( iId ).Priority() >= Entry( aMsgContainer.Id() ).Priority(); + break; + + case EFSMailSortByFlagStatus: + result = Entry( iId ).New() >= Entry( aMsgContainer.Id() ).New(); + break; + + case EFSMailSortByUnread: + result = Entry( iId ).Unread() >= Entry( aMsgContainer.Id() ).Unread(); + break; + + case EFSMailSortBySize: + result = Entry( iId ).iSize >= Entry( aMsgContainer.Id() ).iSize; + break; + + case EFSMailSortByAttachment: + result = Entry( iId ).iDate >= Entry( aMsgContainer.Id() ).iDate; + break; + } + + return result; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::TMsgContainer() +// --------------------------------------------------------------------------- +// +TBool CIpsPlgSearch::TMsgContainer::operator<=( + const TMsgContainer& aMsgContainer ) const + { + FUNC_LOG; + TBool result = EFalse; + + switch ( iCriteria.iField ) + { + default: + case EFSMailDontCare: + break; + + case EFSMailSortByDate: + result = Entry( iId ).iDate <= Entry( aMsgContainer.Id() ).iDate; + break; + + case EFSMailSortBySender: + { + HBufC* leftSender = NULL; + HBufC* rightSender = NULL; + + GetSenderStringsCC( + iId, + aMsgContainer.Id(), + leftSender, + rightSender ); + + result = *leftSender <= *rightSender; + CleanupStack::PopAndDestroy( 2, leftSender ); + } + break; + + case EFSMailSortBySubject: + { + HBufC* leftSubject = NULL; + HBufC* rightSubject = NULL; + + GetSubjectStringsCC( + iId, + aMsgContainer.Id(), + leftSubject, + rightSubject ); + + result = *leftSubject <= *rightSubject; + CleanupStack::PopAndDestroy( 2, leftSubject ); + } + break; + + case EFSMailSortByPriority: + result = Entry( iId ).Priority() <= Entry( aMsgContainer.Id() ).Priority(); + break; + + case EFSMailSortByFlagStatus: + result = Entry( iId ).New() <= Entry( aMsgContainer.Id() ).New(); + break; + + case EFSMailSortByUnread: + result = Entry( iId ).Unread() <= Entry( aMsgContainer.Id() ).Unread(); + break; + + case EFSMailSortBySize: + result = Entry( iId ).iSize <= Entry( aMsgContainer.Id() ).iSize; + break; + + case EFSMailSortByAttachment: + result = Entry( iId ).iDate <= Entry( aMsgContainer.Id() ).iDate; + break; + } + + return result; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::GetSenderStringsCC() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::TMsgContainer::GetSenderStringsCC( + const TMsvId aLeft, + const TMsvId aRight, + HBufC*& aLeftSender, + HBufC*& aRightSender ) const + { + FUNC_LOG; + TMsvEntry entry = Entry( aLeft ); + aLeftSender = entry.iDetails.Alloc(); + TRAP_IGNORE( CleanupStack::PushL( aLeftSender ) ); + + entry = Entry( aRight ); + aRightSender = entry.iDetails.Alloc(); + TRAP_IGNORE( CleanupStack::PushL( aRightSender ) ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::GetSubjectStringsCC() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::TMsgContainer::GetSubjectStringsCC( + const TMsvId aLeft, + const TMsvId aRight, + HBufC*& aLeftSubject, + HBufC*& aRightSubject ) const + { + FUNC_LOG; + TMsvEntry entry = Entry( aLeft ); + aLeftSubject = entry.iDescription.Alloc(); + TRAP_IGNORE( CleanupStack::PushL( aLeftSubject ) ); + + entry = Entry( aRight ); + aRightSubject = entry.iDescription.Alloc(); + TRAP_IGNORE( CleanupStack::PushL( aRightSubject ) ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::TMsgContainer() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch::TMsgContainer& CIpsPlgSearch::TMsgContainer::operator=( + const TMsgContainer& aMsgContainer ) + { + FUNC_LOG; + iId = aMsgContainer.Id(); + return *this; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::Entry() +// --------------------------------------------------------------------------- +// +TMsvEntry CIpsPlgSearch::TMsgContainer::Entry( const TMsvId aId ) const + { + FUNC_LOG; + return CIpsPlgSearch::TMsgContainer::Entry( iMsvSession, aId ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::TMsgContainer::Entry() +// --------------------------------------------------------------------------- +// +TMsvEntry CIpsPlgSearch::TMsgContainer::Entry( + CMsvSession& aMsvSession, + const TMsvId aId ) + { + FUNC_LOG; + TMsvId service; + TMsvEntry entry; + aMsvSession.GetEntry( aId, service, entry ); + return entry; + } + +// ======== CLASS CIPSPLGSEARCH ======== + +// ======== CONSTRUCTORS & DESTRUCTOR ======== + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::NewL() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch* CIpsPlgSearch::NewL( + CMsvSession& aMsvSession, + CIpsPlgSosBasePlugin& aPlugin ) + { + FUNC_LOG; + CIpsPlgSearch* self = CIpsPlgSearch::NewLC( aMsvSession, aPlugin ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::NewLC() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch* CIpsPlgSearch::NewLC( + CMsvSession& aMsvSession, + CIpsPlgSosBasePlugin& aPlugin ) + { + FUNC_LOG; + CIpsPlgSearch* self = new( ELeave ) CIpsPlgSearch( aMsvSession, aPlugin ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::~CIpsPlgSearch() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch::~CIpsPlgSearch() + { + FUNC_LOG; + // Any running search operations must be cancelled before deletion. + if ( iOperation ) + { + iOperation->Cancel(); + } + + delete iOperation; + iOperation = NULL; + + iObserver = NULL; + + delete iActiveEntry; + iActiveEntry = NULL; + + delete iMapper; + iMapper = NULL; + + iCache.Reset(); + iEmailMessages.Reset(); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::CIpsPlgSearch() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch::CIpsPlgSearch( + CMsvSession& aMsvSession, + CIpsPlgSosBasePlugin& aPlugin ) + : + iMsvSession( aMsvSession ), + iActiveEntry( NULL ), + iOperation( NULL ), + iObserver( NULL ), + iPlugin( aPlugin ), + iMapper( NULL ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::ConstructL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::ConstructL() + { + FUNC_LOG; + iMapper = CIpsPlgMsgMapper::NewL( iMsvSession, iPlugin ); + iActiveEntry = iMsvSession.GetEntryL( KMsvLocalServiceIndexEntryId ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::Cancel() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::Cancel() + { + FUNC_LOG; + // Cancel the operation before deleting. + if ( iOperation ) + { + iOperation->Cancel(); + } + + // All checks are based on pointer value, so make it NULL + delete iOperation; + iOperation = NULL; + + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::ClearCache() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::ClearCache() + { + FUNC_LOG; + iCache.Reset(); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::GetFoldersL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::GetFoldersL( TSearchParams& aParams ) + { + FUNC_LOG; + iActiveEntry->SetEntryL( aParams.iMailbox.Id() ); + + if ( iActiveEntry->Entry().iMtm == KSenduiMtmPop3Uid ) + { + aParams.iFolderIds.AppendL( + TFSMailMsgId( iPlugin.PluginId(), aParams.iMailbox.Id() ) ); + return; + } + const TInt folders = iActiveEntry->Count(); + for ( TInt folder = 0; folder < folders; folder++ ) + { + const TMsvEntry& entry = ( *iActiveEntry )[folder]; + if ( entry.iType == KUidMsvFolderEntry && + entry.iDescription.Compare( KIpsPlgDeleted ) ) + { + GetFoldersL( entry.Id(), aParams.iFolderIds ); + } + } + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::GetFoldersL() +// --------------------------------------------------------------------------- +void CIpsPlgSearch::GetFoldersL( + const TMsvId aFolderId, + RArray& aFolders ) + { + FUNC_LOG; + // Add this folder to array. + aFolders.AppendL( TFSMailMsgId( iPlugin.PluginId(), aFolderId ) ); + + CMsvEntry* entry = iMsvSession.GetEntryL( aFolderId ); + CleanupStack::PushL( entry ); + + const TInt count = entry->Count(); + for ( TInt loop = 0; loop < count; loop++ ) + { + const TMsvEntry& tEntry = (*entry)[loop]; + if ( tEntry.iType == KUidMsvFolderEntry ) + { + GetFoldersL( tEntry.Id(), aFolders ); + } + } + + CleanupStack::PopAndDestroy( entry ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::SearchL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::SearchL( + const TFSMailMsgId& aMailBoxId, + const RArray& aFolderIds, + const RPointerArray& aSearchStrings, + const TFSMailSortCriteria& aSortCriteria, + MFSMailBoxSearchObserver& aSearchObserver ) + { + FUNC_LOG; + if ( iOperation ) + { + // if there is ongoing search, it must be canceled + // according to UI specs + Cancel(); + } + + // Create search parameters group for init. + TSearchParams newSearch( + aSearchStrings, + aMailBoxId, + aFolderIds, + aSortCriteria ); + + // If folder list is empty, whole mailbox needs to be searched. + if ( !newSearch.iFolderIds.Count() ) + { + GetFoldersL( newSearch ); + } + + // If search strings are same than last time, then sorting is same. + // Clear previous cache and continue. + if ( iPreviousSearch == newSearch ) + { + // At this point, append new folders to list. + iCurrentSearch += newSearch; + iPreviousSearch += newSearch; + } + else + { + ClearCache(); + iCurrentSearch = newSearch; + iPreviousSearch = newSearch; + } + + iCurrentMessage.SetPluginId( aMailBoxId.PluginId() ); + iObserver = &aSearchObserver; + + iOperation = CIpsPlgSearchOp::NewL( *this ); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::Session() +// --------------------------------------------------------------------------- +// +CMsvSession& CIpsPlgSearch::Session() + { + FUNC_LOG; + return iMsvSession; + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::MailboxId() +// --------------------------------------------------------------------------- +// +TMsvId CIpsPlgSearch::MailboxId() + { + FUNC_LOG; + return iCurrentSearch.iMailbox.Id(); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::FolderId() +// --------------------------------------------------------------------------- +// +TMsvId CIpsPlgSearch::FolderId() + { + FUNC_LOG; + return iActiveEntry->EntryId(); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::CurrentMessage() +// --------------------------------------------------------------------------- +// +const TFSMailMsgId& CIpsPlgSearch::CurrentMessage() const + { + FUNC_LOG; + return iCurrentMessage; + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::SearchStringsL() +// --------------------------------------------------------------------------- +// +const CDesC16Array& CIpsPlgSearch::SearchStringsL() + { + FUNC_LOG; + return *iCurrentSearch.iSearchStrings; + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::MatchFound() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::MatchFoundL() + { + FUNC_LOG; + // Set current email as an entry and create messages for both cache and + // observer, for now like this. + iActiveEntry->SetEntryL( iCurrentMessage.Id() ); + iCache.AppendL( SendToObserverL() ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::SendToObserverL() +// --------------------------------------------------------------------------- +// +TFSMailMsgId CIpsPlgSearch::SendToObserverL() + { + FUNC_LOG; + CFSMailMessage* obsMail = iMapper->GetMailMessageL( *iActiveEntry ); + CleanupStack::PushL( obsMail ); + + iObserver->MatchFoundL( obsMail ); + + CleanupStack::Pop( obsMail ); + return obsMail->GetMessageId(); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::SearchFinished() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::SearchFinishedL() + { + FUNC_LOG; + iObserver->SearchCompletedL(); + + delete iOperation; + iOperation = NULL; + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::NextItem() +// --------------------------------------------------------------------------- +// +CIpsPlgSearch::TMsgContainer& CIpsPlgSearch::NextItem() + { + FUNC_LOG; + if ( iCurrentSearch.iSortCriteria.iOrder == EFSMailAscending ) + { + return iEmailMessages[0]; + } + else + { + return iEmailMessages[iEmailMessages.Count() - 1]; + } + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::NextMessageL() +// --------------------------------------------------------------------------- +// +CImEmailMessage* CIpsPlgSearch::NextMessageL() + { + FUNC_LOG; + // Items, that are already in cache, are not needed to be searched. + while ( iEmailMessages.Count() ) + { + TFSMailMsgId id( + iCurrentSearch.iMailbox.PluginId().iUid, NextItem().Id() ); + + TInt index=KErrNotFound; + TInt count = iCache.Count(); + + for( TInt i=0; i KErrNotFound ) + { + iActiveEntry->SetEntryL( id.Id() ); + + if( iCurrentSearch.iSortCriteria.iOrder == EFSMailAscending ) + { + iEmailMessages.Remove( 0 ); + } + else + { + iEmailMessages.Remove( iEmailMessages.Count()-1 ); + } + SendToObserverL(); + } + else + { + break; + } + } + + // Return next available message. + if ( iEmailMessages.Count() ) + { + iCurrentMessage.SetId( NextItem().Id() ); + + if( iCurrentSearch.iSortCriteria.iOrder == EFSMailAscending ) + { + iEmailMessages.Remove( 0 ); + } + else + { + iEmailMessages.Remove( iEmailMessages.Count()-1 ); + } + iActiveEntry->SetEntryL( iCurrentMessage.Id() ); + return CImEmailMessage::NewL( *iActiveEntry ); + } + else + { + // Empty, return Null index, so the search can be finished. + return NULL; + } + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::MessageHeaderL() +// --------------------------------------------------------------------------- +// +CImHeader* CIpsPlgSearch::MessageHeaderL() + { + FUNC_LOG; + CImHeader* header = NULL; + CMsvStore* store = iActiveEntry->EditStoreL(); + CleanupStack::PushL( store ); + + if ( store->IsPresentL( KUidMsgFileIMailHeader ) ) + { + header = CImHeader::NewLC(); + header->RestoreL( *store ); + CleanupStack::Pop( header ); + } + + CleanupStack::PopAndDestroy( store ); + return header; + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::GetSubjectL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::GetSubjectL( RBuf& aSubject ) + { + FUNC_LOG; + TMsvEntry email = iActiveEntry->Entry(); + aSubject.CreateL( email.iDescription ); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::GetSenderL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::GetSenderL( RBuf& aSubject ) + { + FUNC_LOG; + TMsvEntry email = iActiveEntry->Entry(); + aSubject.CreateL( email.iDetails ); + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::Sort() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::Sort() + { + FUNC_LOG; + // Here we use quick sort algorithm + QuickSort( iEmailMessages, 0, iEmailMessages.Count() - 1 ); + } + +// --------------------------------------------------------------------------- +// CIpsPlgSearch::QuickSort() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::QuickSort( + RArray& aMessages, + TInt aLeft, + TInt aRight ) + { + FUNC_LOG; + if( aMessages.Count() <= 1 ) + { + return; + } + TInt leftHold = aLeft; + TInt rightHold = aRight; + TMsgContainer pivot = aMessages[aLeft]; + + while ( aLeft < aRight ) + { + while ( ( aMessages[aRight] >= pivot ) && ( aLeft < aRight ) ) + { + aRight--; + } + + if (aLeft != aRight) + { + aMessages[aLeft] = aMessages[aRight]; + aLeft++; + } + + while ( ( aMessages[aLeft] <= pivot ) && ( aLeft < aRight ) ) + { + aLeft++; + } + + if ( aLeft != aRight ) + { + aMessages[aRight] = aMessages[aLeft]; + aRight--; + } + } + + aMessages[aLeft] = pivot; + + TInt pivotIndex = aLeft; + aLeft = leftHold; + aRight = rightHold; + if ( aLeft < pivotIndex ) + { + QuickSort( aMessages, aLeft, pivotIndex-1); + } + + if ( aRight > pivotIndex ) + { + QuickSort( aMessages, pivotIndex+1, aRight); + } + } + +// --------------------------------------------------------------------------- +// From class MIpsPlgSearch. +// CIpsPlgSearch::CollectMessagesL() +// --------------------------------------------------------------------------- +// +void CIpsPlgSearch::CollectMessagesL() + { + FUNC_LOG; + // Lets make a huge list of message id's. + iEmailMessages.Reset(); + + const TInt folders = iCurrentSearch.iFolderIds.Count(); + for ( TInt folder = 0; folder < folders; folder++ ) + { + iActiveEntry->SetEntryL( iCurrentSearch.iFolderIds[folder].Id() ); + const TInt msgs = iActiveEntry->Count(); + for ( TInt msg = 0; msg < msgs; msg++ ) + { + const TMsvEntry& entry = ( *iActiveEntry )[msg]; + if ( entry.iType == KUidMsvMessageEntry && + ( entry.iMtm.iUid == KSenduiMtmSmtpUidValue || + entry.iMtm.iUid == iPlugin.MtmId().iUid ) ) + { + iEmailMessages.AppendL( TMsgContainer( + entry.Id(), iCurrentSearch.iSortCriteria, iMsvSession ) ); + } + } + } + } + +// End of File +