--- /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<TFSMailMsgId>& 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<TFSMailMsgId>& aFolderIds,
+ const RPointerArray<TDesC>& 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<count; i++ )
+ {
+ if ( iCache[i].Id() == id.Id() )
+ {
+ index = i;
+ }
+ }
+
+ if ( index > 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<TMsgContainer>& 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
+