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

Symbian

开发平台:

C/C++

  1. /*
  2. * ============================================================================
  3. *  Name     : CImap4Mail from Imap4Mail.cpp
  4. *  Part of  : EmailExample
  5. *  Created  : 09/11/2003 by Forum Nokia
  6. *  Implementation notes:
  7. * basic statemachine
  8. *  Version  : 1.0
  9. *  Copyright: Nokia Corporation
  10. * ============================================================================
  11. */
  12. #include "Imap4Mail.h"
  13. #include "MsvEmailUtils.h"
  14. // constant strings for info print messages used when fetching mail.
  15. _LIT(KIMConnect, "Connecting to mailserver");
  16. _LIT(KIMSync, "Synchronising against mailserver");
  17. _LIT(KIMWaitSync, "Waiting background synchronize to finish");
  18. _LIT(KIMDisconnect, "Disconnecting");
  19. _LIT(KIMComplete,   "Operation complete");
  20. _LIT(KFetchTitle, "Imap4 operation in progress");
  21. _LIT(KFetchMessage, "Synchronising folders and message headers n against remote mailbox");
  22. // static creation. Doesn't leave a copy on the clean up stack
  23. CImap4Mail* CImap4Mail::NewL(TRequestStatus& aStatus,CMsvSession& aMsvSession)
  24. {
  25. CImap4Mail* self = new (ELeave) CImap4Mail(aStatus,aMsvSession);
  26. CleanupStack::PushL(self);
  27. self->ConstructL();
  28. CleanupStack::Pop(self);
  29. return self;
  30. }
  31. CImap4Mail::CImap4Mail(TRequestStatus& aStatus,CMsvSession& aMsvSession)
  32. : CActive(CActive::EPriorityStandard), iObserverStatus(aStatus), iMsvSession(aMsvSession)
  33. {
  34. CActiveScheduler::Add(this);
  35. }
  36. void CImap4Mail::ConstructL()
  37. {
  38. iState=EInitialising;
  39. // create an empty selection to used later.
  40. iMsvSelection = new(ELeave) CMsvEntrySelection();
  41. iState = EReady;
  42. Queue();
  43. }
  44. CImap4Mail::~CImap4Mail()
  45. {
  46. if(iOperation)
  47. {
  48. iOperation->Cancel();
  49. }
  50. Cancel();
  51. delete iOperation;
  52. delete iDialog;
  53. delete iMsvSelection;
  54. delete iImap4Mtm;
  55. delete iImap4Utils;
  56. }
  57. // active objects RunL functions acts as main state handling routine
  58. void CImap4Mail::RunL()
  59. {
  60. // get a pointer to our observers status
  61. TRequestStatus* st = &iObserverStatus;
  62. switch(iState)
  63. {
  64. case EReady:
  65. // tell the observer that the object os ready for use
  66. User::RequestComplete(st,KErrNone);
  67. break;
  68. case EConnecting:
  69. {
  70. // display connecting message and initiate connection
  71. User::InfoPrint(KIMConnect);
  72. ExecuteConnectL();
  73. }
  74. break;
  75. case ESync:
  76. {
  77. // display sync message and syncronize with remote server
  78. User::InfoPrint(KIMSync);
  79. ExecuteSyncL();
  80. }
  81. break;
  82. case EWaitSync:
  83. {
  84. // display message and wait for background sync operation to finish
  85. User::InfoPrint(KIMWaitSync);
  86. ExecuteWaitSyncL();
  87. }
  88. break;
  89. case EDisconnectRemote:
  90. // display disconnect message and initiate disconnect
  91. User::InfoPrint(KIMDisconnect);
  92. ExecuteDisconnectL();
  93. break;
  94. case EDisconnecting:
  95. // display disconnecting message, reset object and complete observers request
  96. User::InfoPrint(KIMComplete);
  97. delete iDialog;
  98. iDialog=NULL;
  99. iState = EReady;
  100. delete iOperation;
  101. iOperation=NULL;
  102. User::RequestComplete(st,KErrNone);
  103. break;
  104. case ECanceling:
  105. // cancel the any outstanding operations and reset object.
  106. iStatus = KRequestPending;
  107. iState= EReady;
  108. delete iOperation;
  109. iOperation=NULL;
  110. User::RequestComplete(st,KErrCancel);
  111. default:
  112. break;
  113. }
  114. }
  115. // Connect to remote mail box
  116. void CImap4Mail::ExecuteConnectL()
  117. {
  118. // reset our status
  119. iStatus = KRequestPending;
  120. TBuf8<1> null;
  121. // execute the Imap4 connect command
  122. MailCommandL(KIMAP4MTMConnect,null);
  123. //Note:  KIMAP4MTMConnectAndSynchronise would be more elegant for some applications
  124. iState=ESync;
  125. SetActive();
  126. }
  127. // full background syncronization with remote server
  128. void CImap4Mail::ExecuteSyncL()
  129. {
  130. // reset our status
  131. iStatus = KRequestPending;
  132. TBuf8<1> null;
  133. // Synchronises the service whose TMsvId is given by aSelection[0].
  134. // If the service is already synchronising, then complete with KErrServerBusy.
  135. MailCommandL(KIMAP4MTMFullSync, null );
  136. iState=EWaitSync;
  137. //iState=EDisconnectRemote;
  138. SetActive();
  139. }
  140. // waits for synchronization to end
  141. void CImap4Mail::ExecuteWaitSyncL()
  142. {
  143. // reset our status
  144. iStatus = KRequestPending;
  145. TBuf8<1> null;
  146. //Completes (with KErrNone) only when the background synchronisation has finished.
  147. //It is used to ensure that no UI-initiated folder syncing is performed during the background synchronisation.
  148. MailCommandL(KIMAP4MTMWaitForBackground,null);
  149. iState=EDisconnectRemote;
  150. SetActive();
  151. }
  152. // disconnect from service
  153. void CImap4Mail::ExecuteDisconnectL()
  154. {
  155. // reset our status
  156. iStatus = KRequestPending;
  157. TBuf8<1> null;
  158. //Cancels any operations in progress and sends logout messages to server.
  159. //As long as the background synchronisation, this will also run any pending delete operations queued while offline.
  160. MailCommandL(KIMAP4MTMDisconnect,null);
  161. iState=EDisconnecting;
  162. SetActive();
  163. }
  164. // interface to engine for sync
  165. void CImap4Mail::SyncWithRemoteServerL(TMsvId aMailId)
  166. {
  167. // panic client is object is not in EReady state.
  168. __ASSERT_DEBUG(iState==EReady,User::Invariant());
  169. iMailId=aMailId;
  170. // reset our status
  171. iObserverStatus = KRequestPending;
  172. // create cancel dialog
  173. CCknCancelDialog* dialog=CCknCancelDialog::NewL(&iDialog,this,KFetchTitle,KFetchMessage);
  174. // activate cancel dialog
  175.     dialog->RunDlgLD();
  176. LoadMtmL();
  177. iState=EConnecting;
  178. // set active and complete our own request.
  179. Queue();
  180. }
  181. // executes Imap4 mail commands
  182. void CImap4Mail::MailCommandL(TInt aCommand,TDes8& aParams)
  183. {
  184. // get the imap4 service id
  185. if(!iImap4Utils)
  186. {
  187. iImap4Utils = CMsvEmailUtils::NewL(iMsvSession);
  188. }
  189. TMsvId id = iImap4Utils->GetServiceIdL(KUidMsgTypeIMAP4);
  190. // make sure iServiceId is a remote type service
  191. if(iServiceId != KMsvLocalServiceIndexEntryId)
  192. {
  193. iMsvSelection->Reset();
  194. // append imap4 service entry id
  195. iMsvSelection->AppendL(id);
  196. // get the msventry for the service id
  197. CMsvEntry* service = iMsvSession.GetEntryL(iServiceId);
  198. CleanupStack::PushL(service);
  199. // make sure the mtm for the service is a Imap4 type
  200. if(service->Entry().iMtm == KUidMsgTypeIMAP4)
  201. {
  202. // delete and reset any outstanding operation
  203. if(iOperation)
  204. {
  205. iOperation->Cancel();
  206. }
  207. delete iOperation;
  208. iOperation=NULL;
  209. iOperation =  iImap4Mtm->InvokeAsyncFunctionL(aCommand,*iMsvSelection,aParams/*ptr*/,iStatus);
  210. }
  211. CleanupStack::PopAndDestroy(service);
  212. }
  213. else
  214. {
  215. // there is no Imap4 mail service defined on the device.
  216. User::Leave(KErrNotFound);
  217. }
  218. }
  219. void CImap4Mail::LoadMtmL()
  220. {
  221. // get the id for the Imap4 mtm
  222. if(!iImap4Utils)
  223. {
  224. iImap4Utils = CMsvEmailUtils::NewL(iMsvSession);
  225. }
  226. TMsvId id = iImap4Utils->GetServiceIdL(KUidMsgTypeIMAP4);
  227. // make sure that there is a Imap4 mtm defined in the system
  228. if(id == KMsvRootIndexEntryId)
  229. {
  230. User::Leave(KErrNotFound);
  231. }
  232.     TMsvEntry tmp;
  233. // get the entry
  234. User::LeaveIfError(iMsvSession.GetEntry(id,iServiceId,tmp));
  235. // create a Imap4 mtm from the service id
  236. iImap4Mtm = iImap4Utils->InstantiateImapClientMtmL(iServiceId);
  237. }
  238. // called by the user pressing the cancel button
  239. void CImap4Mail::CancelOperation()
  240. {
  241. // the dialog has destroyed itself so set the pointer to null
  242. iDialog=NULL;
  243. // cancel the operation if one exists
  244. if(iOperation)
  245. {
  246. iOperation->Cancel();
  247. }
  248. iState=ECanceling;
  249. if(!IsActive())
  250. {
  251. SetActive();
  252. }
  253. }
  254. // msvsession callback handling funtion
  255. void CImap4Mail::HandleSessionEventL(TMsvSessionEvent aEvent,TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/)
  256. {
  257. switch(aEvent)
  258. {
  259. case MMsvSessionObserver::EMsvServerReady:
  260. if(iState==EInitialising)
  261. {
  262. // the message server is now ready for use.
  263. // set our state to ready and queue the next state.
  264. iState = EReady;
  265. Queue();
  266. }
  267. break;
  268. case EMsvServerTerminated:
  269. iState=EInitialising;
  270. break;
  271. case MMsvSessionObserver::EMsvEntriesCreated:
  272. case MMsvSessionObserver::EMsvEntriesChanged:
  273. case MMsvSessionObserver::EMsvEntriesDeleted:
  274. case MMsvSessionObserver::EMsvEntriesMoved:
  275. case MMsvSessionObserver::EMsvMtmGroupInstalled:
  276. case MMsvSessionObserver::EMsvMtmGroupDeInstalled:
  277. case MMsvSessionObserver::EMsvGeneralError:
  278. case MMsvSessionObserver::EMsvCloseSession:
  279. case MMsvSessionObserver::EMsvServerFailedToStart:
  280. case MMsvSessionObserver::EMsvCorruptedIndexRebuilt:
  281. case MMsvSessionObserver::EMsvMediaChanged:
  282. case MMsvSessionObserver::EMsvMediaUnavailable:
  283. case MMsvSessionObserver::EMsvMediaAvailable:
  284. case MMsvSessionObserver::EMsvMediaIncorrect:
  285. case MMsvSessionObserver::EMsvCorruptedIndexRebuilding:
  286. break;
  287. }
  288. }
  289. void CImap4Mail::DoCancel()
  290. {}
  291. // don't handle errors at the moment
  292. TInt CImap4Mail::RunError(TInt aError)
  293. {
  294. return aError;
  295. }
  296. // complete our own status.
  297. // this allows the active scheduler chance to service other active objects before
  298. // return back to our RunL
  299. void CImap4Mail::Queue()
  300. {
  301. if(!IsActive())
  302. {
  303. SetActive();
  304. }
  305. TRequestStatus* st= &iStatus;
  306. User::RequestComplete(st,KErrNone);
  307. }