EmailExampleEngine.cpp
上传用户:sempras
上传日期:2007-03-04
资源大小:821k
文件大小:12k
源码类别:

Symbian

开发平台:

C/C++

  1. /*
  2. * ============================================================================
  3. *  Name     : CEmailExampleEngine from EmailExampleEngine.cpp
  4. *  Part of  : EmailExample
  5. *  Created  : 09/11/2003 by Forum Nokia
  6. *  Implementation notes:
  7. * basic statemachine with 2 internal state machines one
  8. * for pop one for imap.
  9. *  Version  : 1.0
  10. *  Copyright: Nokia Corporation
  11. * ============================================================================
  12. */
  13. #include "EmailExampleEngine.h"
  14. #include <EmailExample.rsg>
  15. #include <mtclreg.h>            // for CClientMtmRegistry
  16. #include <mtmstore.h> // for CMtmStore
  17. #include <mtmuibas.h> // for CBaseMtmUi
  18. #include <comabs.h> // for CCommandAbsorbingControl
  19. #include <eikenv.h> // for CEikonEnv
  20. #include "Imap4Mail.h"
  21. #include "Pop3Mail.h"
  22. #include "msvEmailUtils.h"
  23. #include "settingsdialog.h"
  24. //static creation
  25. CEmailExampleEngine* CEmailExampleEngine::NewL(MEmailExampleEngineObserver& aObserver)
  26. {
  27. CEmailExampleEngine* engine=new(ELeave) CEmailExampleEngine(aObserver);
  28. CleanupStack::PushL(engine);
  29. engine->ConstructL();
  30. CleanupStack::Pop(engine);
  31. return engine;
  32. }
  33. // actual constructor. Create with standard prioritory
  34. CEmailExampleEngine::CEmailExampleEngine(MEmailExampleEngineObserver& aObserver)
  35. : CActive(CActive::EPriorityStandard), iObserver(aObserver)
  36. {
  37. // add this object to the active scheduler
  38. CActiveScheduler::Add(this);
  39. }
  40. // destructor
  41. CEmailExampleEngine::~CEmailExampleEngine()
  42. {
  43. Cancel();
  44. delete iEntry;
  45. delete iImapMail;
  46. delete iMtmReg;
  47. delete iMtmStore;
  48.     delete iRemoteEntries;
  49. delete iMsvSession; //Session must be deleted last
  50. }
  51. // sencond phase of construction
  52. void CEmailExampleEngine::ConstructL()
  53. {
  54. // set initial object state
  55. iState=EInitialising;
  56. // create and open a session towards messaging
  57. // the open operation is asynchronous and HandleSessionEventL will be called when the open is complete
  58.     iMsvSession=CMsvSession::OpenAsyncL(*this);
  59. // Default protocol values
  60. iProtocolType=EProtocolImap4;
  61. iSettingProtocolType=EProtocolImap4;
  62. }
  63. // Handles async completions
  64. void CEmailExampleEngine::RunL()
  65. {
  66. switch(iState)
  67. {
  68. // waiting for a imap4 operation to complete
  69. case EWaitingForImap4:
  70. {
  71. iStatus = KRequestPending;
  72. iState = ESyncImap4;
  73. SetActive();
  74. // initiate remote mail sync
  75. TRAPD(ret,iImapMail->SyncWithRemoteServerL());
  76. if(ret != KErrNone)
  77. {
  78. // if there was an error delete imap mail and reset object
  79. delete iImapMail;
  80. iImapMail=NULL;
  81. iState=EReady;
  82. TRequestStatus* st= &iStatus;
  83. // signal own status to reset object to start state
  84. User::RequestComplete(st,KErrNone);
  85. }
  86. }
  87. break;
  88. case ESyncImap4:
  89. {
  90. if(iStatus == KErrCancel)
  91. {
  92. CEikonEnv::Static()->InfoMsg(R_EMAILEXAMPLEAPP_REMOTE_CANCELED);
  93. }
  94. delete iImapMail;
  95. iImapMail=NULL;
  96. UpdateRemoteCountImap4L();
  97. iState=EReady;
  98. }
  99. break;
  100. // waiting for a pop3 operation to complete
  101. case EWaitingForPop3:
  102. {
  103. iStatus = KRequestPending;
  104. iState = EFetchingPop3;
  105. SetActive();
  106. // initiate remote mail fetch
  107. TRAPD(ret,iPopMail->FetchRemoteMailL());
  108. if(ret != KErrNone)
  109. {
  110. // if there was an error delete pop mail and reset object
  111. delete iPopMail;
  112. iPopMail=NULL;
  113. // reset state
  114. iState=EReady;
  115. TRequestStatus* st= &iStatus;
  116. // signal own status to reset object to start state
  117. User::RequestComplete(st,KErrNone);
  118. }
  119. }
  120. break;
  121. case EFetchingPop3:
  122. {
  123. // check current status and display cancel message if neccessary
  124. if(iStatus == KErrCancel)
  125. {
  126. CEikonEnv::Static()->InfoMsg(R_EMAILEXAMPLEAPP_REMOTE_CANCELED);
  127. }
  128. delete iPopMail;
  129. iPopMail=NULL;
  130. UpdateRemoteCountPop3L();
  131. iState=EReady;
  132. }
  133. break;
  134. default:
  135. break;
  136. }
  137. }
  138. // nothing to cancel
  139. void CEmailExampleEngine::DoCancel()
  140. {}
  141. // simply return error value
  142. TInt CEmailExampleEngine::RunError(TInt aError)
  143. {
  144. return aError;
  145. }
  146. // Get the subject of the email
  147. TPtrC CEmailExampleEngine::RemoteEmailTextL(TInt aIndex)
  148. {
  149. TMsvId entryId=(*iRemoteEntries)[aIndex];
  150. if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
  151. {
  152. delete iEntry;
  153. iEntry=NULL;
  154. iEntry=iMsvSession->GetEntryL(entryId);
  155. }
  156. return iEntry->Entry().iDescription;
  157. }
  158. TPtrC CEmailExampleEngine::RemoteEmailSenderL(TInt aIndex)
  159. {
  160. TMsvId entryId=(*iRemoteEntries)[aIndex];
  161. if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
  162. {
  163. delete iEntry;
  164. iEntry=NULL;
  165. iEntry=iMsvSession->GetEntryL(entryId);
  166. }
  167. return iEntry->Entry().iDetails;
  168. }
  169. // get the remote mail count
  170. TInt CEmailExampleEngine::RemoteEmailCount()
  171. {
  172. return iRemoteCount;
  173. }
  174. // open remote email. may cause system to go online to retrieve mail
  175. void CEmailExampleEngine::RemoteOpenEmailL(TInt aIndex)
  176. {
  177. TMsvId entryId=(*iRemoteEntries)[aIndex];
  178. if(aIndex<0 || aIndex>=iRemoteCount)
  179. {
  180. User::Leave(KErrGeneral);
  181. }
  182. OpenEmailL(entryId);
  183. }
  184. //opens a message given it's TMsvId
  185. void CEmailExampleEngine::OpenEmailL(TMsvId& aEntryId)
  186. {
  187. //make sure that the object is ready
  188. if(iState==EInitialising)
  189. {
  190. User::Leave(KErrNotReady);
  191. }
  192. if(iState==EReadyButNeedsUpdating)
  193. {
  194. UpdateRemoteCountL();
  195. }
  196. TMsvEntry entryToView;
  197. TMsvId service;
  198. // get the TMsvId and TMsvEntry for the given entryId
  199. iMsvSession->GetEntry(aEntryId,service,entryToView);
  200. // create a command absorbing control. The object is on the cleanup stack upon return
  201. // this object will absord UI type events and silently ignore them.
  202. CCommandAbsorbingControl*command = CCommandAbsorbingControl::NewLC();
  203. CMsvOperationWait* waiter=CMsvOperationWait::NewLC();
  204. waiter->Start();
  205. // assert that the entry is not KUidMsvServiceEntryValue
  206. __ASSERT_DEBUG(entryToView.iType.iUid!=KUidMsvServiceEntryValue,User::Invariant());
  207. CBaseMtmUi* mtmUi=NULL;
  208. // grab the appropriate mtmui object for this entry
  209. TRAPD(ret,mtmUi=&iMtmStore->ClaimMtmUiAndSetContextL(entryToView));
  210. User::LeaveIfError(ret);
  211. CMtmStoreMtmReleaser::CleanupReleaseMtmUiLC(*iMtmStore,entryToView.iMtm);
  212. CMsvOperation* op=mtmUi->OpenL(waiter->iStatus);
  213. CActiveScheduler::Start();
  214. CleanupStack::PopAndDestroy();   // release mtmUi
  215. CleanupStack::PopAndDestroy(waiter);  // release CMvsOperationWait
  216. CleanupStack::PopAndDestroy(command); // release CCommandAbsorbingControl
  217. delete op;
  218. iState=EEditing;
  219. }
  220. // handler between imap/pop
  221. TInt CEmailExampleEngine::HandleCmdRemoteFetchL()
  222. {
  223. if( iProtocolType == EProtocolImap4 )
  224. {
  225. SyncWithRemoteServerImap4L();
  226. }
  227. else
  228. {
  229. FetchRemoteMailPop3L();
  230. }
  231. return KErrNone;
  232. }
  233. // initiate a remote mail fetch with pop3
  234. TInt CEmailExampleEngine::FetchRemoteMailPop3L()
  235. {
  236. // delete any outstanding popmail objects
  237. delete iPopMail;
  238. iPopMail = NULL;
  239. iPopMail = CPop3Mail::NewL(iStatus,*iMsvSession);
  240. // reset this objects status
  241. iStatus = KRequestPending;
  242. iState = EWaitingForPop3;
  243. SetActive();
  244. return KErrNone;
  245. }
  246. // initiate a remote mail sync with imap4
  247. TInt CEmailExampleEngine::SyncWithRemoteServerImap4L()
  248. {
  249. // delete any outstanding imapmail objects
  250. delete iImapMail;
  251. iImapMail = NULL;
  252. iImapMail = CImap4Mail::NewL(iStatus,*iMsvSession);
  253. // reset this objects status
  254. iStatus = KRequestPending;
  255. iState = EWaitingForImap4;
  256. SetActive();
  257. return KErrNone;
  258. }
  259. // update the entries
  260. CMsvEntrySelection* CEmailExampleEngine::UpdateEntriesL(const TMsvId& aServiceId)
  261. {
  262. // make sure that there is a mtmRegistry & msmStore
  263. if(iMtmReg==NULL)
  264. {
  265. iMtmReg=CClientMtmRegistry::NewL(*iMsvSession);
  266. }
  267. if(iMtmStore==NULL)
  268. {
  269. iMtmStore=CMtmStore::NewL(*iMsvSession);
  270. }
  271. // get the entry
  272. CMsvEntry* entry=iMsvSession->GetEntryL(aServiceId);
  273. CleanupStack::PushL(entry);
  274. // get the entry's children
  275. CMsvEntrySelection* entries=entry->ChildrenL();
  276. CleanupStack::PopAndDestroy(entry);
  277. return entries;
  278. }
  279. void CEmailExampleEngine::UpdateRemoteCountL()
  280. {
  281. if( iProtocolType == EProtocolImap4 )
  282. {
  283. UpdateRemoteCountImap4L();
  284. }
  285. else
  286. {
  287. UpdateRemoteCountPop3L();
  288. }
  289. }
  290. // update the remote mail count imap4 version
  291. void CEmailExampleEngine::UpdateRemoteCountImap4L()
  292. {
  293. CMsvEmailUtils* utils = CMsvEmailUtils::NewLC(*iMsvSession);
  294. TMsvId id=NULL;
  295. // get the id of the first imap4 mailbox or if
  296. // not exists then first service
  297. id = utils->GetFolderThenServiceIdL(KUidMsgTypeIMAP4);
  298. CleanupStack::PopAndDestroy(utils); //CMsvEmailUtils
  299. // reset the remote mail count and entries
  300. iRemoteCount=0;
  301. delete iRemoteEntries;
  302. iRemoteEntries=NULL;
  303. if(id == KMsvRootIndexEntryId)
  304. {
  305. iNoImap4defined = ETrue;
  306. return;
  307. }
  308. else
  309. {
  310. iNoImap4defined = EFalse;
  311. }
  312. // get the remote mail entries
  313. iRemoteEntries=UpdateEntriesL(id);
  314. // if the nunber has chaneg then inform the observer
  315. if(iRemoteEntries->Count()!=iRemoteCount)
  316. {
  317. iRemoteCount=iRemoteEntries->Count();
  318. iObserver.HandleEngineChangedEventL(ERemoteCountChanged);
  319. }
  320. }
  321. // update the remote mail count pop3 version
  322. void CEmailExampleEngine::UpdateRemoteCountPop3L()
  323. {
  324. CMsvEmailUtils* utils = CMsvEmailUtils::NewLC(*iMsvSession);
  325. TMsvId id=NULL;
  326. id = utils->GetServiceIdL(KUidMsgTypePOP3);
  327. CleanupStack::PopAndDestroy(utils);
  328. // reset the remote mail count and entries
  329. iRemoteCount=0;
  330. delete iRemoteEntries;
  331. iRemoteEntries=NULL;
  332. if(id == KMsvRootIndexEntryId)
  333. {
  334. iNoPop3defined = ETrue;
  335. return;
  336. }
  337. else
  338. {
  339. iNoPop3defined = EFalse;
  340. }
  341. // get the remote mail entries
  342. iRemoteEntries=UpdateEntriesL(id);
  343. // if the nunber has chaneg then inform the observer
  344. if(iRemoteEntries->Count()!=iRemoteCount)
  345. {
  346. iRemoteCount=iRemoteEntries->Count();
  347. iObserver.HandleEngineChangedEventL(ERemoteCountChanged);
  348. }
  349. }
  350. TBool CEmailExampleEngine::HandleAccountNotDefined()
  351. {
  352. return ( ( iProtocolType == EProtocolImap4 ) ? Imap4AccountNotDefined() : Pop3AccountNotDefined() );
  353. }
  354. // ERemoteCountChanged ETrue if there is no IMAP4 account on this machine
  355. TBool CEmailExampleEngine::Imap4AccountNotDefined()
  356. {
  357. return iNoImap4defined;
  358. }
  359. // return ETrue if there is no POP3 account on this machine
  360. TBool CEmailExampleEngine::Pop3AccountNotDefined()
  361. {
  362. return iNoPop3defined;
  363. }
  364. // messaging session callback
  365. void CEmailExampleEngine::HandleSessionEventL(TMsvSessionEvent aEvent,TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/ )
  366. {
  367. switch(aEvent)
  368. {
  369.  // the messaging server is ready
  370. case MMsvSessionObserver::EMsvServerReady:
  371. {
  372. if(iState==EInitialising)
  373. {
  374. TRAPD(err,UpdateRemoteCountL());
  375. if(err==KErrNone)
  376. {
  377. iState=EReady;
  378. }
  379. else
  380. {
  381. iState=EReadyButNeedsUpdating;
  382. }
  383. }
  384. }
  385. break;
  386. case MMsvSessionObserver::EMsvEntriesCreated:
  387. case MMsvSessionObserver::EMsvEntriesChanged:
  388. case MMsvSessionObserver::EMsvEntriesDeleted:
  389. case MMsvSessionObserver::EMsvEntriesMoved:
  390. UpdateRemoteCountL();
  391. break;
  392. case MMsvSessionObserver::EMsvMtmGroupInstalled:
  393. case MMsvSessionObserver::EMsvMtmGroupDeInstalled:
  394. case MMsvSessionObserver::EMsvGeneralError:
  395. case MMsvSessionObserver::EMsvCloseSession:
  396. case MMsvSessionObserver::EMsvServerFailedToStart:
  397. case MMsvSessionObserver::EMsvCorruptedIndexRebuilt:
  398. case MMsvSessionObserver::EMsvServerTerminated:
  399. case MMsvSessionObserver::EMsvMediaChanged:
  400. case MMsvSessionObserver::EMsvMediaUnavailable:
  401. case MMsvSessionObserver::EMsvMediaAvailable:
  402. case MMsvSessionObserver::EMsvMediaIncorrect:
  403. case MMsvSessionObserver::EMsvCorruptedIndexRebuilding:
  404. break;
  405. }
  406. }
  407. void CEmailExampleEngine::SetProtocolType( TInt aProtocolType )
  408. {
  409. iProtocolType = aProtocolType;
  410. }
  411. void CEmailExampleEngine::Settings()
  412. {
  413. //Allocate memory for my custom dialog.
  414. CSettingsDialog* dialog = new(ELeave) CSettingsDialog();
  415. // Set engine pointer to settingsdialog
  416. dialog->iEngine=this;
  417. // Execute dialog
  418. TInt ret = dialog->ExecuteLD(R_CHOICELIST_DIALOG);
  419. if( ret == EEikBidOk )
  420. {
  421. SetProtocolType( iSettingProtocolType );
  422. }
  423. // update id
  424. UpdateRemoteCountL();
  425. }