📄 imap4mail.cpp
字号:
/*
* ============================================================================
* Name : CImap4Mail from Imap4Mail.cpp
* Part of : EmailExample
* Created : 09/11/2003 by Forum Nokia
* Implementation notes:
* basic statemachine
* Version : 1.0
* Copyright: Nokia Corporation
* ============================================================================
*/
#include "Imap4Mail.h"
#include "MsvEmailUtils.h"
// constant strings for info print messages used when fetching mail.
_LIT(KIMConnect, "Connecting to mailserver");
_LIT(KIMSync, "Synchronising against mailserver");
_LIT(KIMWaitSync, "Waiting background synchronize to finish");
_LIT(KIMDisconnect, "Disconnecting");
_LIT(KIMComplete, "Operation complete");
_LIT(KFetchTitle, "Imap4 operation in progress");
_LIT(KFetchMessage, "Synchronising folders and message headers \n against remote mailbox");
// static creation. Doesn't leave a copy on the clean up stack
CImap4Mail* CImap4Mail::NewL(TRequestStatus& aStatus,CMsvSession& aMsvSession)
{
CImap4Mail* self = new (ELeave) CImap4Mail(aStatus,aMsvSession);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CImap4Mail::CImap4Mail(TRequestStatus& aStatus,CMsvSession& aMsvSession)
: CActive(CActive::EPriorityStandard), iObserverStatus(aStatus), iMsvSession(aMsvSession)
{
CActiveScheduler::Add(this);
}
void CImap4Mail::ConstructL()
{
iState=EInitialising;
// create an empty selection to used later.
iMsvSelection = new(ELeave) CMsvEntrySelection();
iState = EReady;
Queue();
}
CImap4Mail::~CImap4Mail()
{
if(iOperation)
{
iOperation->Cancel();
}
Cancel();
delete iOperation;
delete iDialog;
delete iMsvSelection;
delete iImap4Mtm;
delete iImap4Utils;
}
// active objects RunL functions acts as main state handling routine
void CImap4Mail::RunL()
{
// get a pointer to our observers status
TRequestStatus* st = &iObserverStatus;
switch(iState)
{
case EReady:
// tell the observer that the object os ready for use
User::RequestComplete(st,KErrNone);
break;
case EConnecting:
{
// display connecting message and initiate connection
User::InfoPrint(KIMConnect);
ExecuteConnectL();
}
break;
case ESync:
{
// display sync message and syncronize with remote server
User::InfoPrint(KIMSync);
ExecuteSyncL();
}
break;
case EWaitSync:
{
// display message and wait for background sync operation to finish
User::InfoPrint(KIMWaitSync);
ExecuteWaitSyncL();
}
break;
case EDisconnectRemote:
// display disconnect message and initiate disconnect
User::InfoPrint(KIMDisconnect);
ExecuteDisconnectL();
break;
case EDisconnecting:
// display disconnecting message, reset object and complete observers request
User::InfoPrint(KIMComplete);
delete iDialog;
iDialog=NULL;
iState = EReady;
delete iOperation;
iOperation=NULL;
User::RequestComplete(st,KErrNone);
break;
case ECanceling:
// cancel the any outstanding operations and reset object.
iStatus = KRequestPending;
iState= EReady;
delete iOperation;
iOperation=NULL;
User::RequestComplete(st,KErrCancel);
default:
break;
}
}
// Connect to remote mail box
void CImap4Mail::ExecuteConnectL()
{
// reset our status
iStatus = KRequestPending;
TBuf8<1> null;
// execute the Imap4 connect command
MailCommandL(KIMAP4MTMConnect,null);
//Note: KIMAP4MTMConnectAndSynchronise would be more elegant for some applications
iState=ESync;
SetActive();
}
// full background syncronization with remote server
void CImap4Mail::ExecuteSyncL()
{
// reset our status
iStatus = KRequestPending;
TBuf8<1> null;
// Synchronises the service whose TMsvId is given by aSelection[0].
// If the service is already synchronising, then complete with KErrServerBusy.
MailCommandL(KIMAP4MTMFullSync, null );
iState=EWaitSync;
//iState=EDisconnectRemote;
SetActive();
}
// waits for synchronization to end
void CImap4Mail::ExecuteWaitSyncL()
{
// reset our status
iStatus = KRequestPending;
TBuf8<1> null;
//Completes (with KErrNone) only when the background synchronisation has finished.
//It is used to ensure that no UI-initiated folder syncing is performed during the background synchronisation.
MailCommandL(KIMAP4MTMWaitForBackground,null);
iState=EDisconnectRemote;
SetActive();
}
// disconnect from service
void CImap4Mail::ExecuteDisconnectL()
{
// reset our status
iStatus = KRequestPending;
TBuf8<1> null;
//Cancels any operations in progress and sends logout messages to server.
//As long as the background synchronisation, this will also run any pending delete operations queued while offline.
MailCommandL(KIMAP4MTMDisconnect,null);
iState=EDisconnecting;
SetActive();
}
// interface to engine for sync
void CImap4Mail::SyncWithRemoteServerL(TMsvId aMailId)
{
// panic client is object is not in EReady state.
__ASSERT_DEBUG(iState==EReady,User::Invariant());
iMailId=aMailId;
// reset our status
iObserverStatus = KRequestPending;
// create cancel dialog
CCknCancelDialog* dialog=CCknCancelDialog::NewL(&iDialog,this,KFetchTitle,KFetchMessage);
// activate cancel dialog
dialog->RunDlgLD();
LoadMtmL();
iState=EConnecting;
// set active and complete our own request.
Queue();
}
// executes Imap4 mail commands
void CImap4Mail::MailCommandL(TInt aCommand,TDes8& aParams)
{
// get the imap4 service id
if(!iImap4Utils)
{
iImap4Utils = CMsvEmailUtils::NewL(iMsvSession);
}
TMsvId id = iImap4Utils->GetServiceIdL(KUidMsgTypeIMAP4);
// make sure iServiceId is a remote type service
if(iServiceId != KMsvLocalServiceIndexEntryId)
{
iMsvSelection->Reset();
// append imap4 service entry id
iMsvSelection->AppendL(id);
// get the msventry for the service id
CMsvEntry* service = iMsvSession.GetEntryL(iServiceId);
CleanupStack::PushL(service);
// make sure the mtm for the service is a Imap4 type
if(service->Entry().iMtm == KUidMsgTypeIMAP4)
{
// delete and reset any outstanding operation
if(iOperation)
{
iOperation->Cancel();
}
delete iOperation;
iOperation=NULL;
iOperation = iImap4Mtm->InvokeAsyncFunctionL(aCommand,*iMsvSelection,aParams/*ptr*/,iStatus);
}
CleanupStack::PopAndDestroy(service);
}
else
{
// there is no Imap4 mail service defined on the device.
User::Leave(KErrNotFound);
}
}
void CImap4Mail::LoadMtmL()
{
// get the id for the Imap4 mtm
if(!iImap4Utils)
{
iImap4Utils = CMsvEmailUtils::NewL(iMsvSession);
}
TMsvId id = iImap4Utils->GetServiceIdL(KUidMsgTypeIMAP4);
// make sure that there is a Imap4 mtm defined in the system
if(id == KMsvRootIndexEntryId)
{
User::Leave(KErrNotFound);
}
TMsvEntry tmp;
// get the entry
User::LeaveIfError(iMsvSession.GetEntry(id,iServiceId,tmp));
// create a Imap4 mtm from the service id
iImap4Mtm = iImap4Utils->InstantiateImapClientMtmL(iServiceId);
}
// called by the user pressing the cancel button
void CImap4Mail::CancelOperation()
{
// the dialog has destroyed itself so set the pointer to null
iDialog=NULL;
// cancel the operation if one exists
if(iOperation)
{
iOperation->Cancel();
}
iState=ECanceling;
if(!IsActive())
{
SetActive();
}
}
// msvsession callback handling funtion
void CImap4Mail::HandleSessionEventL(TMsvSessionEvent aEvent,TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/)
{
switch(aEvent)
{
case MMsvSessionObserver::EMsvServerReady:
if(iState==EInitialising)
{
// the message server is now ready for use.
// set our state to ready and queue the next state.
iState = EReady;
Queue();
}
break;
case EMsvServerTerminated:
iState=EInitialising;
break;
case MMsvSessionObserver::EMsvEntriesCreated:
case MMsvSessionObserver::EMsvEntriesChanged:
case MMsvSessionObserver::EMsvEntriesDeleted:
case MMsvSessionObserver::EMsvEntriesMoved:
case MMsvSessionObserver::EMsvMtmGroupInstalled:
case MMsvSessionObserver::EMsvMtmGroupDeInstalled:
case MMsvSessionObserver::EMsvGeneralError:
case MMsvSessionObserver::EMsvCloseSession:
case MMsvSessionObserver::EMsvServerFailedToStart:
case MMsvSessionObserver::EMsvCorruptedIndexRebuilt:
case MMsvSessionObserver::EMsvMediaChanged:
case MMsvSessionObserver::EMsvMediaUnavailable:
case MMsvSessionObserver::EMsvMediaAvailable:
case MMsvSessionObserver::EMsvMediaIncorrect:
case MMsvSessionObserver::EMsvCorruptedIndexRebuilding:
break;
}
}
void CImap4Mail::DoCancel()
{}
// don't handle errors at the moment
TInt CImap4Mail::RunError(TInt aError)
{
return aError;
}
// complete our own status.
// this allows the active scheduler chance to service other active objects before
// return back to our RunL
void CImap4Mail::Queue()
{
if(!IsActive())
{
SetActive();
}
TRequestStatus* st= &iStatus;
User::RequestComplete(st,KErrNone);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -