/*
* Copyright (c) 2009 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 class CEmailMessageSearchAsync
*
*/
#include <emailclientapi.hrh>
#include "emailmessagesearch.h"
#include "emailmessage.h"
/**
* Global semaphore name. Semaphore blocks parallel service access.
*/
_LIT( KGlobalSemaphoreToPreventParallelCall, "12mymessaging.nokia.com34" );
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CEmailMessageSearchAsync::NewL
// ---------------------------------------------------------------------------
//
CEmailMessageSearchAsync* CEmailMessageSearchAsync::NewL(
CPluginData& aPluginData,
const TMailboxId& aMailboxId )
{
CEmailMessageSearchAsync* self = new (ELeave) CEmailMessageSearchAsync(aPluginData, aMailboxId);
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CEmailMessageSearchAsync::ConstructL()
{
iPlugin = iPluginData.ClaimInstanceL();
// Open existing semaphore, or create a new one
if (KErrNone != iGate.OpenGlobal(KGlobalSemaphoreToPreventParallelCall, EOwnerProcess))
{
User::LeaveIfError(iGate.CreateGlobal(KGlobalSemaphoreToPreventParallelCall, 1, EOwnerProcess));
}
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
CEmailMessageSearchAsync::CEmailMessageSearchAsync(
CPluginData& aPluginData,
const TMailboxId& aMailboxId )
: iPluginData( aPluginData ), iMailboxId( aMailboxId.iId ),
iCriteria(), iObserver(NULL), iRemote(EFalse)
{
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
CEmailMessageSearchAsync::~CEmailMessageSearchAsync()
{
iSearchStrings.Close();
iPluginData.ReleaseInstance();
iGate.Close();
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
TEmailTypeId CEmailMessageSearchAsync::InterfaceId() const
{
return KEmailIFUidSearch;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void CEmailMessageSearchAsync::Release()
{
if (KErrNone != iGate.Wait(1))
{
this->Cancel();
}
delete this;
}
/**
* Sets sort order for search results.
* Leaves KErrNotReady if search is ongoing.
*/
void CEmailMessageSearchAsync::SetSortCriteriaL( const TEmailSortCriteria& aCriteria )
{
if (KErrNone != iGate.Wait(1))
{
// Leave now, search is going on
User::Leave( KErrNotReady );
}
switch (aCriteria.iField)
{
case TEmailSortCriteria::EDontCare:
iCriteria.iField = EFSMailDontCare;
break;
case TEmailSortCriteria::EByDate:
iCriteria.iField = EFSMailSortByDate;
break;
case TEmailSortCriteria::EBySender:
iCriteria.iField = EFSMailSortBySender;
break;
case TEmailSortCriteria::EByRecipient:
iCriteria.iField = EFSMailSortByRecipient;
break;
case TEmailSortCriteria::EBySubject:
iCriteria.iField = EFSMailSortBySubject;
break;
case TEmailSortCriteria::EByPriority:
iCriteria.iField = EFSMailSortByPriority;
break;
case TEmailSortCriteria::EByFlagStatus:
iCriteria.iField = EFSMailSortByFlagStatus;
break;
case TEmailSortCriteria::EByUnread:
iCriteria.iField = EFSMailSortByUnread;
break;
case TEmailSortCriteria::EBySize:
iCriteria.iField = EFSMailSortBySize;
break;
case TEmailSortCriteria::EByAttachment:
iCriteria.iField = EFSMailSortByAttachment;
break;
default:
User::Leave( KErrNotSupported );
break;
}
if (aCriteria.iAscending)
{
iCriteria.iOrder = EFSMailAscending;
}
else
{
iCriteria.iOrder = EFSMailDescending;
}
// Release gate
iGate.Signal();
}
/**
* Adds a search key. Leaves KErrNotReady if search is ongoing.
*/
void CEmailMessageSearchAsync::AddSearchKeyL( const TDesC& aSearchKey )
{
if (KErrNone != iGate.Wait(1))
{
// Leave now, search is going on
User::Leave( KErrNotReady );
}
iSearchStrings.AppendL(&aSearchKey);
// Release gate
iGate.Signal();
}
/**
* Enables/disables search from remote email server.
* Leaves KErrNotReady if search is ongoing.
*/
void CEmailMessageSearchAsync::SetRemoteSearchL( TBool aRemote )
{
if (KErrNone != iGate.Wait(1))
{
// Leave now, search is going on
User::Leave( KErrNotReady );
}
iRemote = aRemote;
// Release gate
iGate.Signal();
// Currently plugins do not support this function
User::Leave( KErrNotSupported );
}
/**
* Indicates whether remote search is enabled.
*/
TBool CEmailMessageSearchAsync::IsRemoteSearch() const
{
// Currently plugins do not support this function
return EFalse;
}
/**
* Starts search, all methods affecting search attribures leave
* KErrNotReady while search is ongoing.
* @param aObserver called when results are available.
*/
void CEmailMessageSearchAsync::StartSearchL( MEmailSearchObserver& aObserver )
{
if (KErrNone != iGate.Wait(1))
{
// Leave now, search is going on
User::Leave( KErrNotReady );
}
iObserver = &aObserver;
const TFSMailMsgId fsMailboxId( iPluginData.Uid(), iMailboxId.iId );
RArray <TFSMailMsgId> folderIds;
CleanupClosePushL( folderIds );
/** Search API */
/**
* Asyncronous call for starting search for given string. Only one search can be
* performed at a time.
*
*
* This function will search for message's containing the given search string.
* The search will be performed on the all message fields: To, Cc, Bcc, subject, body.
* The search client will be notified of each found message,
* and upon completion of the search. Only one search can be performed at a time.
*
* To change the sort order in the search result, use the same search string in the
* but change the aSortCriteria parameter. The store "caches" the search
* results generated by the same search string.
*
* The function will leave with KErrInUse if a search is already in progress.
*
* /note Only works if the store is in an authenticated state,
* otherwise this function leaves with KErrNotReady
*
* @paran aMailBoxId id of the mailbox where messages are to be searched
* @param aFolderIds list of folders where messages are to be searched
* global or folder specific search depends on the size of array is 0 or not.
* @param aSearchStrings text strings that will be searched from different message fields.
* @param aSortCriteria sort criteria for the results
* @param aSearchObserver client observer that will be notified about search status.
*
*/
iPlugin->SearchL( fsMailboxId,
folderIds,
iSearchStrings,
iCriteria,
*this );
// Gate is kept closed as search is asynchronous. Gate will be reopen after search is completed, i.e.
// CEmailMessageSearchAsync::SearchCompleted.
CleanupStack::PopAndDestroy( &folderIds );
}
/**
* Cancels search.
*/
void CEmailMessageSearchAsync::Cancel()
{
if (KErrNone != iGate.Wait(1))
{
/**
* Cancels current search. Does nothing if there is not any search.
* The search client will not be called back after this function is called.
*
*/
const TFSMailMsgId fsMailboxId( iPluginData.Uid(), iMailboxId.iId );
iPlugin->CancelSearch( fsMailboxId );
}
else
{
// Release gate
iGate.Signal();
}
}
/** returns search status
* @return search status:
* < 0 : Search has failed
* KRequestPending : search is ongoing. note that status may be
* KRequestPending after HandleResultL callback because results
* may be given in chunks of results. Size of chunk depends on
* implementation and may vary.
* KErrNone : initial state, or search has finished
*/
TInt CEmailMessageSearchAsync::Status() const
{
if (KErrNone != iGate.Wait(1))
{
// Search is going on
return KRequestPending;
}
else
{
// Release gate
iGate.Signal();
}
return KErrNone;
}
/**
* Resets all search attribures. Cancels search if ongoing.
*/
void CEmailMessageSearchAsync::Reset()
{
if (KErrNone != iGate.Wait(1))
{
this->Cancel();
}
iCriteria = TFSMailSortCriteria();
iSearchStrings.Reset();
// Release gate
iGate.Signal();
};
/**
* Notifies the email search API client that a match has been found
*
* @param aMatchMessage contains a pointer to the matched message.
* Ownership is transfered to the observer.
*
*/
void CEmailMessageSearchAsync::MatchFoundL( CFSMailMessage* aMatchMessage )
{
CEmailMessage *result = CEmailMessage::NewL(iPluginData, aMatchMessage, EClientOwns );
iObserver->HandleResultL(result);
}
/**
* Notifies the email search API client that the search has completed
*
*/
void CEmailMessageSearchAsync::SearchCompletedL()
{
iObserver->SearchCompletedL();
// Search is now complete, release gate.
iGate.Signal();
}
//
/**
* Asks client if search engine should change search priority
*/
void CEmailMessageSearchAsync::ClientRequiredSearchPriority(TInt * /* apRequiredSearchPriority */ )
{
return;
}
//