|
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Client MTM for the IMAP4 protocol |
|
15 // |
|
16 // |
|
17 |
|
18 |
|
19 #if !defined (__IMPCMTM_H__) |
|
20 #define __IMPCMTM_H__ |
|
21 |
|
22 #if !defined (__MTCLBASE_H_) |
|
23 #include <mtclbase.h> |
|
24 #endif |
|
25 |
|
26 #if !defined (__MIUTHDR_H_) |
|
27 #include <miuthdr.h> |
|
28 #endif |
|
29 |
|
30 #if !defined (__MIUTPARS_H__) |
|
31 #include <miutpars.h> //TImMessageField |
|
32 #endif |
|
33 |
|
34 #if !defined (__IMAPSET_H__) |
|
35 #include <imapset.h> |
|
36 #endif |
|
37 |
|
38 #if !defined (__IMAPCMDS_H__) |
|
39 #include <imapcmds.h> |
|
40 #endif |
|
41 |
|
42 #if !defined(__OFFOP_H__) |
|
43 #include <offop.h> |
|
44 #endif |
|
45 |
|
46 #if !defined(__MIUTMSG_H__) |
|
47 #include <miutmsg.h> |
|
48 #endif |
|
49 |
|
50 |
|
51 |
|
52 // Forward declarations. |
|
53 class CImap4ClientSessionObserver; |
|
54 class CImImap4GetMail; |
|
55 class CImEmailAutoSend; |
|
56 |
|
57 // |
|
58 // Imap4 Client MTM |
|
59 class CImap4ClientMtm : public CBaseMtm, public MImUndoOffLineOperation |
|
60 |
|
61 /** IMAP4 client MTM interface, providing access to the email services using the IMAP4 |
|
62 protocol. |
|
63 |
|
64 The class provides support for: |
|
65 |
|
66 - connecting to remote IMAP4 mail servers |
|
67 - synchronising message headers with mailboxes on these servers |
|
68 - getting message bodies and attachments |
|
69 - copying and moving messages |
|
70 - creating messages that forward or reply to IMAP4 messages |
|
71 - server notification of new messages using IMAP IDLE |
|
72 - queueing operations requested when there is no connection to a mail server, to be |
|
73 performed when a connection is made (offline operations). |
|
74 |
|
75 Note that CImap4ClientMtm does not support many of the generic functions defined by |
|
76 the @c CBaseMtm base class. In particular: |
|
77 |
|
78 - Message address information, body, subjects, and attachments are not manipulated |
|
79 through CImap4ClientMtm. Consequently, SaveMessageL() has an empty |
|
80 implementation, and is not used. Message access and manipulation is instead done |
|
81 through CImEmailMessage, which understands the email specific message formats, |
|
82 including MHTML (RFC 2557). The RFC 822 email header, which includes subject and |
|
83 address information, is encapsulated in a CImHeader object, which can be obtained from |
|
84 a CImEmailMessage object. IMAP also has its own specific flags, such as draft, |
|
85 answered, and deleted: this can be accessed through TMsvEmailEntry, which extends the |
|
86 message server's generic TMsvEntry to add email-specific information. |
|
87 |
|
88 - The idea of a default service used by base class functions DefaultServiceL(), |
|
89 ChangeDefaultServiceL(), and RemoveDefaultServiceL() is not supported. |
|
90 |
|
91 IMAP specific commands are issued through the InvokeAsyncFunctionL() function, with |
|
92 the commands defined in the #TImap4Cmds enumeration. Details of particular commands |
|
93 are given in the documentation for that enumeration, but the following describes some of |
|
94 the key concepts required to use those commands. Note that usually these commands do |
|
95 not correspond directly to the IMAP protocol commands described in RFC 3501. Instead, |
|
96 they are at a higher level, to simplify the logic required for an email client program. |
|
97 |
|
98 -------------------------------------- |
|
99 |
|
100 Connection and services |
|
101 |
|
102 Settings for connection to and use of an IMAP4 mail server and its mailboxes are |
|
103 encapsulated in an CImImap4Settings object, created and accessed through |
|
104 CEmailAccounts. Preferences for the network connection (e.g. the ISP to use) to be made |
|
105 to access an IMAP server are also accessed through CEmailAccounts. |
|
106 |
|
107 The settings are associated with a service-type entry in the Message Server's message |
|
108 store. Message and folder type entries under the service entry store a local copy of the |
|
109 mailboxes and messages that are present on an IMAP server. For this reason, the service |
|
110 is sometimes referred to as the local mirror of an IMAP server. |
|
111 |
|
112 By default, it is assumed that the user has a primary mailbox on the server called INBOX, |
|
113 though this can be changed if necessary using CImImap4Settings::SetFolderPathL(). (To |
|
114 avoid confusion, the term "Inbox" used in the IMAP MTM documentation refers to this |
|
115 mailbox, rather than the Message Server's standard local Inbox folder.) |
|
116 |
|
117 The settings store the user's log-in details required to access the IMAP server, and other |
|
118 settings not related to connection, but which affect the behaviour of commands, such as |
|
119 synchronisation, made to the service. |
|
120 |
|
121 -------------------------------------- |
|
122 |
|
123 Synchronisation |
|
124 |
|
125 The IMAP4 MTM provides the means to synchronise message headers on a remote |
|
126 IMAP mailboxes with the messages headers on the phone. Note that synchronisation only |
|
127 refers to message headers. Once headers are synchronised, populate operations (i.e. |
|
128 getting the message bodies) can be done. |
|
129 |
|
130 The basic steps involved in a full synchronisation are: |
|
131 |
|
132 - The headers of messages in the Inbox are synchronised. |
|
133 - The local list of folders is synchronised with those existing on the remote IMAP service. |
|
134 Depending on the service settings, the local or remote settings of subscribed mailboxes |
|
135 may be updated (see below for more information). |
|
136 - The headers of messages in subscribed folders are synchronised. |
|
137 |
|
138 Queued offline operations (see below) pending on the Inbox or subscribed folders are |
|
139 performed prior to the relevant folder being synchronised. |
|
140 |
|
141 Synchronisations can be performed in the background or the foreground. A foreground |
|
142 synchronisation means no other requests, such as message fetching, can be made to the |
|
143 MTM, until the synchronisation is complete. A background synchronisation allows some |
|
144 types of command to be given while it is in progress. Commands that write to the remote |
|
145 server are not allowed however while a background synchronisation is in progress. A |
|
146 client is informed of the state of a background synchronisation through the |
|
147 MMsvImapConnectionObserver callback interface. |
|
148 |
|
149 Synchronisations commands are made through |
|
150 CImap4ClientMtm::InvokeAsyncFunctionL(). There a variety of commands available |
|
151 that give different options for compounding synchronisation |
|
152 with other commands, such as connection, and synchronising only particular folders. See |
|
153 TImap4Cmds for details. Progress information for synchronisation commands can be |
|
154 obtained from the CMsvOperation object returned by the InvokeAsyncFunctionL(). |
|
155 Synchronisation progress information is encapsulated in a TImap4SyncProgress object. |
|
156 |
|
157 Settings that affect how a synchronisation is performed include: |
|
158 |
|
159 - Subscriptions: when an IMAP service had been synchronised, the Messaging server will |
|
160 contain entries for all folders on the remote server. These entries will be marked invisible |
|
161 within the TMsvEntry for the folder, implying that they should be invisible to the user. |
|
162 Messages in these folders are not synchronised unless the folder has been subscribed to. |
|
163 Note a folder subscription can be set either locally (i.e. just on the phone), using |
|
164 the #KIMAP4MTMLocalSubscribe command, or remotely (on the server), possibly through email |
|
165 clients on other devices. A service can be set to synchronise folders using either or both |
|
166 of these types of subscription (CImImap4Settings::SetSynchronise()). Local and remote |
|
167 subscriptions can themselves be synchronised in various ways (CImImap4Settings::SetSuscribe()). |
|
168 |
|
169 - Filters: a filter prevents certain e-mail messages from being synchronised onto the |
|
170 device when a client requests a synchronisation. Filters can include anything permitted by |
|
171 the IMAP Search command, including date, size, content, and message flags. |
|
172 |
|
173 - Limits: service settings can limit the number of emails synchronised to the inbox |
|
174 (CImImap4Settings::SetInboxSynchronisationLimit()), and to other folders |
|
175 (CImImap4Settings::SetMailboxSynchronisationLimit()). |
|
176 |
|
177 - Sync rate: one of the synchronisation commands |
|
178 (KIMAP4MTMConnectAndSyncCompleteAfterDisconnect) periodically resynchronises |
|
179 the Inbox until the service is disconnected. CImImap4Settings::SyncRate() sets the |
|
180 refresh period. |
|
181 |
|
182 -------------------------------------- |
|
183 |
|
184 Getting and copying messages |
|
185 |
|
186 After messages headers have been synchronised, message bodies and attachments can be |
|
187 fetched from the remote email server. Getting message parts and saving them in the |
|
188 mirror service is calling populating them. |
|
189 |
|
190 Commands for these actions can be made through |
|
191 CImap4ClientMtm::InvokeAsyncFunctionL(). There are a large number of commands, |
|
192 for different combinations of these options: |
|
193 |
|
194 - action type: whether to just populate messages, or to also copy or move them to a local |
|
195 folder |
|
196 - message selection: whether to get all, new, or selected messages |
|
197 - connection: whether to make a new connection or assume an existing connection |
|
198 - disconnect: whether to disconnect or stay online after operation is complete |
|
199 |
|
200 For the populate type commands, further options can be set that control the message |
|
201 getting behaviour. Basic options control, encapsulated in TImImap4GetMailInfo, specify |
|
202 whether body text and/or attachments are fetched, and a maximum message size. There |
|
203 are also options, encapsulated in TImImap4GetPartialMailInfo, that allow size limits to |
|
204 be separately specified for body text and/or attachments. If the the body is larger than the |
|
205 limit, then the body is partially downloaded up to the limit. Only attachments smaller |
|
206 than the specified size are downloaded. A partially downloaded message can later be |
|
207 fully downloaded. |
|
208 |
|
209 For the copy or move type commands, a TImImap4GetMailInfo parameter is supplied, in |
|
210 order to specify the destination folder for the messages, and a maximum message size. |
|
211 |
|
212 Progress information for getting commands can be obtained from the CMsvOperation |
|
213 object returned by the InvokeAsyncFunctionL(). Progress information is encapsulated in |
|
214 a TImap4GenericProgress object. |
|
215 |
|
216 Fetching and then copying or moving specified messages can also be performed by using |
|
217 the standard Messaging Framework @c CMsvEntry::CopyL() and @c |
|
218 CMsvEntry::MoveL() functions on entries under the remote service. If these functions are |
|
219 used, then the entire message is fetched without size limits. |
|
220 |
|
221 CMsvEntry functions can also be used to: |
|
222 |
|
223 - create a folder on a remote server |
|
224 - delete messages |
|
225 - copy or move messages from a local folder into a remote folder |
|
226 - copy or move messages between remote folders |
|
227 |
|
228 Note that changing an existing entry through CMsvEntry is not supported. An MTM- |
|
229 specific command #KIMAP4MTMRenameFolder is instead provided to rename a remote |
|
230 folder. |
|
231 |
|
232 The page "CMsvEntry functions for IMAP4 message entries", linked to in the "See also" |
|
233 section below, provides more details on using CMsvEntry. |
|
234 |
|
235 -------------------------------------- |
|
236 |
|
237 Offline operations |
|
238 |
|
239 Some operations can only be performed while online, while other commands may |
|
240 be stored while offline for processing when next connected. An attempt to perform a |
|
241 command while offline that requires the MTM to be connected results in immediate |
|
242 completion with the error code KErrDisconnected. |
|
243 |
|
244 Permitted offline operations include: |
|
245 |
|
246 - copy |
|
247 - move |
|
248 - delete |
|
249 |
|
250 Queued offline operations are usually performed when a connection is made, prior to the |
|
251 relevant folder being synchronised. Delete operations can alternatively be set to be done |
|
252 on disconnection using the service setting |
|
253 CImImap4Settings::SetDeleteEmailsWhenDisconnecting(). |
|
254 |
|
255 Note that: |
|
256 - Offline operations are only permitted if the service setting SetDisconnectedUserMode() |
|
257 is true. |
|
258 - It is possible to undo pending offline operations using the commands |
|
259 #KIMAP4MTMCancelOffLineOperations and #KIMAP4MTMUndeleteAll. |
|
260 |
|
261 -------------------------------------- |
|
262 |
|
263 IMAP IDLE support |
|
264 |
|
265 IMAP IDLE (RFC 2177) is an optional expansion of the IMAP email accessing protocol |
|
266 that allows the server to send updates to the client that messages have been created or |
|
267 deleted in real time. The IDLE command is sent from the client to the server when the |
|
268 client is ready to accept unsolicited mailbox update messages. Whether the client requests |
|
269 the server to provide IDLE support is set in the CImImap4Settings::SetImapIdle() service |
|
270 setting. When the IMAP MTM receives such a notification, it synchronises the changed |
|
271 folder. Email clients can be notified of such changes by setting a MMsvEntryObserver |
|
272 observer on a folder. |
|
273 |
|
274 @publishedAll |
|
275 @released |
|
276 */ |
|
277 { |
|
278 public: |
|
279 IMPORT_C static CImap4ClientMtm* NewL(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession); |
|
280 |
|
281 ~CImap4ClientMtm(); |
|
282 void HandleEntryEvent(TMsvEntryEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3); |
|
283 void StoreL(); // uses a CMsvStore from the Session |
|
284 void RestoreL(); |
|
285 CMsvOperation* ReplyL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus); |
|
286 CMsvOperation* ForwardL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus); |
|
287 TUint ValidateMessage(TUint aPartList); |
|
288 TMsvPartList Find(const TDesC& aTextToFind, TMsvPartList aPartList); |
|
289 void SaveMessageL(); |
|
290 void LoadMessageL(); |
|
291 IMPORT_C void StoreSettingsL(); // uses a CMsvStore from the session |
|
292 IMPORT_C void RestoreSettingsL(); |
|
293 |
|
294 // --- RTTI functions --- |
|
295 TInt QueryCapability(TUid aCapability, TInt& aResponse); |
|
296 void InvokeSyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter); |
|
297 CMsvOperation* InvokeAsyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter, TRequestStatus& aCompletionStatus); |
|
298 // Addressees have no meaning in the text mtm. |
|
299 void AddAddresseeL(const TDesC& aRealAddress); |
|
300 void AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias); |
|
301 void RemoveAddressee(TInt aIndex); |
|
302 |
|
303 // Attachment functions to support the SendAs API |
|
304 |
|
305 IMPORT_C virtual void AddAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus); |
|
306 IMPORT_C virtual void AddAttachmentL(RFile& aFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus); |
|
307 IMPORT_C virtual void AddLinkedAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus); |
|
308 IMPORT_C virtual void AddEntryAsAttachmentL(TMsvId aAttachmentId, TRequestStatus& aStatus); |
|
309 IMPORT_C virtual void CreateAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus); |
|
310 IMPORT_C void CreateMessageL(TMsvId aServiceId); |
|
311 |
|
312 IMPORT_C virtual TMsvId DefaultServiceL() const; |
|
313 IMPORT_C virtual void RemoveDefaultServiceL(); |
|
314 IMPORT_C virtual void ChangeDefaultServiceL(const TMsvId& aService); |
|
315 |
|
316 public: // Returning a list of all the offline operations for a service entry. |
|
317 IMPORT_C CImOperationQueueList* QueueListL(CMsvEntry& aServiceEntry); |
|
318 public: // Wrapper to settings |
|
319 IMPORT_C const CImImap4Settings& Imap4Settings() const; |
|
320 IMPORT_C void SetImap4SettingsL(const CImImap4Settings& aSettings); |
|
321 public: // inherited from MUndoOffLine |
|
322 virtual void UndoOffLineChangesL(const CImOffLineOperation& aDeleted, TMsvId aFolderId); |
|
323 protected: |
|
324 CImap4ClientMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession); |
|
325 void ConstructL(); |
|
326 void ContextEntrySwitched(); // called after the context of this instance has been changed to another entry |
|
327 |
|
328 private: |
|
329 TBool ValidateAddress(const TPtrC& anAddress); |
|
330 void SendOnNextConnectionL(); |
|
331 TMsvPartList DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList); |
|
332 void FilterAllOrNewMailsL(TInt aFunctionId,const CMsvEntrySelection& aSelection,TDes8& aParameter); |
|
333 void FilterMailSelectionL(const CMsvEntrySelection& aSelection,TDes8& aParameter); |
|
334 CMsvOperation* CopyMoveOrPopulateL(TInt aFunctionId,TDes8& aParameter,TRequestStatus& aCompletionStatus); |
|
335 void ConvertToPartialPopulate(TDes8& aParameter); |
|
336 // To check whether a partial fetch or full fetch of message has to be done. |
|
337 TBool IsPartialPopulate(TDes8& aParameter); |
|
338 |
|
339 private: |
|
340 CImImap4Settings iImImap4Settings; |
|
341 TImMessageField iTImMessageField; |
|
342 CImap4ClientSessionObserver* iImap4ClientSessionObserver; |
|
343 HBufC* iEmailAddressFormatString; // defines format of email address used by "Send as" API eg _L("/"%S/" <%S>") |
|
344 CImHeader* iHeader; |
|
345 CMsvEntrySelection* iMsvEntrySelection; |
|
346 CImImap4GetMail* iImIMAP4GetMail; |
|
347 CImEmailOperation* iImEmailOperation; |
|
348 TPckgBuf<TImImap4GetPartialMailInfo> iImap4GetPartialMailInfo; |
|
349 }; |
|
350 |
|
351 class CImImap4GetMail : public CMsvOperation |
|
352 /** Encapsulates an operation to copy, move, and populate (i.e. download the full |
|
353 message body) IMAP4 emails from the remote inbox to any local folder. |
|
354 |
|
355 Note that the same operations are available by calling CImap4ClientMtm::InvokeAsyncFunctionL() |
|
356 with a suitable command. |
|
357 |
|
358 @publishedAll |
|
359 @released |
|
360 */ |
|
361 { |
|
362 public: |
|
363 IMPORT_C CMsvOperation* GetMailL(TInt aFunctionId, CImap4ClientMtm& aImap4ClientMtm, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo, TRequestStatus& aObserverRequestStatus); |
|
364 ~CImImap4GetMail(); |
|
365 void DoCancel(); |
|
366 void RunL(); |
|
367 const TDesC8& ProgressL(); |
|
368 const TDesC8& FinalProgress(); |
|
369 private: |
|
370 CImImap4GetMail(CMsvSession& aMsvSession, CImap4ClientMtm& aImap4ClientMtm, TRequestStatus& aObserverRequestStatus); |
|
371 void ConstructL(TInt aFunctionId, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo); |
|
372 void SelectNextStateL(); // selects next state to go to |
|
373 void ChangeStateL(); // initiates the next state operation |
|
374 void SelectAndChangeToNextStateL(); |
|
375 void RequestComplete(TInt aError); |
|
376 void Complete(); |
|
377 void ConnectToMailboxL(); |
|
378 void CopyMoveNewMessagesL(TBool aCopy); |
|
379 void CopyMoveMessageSelectionL(TBool aCopy); |
|
380 void CopyMoveAllMessagesL(TBool aCopy); |
|
381 void PopulateNewMessagesL(); |
|
382 void PopulateAllMessagesL(); |
|
383 void PopulateMessageSelectionL(); |
|
384 void DisconnectFromMailboxL(); |
|
385 void ResetProgress(); |
|
386 void StoreProgressL(); |
|
387 private: |
|
388 enum TImImap4GetMailState |
|
389 { |
|
390 EConnectToMailbox, |
|
391 ECopyNewMessages, |
|
392 EMoveNewMessages, |
|
393 EPopulateNewMessages, |
|
394 ECopyMessageSelection, |
|
395 EMoveMessageSelection, |
|
396 EPopulateMessageSelection, |
|
397 ECopyAllMessages, |
|
398 EMoveAllMessages, |
|
399 EPopulateAllMessages, |
|
400 EDisconnectFromMailbox, |
|
401 EFinished |
|
402 }; |
|
403 |
|
404 CImap4ClientMtm& iImap4ClientMtm; |
|
405 CMsvEntrySelection* iMsvEntrySelection; |
|
406 CMsvOperation* iMsvOperation; |
|
407 |
|
408 TImap4GenericProgress iProgress; |
|
409 TImap4GenericProgress iErrorProgress; |
|
410 TImImap4GetMailState iState; |
|
411 TInt iCommand; |
|
412 TPckgBuf<TImap4GenericProgress> iProgressBuf; |
|
413 TPckgBuf<TImImap4GetPartialMailInfo> iImap4GetPartialMailInfo; |
|
414 }; |
|
415 |
|
416 #endif // __IMPCMTM_H__ |