📄 emailexampleengine.cpp
字号:
/*
* ============================================================================
* Name : CEmailExampleEngine from EmailExampleEngine.cpp
* Part of : EmailExample
* Created : 09/11/2003 by Forum Nokia
* Implementation notes:
* basic statemachine with 2 internal state machines one
* for pop one for imap.
* Version : 1.0
* Copyright: Nokia Corporation
* ============================================================================
*/
#include "EmailExampleEngine.h"
#include <EmailExample.rsg>
#include <mtclreg.h> // for CClientMtmRegistry
#include <mtmstore.h> // for CMtmStore
#include <mtmuibas.h> // for CBaseMtmUi
#include <comabs.h> // for CCommandAbsorbingControl
#include <eikenv.h> // for CEikonEnv
#include "Imap4Mail.h"
#include "Pop3Mail.h"
#include "msvEmailUtils.h"
#include "settingsdialog.h"
//static creation
CEmailExampleEngine* CEmailExampleEngine::NewL(MEmailExampleEngineObserver& aObserver)
{
CEmailExampleEngine* engine=new(ELeave) CEmailExampleEngine(aObserver);
CleanupStack::PushL(engine);
engine->ConstructL();
CleanupStack::Pop(engine);
return engine;
}
// actual constructor. Create with standard prioritory
CEmailExampleEngine::CEmailExampleEngine(MEmailExampleEngineObserver& aObserver)
: CActive(CActive::EPriorityStandard), iObserver(aObserver)
{
// add this object to the active scheduler
CActiveScheduler::Add(this);
}
// destructor
CEmailExampleEngine::~CEmailExampleEngine()
{
Cancel();
delete iEntry;
delete iImapMail;
delete iMtmReg;
delete iMtmStore;
delete iRemoteEntries;
delete iMsvSession; //Session must be deleted last
}
// sencond phase of construction
void CEmailExampleEngine::ConstructL()
{
// set initial object state
iState=EInitialising;
// create and open a session towards messaging
// the open operation is asynchronous and HandleSessionEventL will be called when the open is complete
iMsvSession=CMsvSession::OpenAsyncL(*this);
// Default protocol values
iProtocolType=EProtocolImap4;
iSettingProtocolType=EProtocolImap4;
}
// Handles async completions
void CEmailExampleEngine::RunL()
{
switch(iState)
{
// waiting for a imap4 operation to complete
case EWaitingForImap4:
{
iStatus = KRequestPending;
iState = ESyncImap4;
SetActive();
// initiate remote mail sync
TRAPD(ret,iImapMail->SyncWithRemoteServerL());
if(ret != KErrNone)
{
// if there was an error delete imap mail and reset object
delete iImapMail;
iImapMail=NULL;
iState=EReady;
TRequestStatus* st= &iStatus;
// signal own status to reset object to start state
User::RequestComplete(st,KErrNone);
}
}
break;
case ESyncImap4:
{
if(iStatus == KErrCancel)
{
CEikonEnv::Static()->InfoMsg(R_EMAILEXAMPLEAPP_REMOTE_CANCELED);
}
delete iImapMail;
iImapMail=NULL;
UpdateRemoteCountImap4L();
iState=EReady;
}
break;
// waiting for a pop3 operation to complete
case EWaitingForPop3:
{
iStatus = KRequestPending;
iState = EFetchingPop3;
SetActive();
// initiate remote mail fetch
TRAPD(ret,iPopMail->FetchRemoteMailL());
if(ret != KErrNone)
{
// if there was an error delete pop mail and reset object
delete iPopMail;
iPopMail=NULL;
// reset state
iState=EReady;
TRequestStatus* st= &iStatus;
// signal own status to reset object to start state
User::RequestComplete(st,KErrNone);
}
}
break;
case EFetchingPop3:
{
// check current status and display cancel message if neccessary
if(iStatus == KErrCancel)
{
CEikonEnv::Static()->InfoMsg(R_EMAILEXAMPLEAPP_REMOTE_CANCELED);
}
delete iPopMail;
iPopMail=NULL;
UpdateRemoteCountPop3L();
iState=EReady;
}
break;
default:
break;
}
}
// nothing to cancel
void CEmailExampleEngine::DoCancel()
{}
// simply return error value
TInt CEmailExampleEngine::RunError(TInt aError)
{
return aError;
}
// Get the subject of the email
TPtrC CEmailExampleEngine::RemoteEmailTextL(TInt aIndex)
{
TMsvId entryId=(*iRemoteEntries)[aIndex];
if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
{
delete iEntry;
iEntry=NULL;
iEntry=iMsvSession->GetEntryL(entryId);
}
return iEntry->Entry().iDescription;
}
TPtrC CEmailExampleEngine::RemoteEmailSenderL(TInt aIndex)
{
TMsvId entryId=(*iRemoteEntries)[aIndex];
if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
{
delete iEntry;
iEntry=NULL;
iEntry=iMsvSession->GetEntryL(entryId);
}
return iEntry->Entry().iDetails;
}
// get the remote mail count
TInt CEmailExampleEngine::RemoteEmailCount()
{
return iRemoteCount;
}
// open remote email. may cause system to go online to retrieve mail
void CEmailExampleEngine::RemoteOpenEmailL(TInt aIndex)
{
TMsvId entryId=(*iRemoteEntries)[aIndex];
if(aIndex<0 || aIndex>=iRemoteCount)
{
User::Leave(KErrGeneral);
}
OpenEmailL(entryId);
}
//opens a message given it's TMsvId
void CEmailExampleEngine::OpenEmailL(TMsvId& aEntryId)
{
//make sure that the object is ready
if(iState==EInitialising)
{
User::Leave(KErrNotReady);
}
if(iState==EReadyButNeedsUpdating)
{
UpdateRemoteCountL();
}
TMsvEntry entryToView;
TMsvId service;
// get the TMsvId and TMsvEntry for the given entryId
iMsvSession->GetEntry(aEntryId,service,entryToView);
// create a command absorbing control. The object is on the cleanup stack upon return
// this object will absord UI type events and silently ignore them.
CCommandAbsorbingControl*command = CCommandAbsorbingControl::NewLC();
CMsvOperationWait* waiter=CMsvOperationWait::NewLC();
waiter->Start();
// assert that the entry is not KUidMsvServiceEntryValue
__ASSERT_DEBUG(entryToView.iType.iUid!=KUidMsvServiceEntryValue,User::Invariant());
CBaseMtmUi* mtmUi=NULL;
// grab the appropriate mtmui object for this entry
TRAPD(ret,mtmUi=&iMtmStore->ClaimMtmUiAndSetContextL(entryToView));
User::LeaveIfError(ret);
CMtmStoreMtmReleaser::CleanupReleaseMtmUiLC(*iMtmStore,entryToView.iMtm);
CMsvOperation* op=mtmUi->OpenL(waiter->iStatus);
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(); // release mtmUi
CleanupStack::PopAndDestroy(waiter); // release CMvsOperationWait
CleanupStack::PopAndDestroy(command); // release CCommandAbsorbingControl
delete op;
iState=EEditing;
}
// handler between imap/pop
TInt CEmailExampleEngine::HandleCmdRemoteFetchL()
{
if( iProtocolType == EProtocolImap4 )
{
SyncWithRemoteServerImap4L();
}
else
{
FetchRemoteMailPop3L();
}
return KErrNone;
}
// initiate a remote mail fetch with pop3
TInt CEmailExampleEngine::FetchRemoteMailPop3L()
{
// delete any outstanding popmail objects
delete iPopMail;
iPopMail = NULL;
iPopMail = CPop3Mail::NewL(iStatus,*iMsvSession);
// reset this objects status
iStatus = KRequestPending;
iState = EWaitingForPop3;
SetActive();
return KErrNone;
}
// initiate a remote mail sync with imap4
TInt CEmailExampleEngine::SyncWithRemoteServerImap4L()
{
// delete any outstanding imapmail objects
delete iImapMail;
iImapMail = NULL;
iImapMail = CImap4Mail::NewL(iStatus,*iMsvSession);
// reset this objects status
iStatus = KRequestPending;
iState = EWaitingForImap4;
SetActive();
return KErrNone;
}
// update the entries
CMsvEntrySelection* CEmailExampleEngine::UpdateEntriesL(const TMsvId& aServiceId)
{
// make sure that there is a mtmRegistry & msmStore
if(iMtmReg==NULL)
{
iMtmReg=CClientMtmRegistry::NewL(*iMsvSession);
}
if(iMtmStore==NULL)
{
iMtmStore=CMtmStore::NewL(*iMsvSession);
}
// get the entry
CMsvEntry* entry=iMsvSession->GetEntryL(aServiceId);
CleanupStack::PushL(entry);
// get the entry's children
CMsvEntrySelection* entries=entry->ChildrenL();
CleanupStack::PopAndDestroy(entry);
return entries;
}
void CEmailExampleEngine::UpdateRemoteCountL()
{
if( iProtocolType == EProtocolImap4 )
{
UpdateRemoteCountImap4L();
}
else
{
UpdateRemoteCountPop3L();
}
}
// update the remote mail count imap4 version
void CEmailExampleEngine::UpdateRemoteCountImap4L()
{
CMsvEmailUtils* utils = CMsvEmailUtils::NewLC(*iMsvSession);
TMsvId id=NULL;
// get the id of the first imap4 mailbox or if
// not exists then first service
id = utils->GetFolderThenServiceIdL(KUidMsgTypeIMAP4);
CleanupStack::PopAndDestroy(utils); //CMsvEmailUtils
// reset the remote mail count and entries
iRemoteCount=0;
delete iRemoteEntries;
iRemoteEntries=NULL;
if(id == KMsvRootIndexEntryId)
{
iNoImap4defined = ETrue;
return;
}
else
{
iNoImap4defined = EFalse;
}
// get the remote mail entries
iRemoteEntries=UpdateEntriesL(id);
// if the nunber has chaneg then inform the observer
if(iRemoteEntries->Count()!=iRemoteCount)
{
iRemoteCount=iRemoteEntries->Count();
iObserver.HandleEngineChangedEventL(ERemoteCountChanged);
}
}
// update the remote mail count pop3 version
void CEmailExampleEngine::UpdateRemoteCountPop3L()
{
CMsvEmailUtils* utils = CMsvEmailUtils::NewLC(*iMsvSession);
TMsvId id=NULL;
id = utils->GetServiceIdL(KUidMsgTypePOP3);
CleanupStack::PopAndDestroy(utils);
// reset the remote mail count and entries
iRemoteCount=0;
delete iRemoteEntries;
iRemoteEntries=NULL;
if(id == KMsvRootIndexEntryId)
{
iNoPop3defined = ETrue;
return;
}
else
{
iNoPop3defined = EFalse;
}
// get the remote mail entries
iRemoteEntries=UpdateEntriesL(id);
// if the nunber has chaneg then inform the observer
if(iRemoteEntries->Count()!=iRemoteCount)
{
iRemoteCount=iRemoteEntries->Count();
iObserver.HandleEngineChangedEventL(ERemoteCountChanged);
}
}
TBool CEmailExampleEngine::HandleAccountNotDefined()
{
return ( ( iProtocolType == EProtocolImap4 ) ? Imap4AccountNotDefined() : Pop3AccountNotDefined() );
}
// ERemoteCountChanged ETrue if there is no IMAP4 account on this machine
TBool CEmailExampleEngine::Imap4AccountNotDefined()
{
return iNoImap4defined;
}
// return ETrue if there is no POP3 account on this machine
TBool CEmailExampleEngine::Pop3AccountNotDefined()
{
return iNoPop3defined;
}
// messaging session callback
void CEmailExampleEngine::HandleSessionEventL(TMsvSessionEvent aEvent,TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/ )
{
switch(aEvent)
{
// the messaging server is ready
case MMsvSessionObserver::EMsvServerReady:
{
if(iState==EInitialising)
{
TRAPD(err,UpdateRemoteCountL());
if(err==KErrNone)
{
iState=EReady;
}
else
{
iState=EReadyButNeedsUpdating;
}
}
}
break;
case MMsvSessionObserver::EMsvEntriesCreated:
case MMsvSessionObserver::EMsvEntriesChanged:
case MMsvSessionObserver::EMsvEntriesDeleted:
case MMsvSessionObserver::EMsvEntriesMoved:
UpdateRemoteCountL();
break;
case MMsvSessionObserver::EMsvMtmGroupInstalled:
case MMsvSessionObserver::EMsvMtmGroupDeInstalled:
case MMsvSessionObserver::EMsvGeneralError:
case MMsvSessionObserver::EMsvCloseSession:
case MMsvSessionObserver::EMsvServerFailedToStart:
case MMsvSessionObserver::EMsvCorruptedIndexRebuilt:
case MMsvSessionObserver::EMsvServerTerminated:
case MMsvSessionObserver::EMsvMediaChanged:
case MMsvSessionObserver::EMsvMediaUnavailable:
case MMsvSessionObserver::EMsvMediaAvailable:
case MMsvSessionObserver::EMsvMediaIncorrect:
case MMsvSessionObserver::EMsvCorruptedIndexRebuilding:
break;
}
}
void CEmailExampleEngine::SetProtocolType( TInt aProtocolType )
{
iProtocolType = aProtocolType;
}
void CEmailExampleEngine::Settings()
{
//Allocate memory for my custom dialog.
CSettingsDialog* dialog = new(ELeave) CSettingsDialog();
// Set engine pointer to settingsdialog
dialog->iEngine=this;
// Execute dialog
TInt ret = dialog->ExecuteLD(R_CHOICELIST_DIALOG);
if( ret == EEikBidOk )
{
SetProtocolType( iSettingProtocolType );
}
// update id
UpdateRemoteCountL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -