1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/app/impcmtm.h Wed Mar 31 12:27:01 2010 +0100
1.3 @@ -0,0 +1,416 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Client MTM for the IMAP4 protocol
1.18 +//
1.19 +//
1.20 +
1.21 +
1.22 +#if !defined (__IMPCMTM_H__)
1.23 +#define __IMPCMTM_H__
1.24 +
1.25 +#if !defined (__MTCLBASE_H_)
1.26 +#include <mtclbase.h>
1.27 +#endif
1.28 +
1.29 +#if !defined (__MIUTHDR_H_)
1.30 +#include <miuthdr.h>
1.31 +#endif
1.32 +
1.33 +#if !defined (__MIUTPARS_H__)
1.34 +#include <miutpars.h> //TImMessageField
1.35 +#endif
1.36 +
1.37 +#if !defined (__IMAPSET_H__)
1.38 +#include <imapset.h>
1.39 +#endif
1.40 +
1.41 +#if !defined (__IMAPCMDS_H__)
1.42 +#include <imapcmds.h>
1.43 +#endif
1.44 +
1.45 +#if !defined(__OFFOP_H__)
1.46 +#include <offop.h>
1.47 +#endif
1.48 +
1.49 +#if !defined(__MIUTMSG_H__)
1.50 +#include <miutmsg.h>
1.51 +#endif
1.52 +
1.53 +
1.54 +
1.55 +// Forward declarations.
1.56 +class CImap4ClientSessionObserver;
1.57 +class CImImap4GetMail;
1.58 +class CImEmailAutoSend;
1.59 +
1.60 +/////////////////////////////////////////////////////////////////////////////
1.61 +// Imap4 Client MTM
1.62 +class CImap4ClientMtm : public CBaseMtm, public MImUndoOffLineOperation
1.63 +
1.64 +/** IMAP4 client MTM interface, providing access to the email services using the IMAP4
1.65 +protocol.
1.66 +
1.67 +The class provides support for:
1.68 +
1.69 +- connecting to remote IMAP4 mail servers
1.70 +- synchronising message headers with mailboxes on these servers
1.71 +- getting message bodies and attachments
1.72 +- copying and moving messages
1.73 +- creating messages that forward or reply to IMAP4 messages
1.74 +- server notification of new messages using IMAP IDLE
1.75 +- queueing operations requested when there is no connection to a mail server, to be
1.76 +performed when a connection is made (offline operations).
1.77 +
1.78 +Note that CImap4ClientMtm does not support many of the generic functions defined by
1.79 +the @c CBaseMtm base class. In particular:
1.80 +
1.81 +- Message address information, body, subjects, and attachments are not manipulated
1.82 +through CImap4ClientMtm. Consequently, SaveMessageL() has an empty
1.83 +implementation, and is not used. Message access and manipulation is instead done
1.84 +through CImEmailMessage, which understands the email specific message formats,
1.85 +including MHTML (RFC 2557). The RFC 822 email header, which includes subject and
1.86 +address information, is encapsulated in a CImHeader object, which can be obtained from
1.87 +a CImEmailMessage object. IMAP also has its own specific flags, such as draft,
1.88 +answered, and deleted: this can be accessed through TMsvEmailEntry, which extends the
1.89 +message server's generic TMsvEntry to add email-specific information.
1.90 +
1.91 +- The idea of a default service used by base class functions DefaultServiceL(),
1.92 +ChangeDefaultServiceL(), and RemoveDefaultServiceL() is not supported.
1.93 +
1.94 +IMAP specific commands are issued through the InvokeAsyncFunctionL() function, with
1.95 +the commands defined in the #TImap4Cmds enumeration. Details of particular commands
1.96 +are given in the documentation for that enumeration, but the following describes some of
1.97 +the key concepts required to use those commands. Note that usually these commands do
1.98 +not correspond directly to the IMAP protocol commands described in RFC 3501. Instead,
1.99 +they are at a higher level, to simplify the logic required for an email client program.
1.100 +
1.101 +--------------------------------------
1.102 +
1.103 +Connection and services
1.104 +
1.105 +Settings for connection to and use of an IMAP4 mail server and its mailboxes are
1.106 +encapsulated in an CImImap4Settings object, created and accessed through
1.107 +CEmailAccounts. Preferences for the network connection (e.g. the ISP to use) to be made
1.108 +to access an IMAP server are also accessed through CEmailAccounts.
1.109 +
1.110 +The settings are associated with a service-type entry in the Message Server's message
1.111 +store. Message and folder type entries under the service entry store a local copy of the
1.112 +mailboxes and messages that are present on an IMAP server. For this reason, the service
1.113 +is sometimes referred to as the local mirror of an IMAP server.
1.114 +
1.115 +By default, it is assumed that the user has a primary mailbox on the server called INBOX,
1.116 +though this can be changed if necessary using CImImap4Settings::SetFolderPathL(). (To
1.117 +avoid confusion, the term "Inbox" used in the IMAP MTM documentation refers to this
1.118 +mailbox, rather than the Message Server's standard local Inbox folder.)
1.119 +
1.120 +The settings store the user's log-in details required to access the IMAP server, and other
1.121 +settings not related to connection, but which affect the behaviour of commands, such as
1.122 +synchronisation, made to the service.
1.123 +
1.124 +--------------------------------------
1.125 +
1.126 +Synchronisation
1.127 +
1.128 +The IMAP4 MTM provides the means to synchronise message headers on a remote
1.129 +IMAP mailboxes with the messages headers on the phone. Note that synchronisation only
1.130 +refers to message headers. Once headers are synchronised, populate operations (i.e.
1.131 +getting the message bodies) can be done.
1.132 +
1.133 +The basic steps involved in a full synchronisation are:
1.134 +
1.135 +- The headers of messages in the Inbox are synchronised.
1.136 +- The local list of folders is synchronised with those existing on the remote IMAP service.
1.137 +Depending on the service settings, the local or remote settings of subscribed mailboxes
1.138 +may be updated (see below for more information).
1.139 +- The headers of messages in subscribed folders are synchronised.
1.140 +
1.141 +Queued offline operations (see below) pending on the Inbox or subscribed folders are
1.142 +performed prior to the relevant folder being synchronised.
1.143 +
1.144 +Synchronisations can be performed in the background or the foreground. A foreground
1.145 +synchronisation means no other requests, such as message fetching, can be made to the
1.146 +MTM, until the synchronisation is complete. A background synchronisation allows some
1.147 +types of command to be given while it is in progress. Commands that write to the remote
1.148 +server are not allowed however while a background synchronisation is in progress. A
1.149 +client is informed of the state of a background synchronisation through the
1.150 +MMsvImapConnectionObserver callback interface.
1.151 +
1.152 +Synchronisations commands are made through
1.153 +CImap4ClientMtm::InvokeAsyncFunctionL(). There a variety of commands available
1.154 +that give different options for compounding synchronisation
1.155 +with other commands, such as connection, and synchronising only particular folders. See
1.156 +TImap4Cmds for details. Progress information for synchronisation commands can be
1.157 +obtained from the CMsvOperation object returned by the InvokeAsyncFunctionL().
1.158 +Synchronisation progress information is encapsulated in a TImap4SyncProgress object.
1.159 +
1.160 +Settings that affect how a synchronisation is performed include:
1.161 +
1.162 +- Subscriptions: when an IMAP service had been synchronised, the Messaging server will
1.163 +contain entries for all folders on the remote server. These entries will be marked invisible
1.164 +within the TMsvEntry for the folder, implying that they should be invisible to the user.
1.165 +Messages in these folders are not synchronised unless the folder has been subscribed to.
1.166 +Note a folder subscription can be set either locally (i.e. just on the phone), using
1.167 +the #KIMAP4MTMLocalSubscribe command, or remotely (on the server), possibly through email
1.168 +clients on other devices. A service can be set to synchronise folders using either or both
1.169 +of these types of subscription (CImImap4Settings::SetSynchronise()). Local and remote
1.170 +subscriptions can themselves be synchronised in various ways (CImImap4Settings::SetSuscribe()).
1.171 +
1.172 +- Filters: a filter prevents certain e-mail messages from being synchronised onto the
1.173 +device when a client requests a synchronisation. Filters can include anything permitted by
1.174 +the IMAP Search command, including date, size, content, and message flags.
1.175 +
1.176 +- Limits: service settings can limit the number of emails synchronised to the inbox
1.177 +(CImImap4Settings::SetInboxSynchronisationLimit()), and to other folders
1.178 +(CImImap4Settings::SetMailboxSynchronisationLimit()).
1.179 +
1.180 +- Sync rate: one of the synchronisation commands
1.181 +(KIMAP4MTMConnectAndSyncCompleteAfterDisconnect) periodically resynchronises
1.182 +the Inbox until the service is disconnected. CImImap4Settings::SyncRate() sets the
1.183 +refresh period.
1.184 +
1.185 +--------------------------------------
1.186 +
1.187 +Getting and copying messages
1.188 +
1.189 +After messages headers have been synchronised, message bodies and attachments can be
1.190 +fetched from the remote email server. Getting message parts and saving them in the
1.191 +mirror service is calling populating them.
1.192 +
1.193 +Commands for these actions can be made through
1.194 +CImap4ClientMtm::InvokeAsyncFunctionL(). There are a large number of commands,
1.195 +for different combinations of these options:
1.196 +
1.197 +- action type: whether to just populate messages, or to also copy or move them to a local
1.198 +folder
1.199 +- message selection: whether to get all, new, or selected messages
1.200 +- connection: whether to make a new connection or assume an existing connection
1.201 +- disconnect: whether to disconnect or stay online after operation is complete
1.202 +
1.203 +For the populate type commands, further options can be set that control the message
1.204 +getting behaviour. Basic options control, encapsulated in TImImap4GetMailInfo, specify
1.205 +whether body text and/or attachments are fetched, and a maximum message size. There
1.206 +are also options, encapsulated in TImImap4GetPartialMailInfo, that allow size limits to
1.207 +be separately specified for body text and/or attachments. If the the body is larger than the
1.208 +limit, then the body is partially downloaded up to the limit. Only attachments smaller
1.209 +than the specified size are downloaded. A partially downloaded message can later be
1.210 +fully downloaded.
1.211 +
1.212 +For the copy or move type commands, a TImImap4GetMailInfo parameter is supplied, in
1.213 +order to specify the destination folder for the messages, and a maximum message size.
1.214 +
1.215 +Progress information for getting commands can be obtained from the CMsvOperation
1.216 +object returned by the InvokeAsyncFunctionL(). Progress information is encapsulated in
1.217 +a TImap4GenericProgress object.
1.218 +
1.219 +Fetching and then copying or moving specified messages can also be performed by using
1.220 +the standard Messaging Framework @c CMsvEntry::CopyL() and @c
1.221 +CMsvEntry::MoveL() functions on entries under the remote service. If these functions are
1.222 +used, then the entire message is fetched without size limits.
1.223 +
1.224 +CMsvEntry functions can also be used to:
1.225 +
1.226 +- create a folder on a remote server
1.227 +- delete messages
1.228 +- copy or move messages from a local folder into a remote folder
1.229 +- copy or move messages between remote folders
1.230 +
1.231 +Note that changing an existing entry through CMsvEntry is not supported. An MTM-
1.232 +specific command #KIMAP4MTMRenameFolder is instead provided to rename a remote
1.233 +folder.
1.234 +
1.235 +The page "CMsvEntry functions for IMAP4 message entries", linked to in the "See also"
1.236 +section below, provides more details on using CMsvEntry.
1.237 +
1.238 +--------------------------------------
1.239 +
1.240 +Offline operations
1.241 +
1.242 +Some operations can only be performed while online, while other commands may
1.243 +be stored while offline for processing when next connected. An attempt to perform a
1.244 +command while offline that requires the MTM to be connected results in immediate
1.245 +completion with the error code KErrDisconnected.
1.246 +
1.247 +Permitted offline operations include:
1.248 +
1.249 +- copy
1.250 +- move
1.251 +- delete
1.252 +
1.253 +Queued offline operations are usually performed when a connection is made, prior to the
1.254 +relevant folder being synchronised. Delete operations can alternatively be set to be done
1.255 +on disconnection using the service setting
1.256 +CImImap4Settings::SetDeleteEmailsWhenDisconnecting().
1.257 +
1.258 +Note that:
1.259 +- Offline operations are only permitted if the service setting SetDisconnectedUserMode()
1.260 +is true.
1.261 +- It is possible to undo pending offline operations using the commands
1.262 +#KIMAP4MTMCancelOffLineOperations and #KIMAP4MTMUndeleteAll.
1.263 +
1.264 +--------------------------------------
1.265 +
1.266 +IMAP IDLE support
1.267 +
1.268 +IMAP IDLE (RFC 2177) is an optional expansion of the IMAP email accessing protocol
1.269 +that allows the server to send updates to the client that messages have been created or
1.270 +deleted in real time. The IDLE command is sent from the client to the server when the
1.271 +client is ready to accept unsolicited mailbox update messages. Whether the client requests
1.272 +the server to provide IDLE support is set in the CImImap4Settings::SetImapIdle() service
1.273 +setting. When the IMAP MTM receives such a notification, it synchronises the changed
1.274 +folder. Email clients can be notified of such changes by setting a MMsvEntryObserver
1.275 +observer on a folder.
1.276 +
1.277 +@publishedAll
1.278 +@released
1.279 +*/
1.280 + {
1.281 +public:
1.282 + IMPORT_C static CImap4ClientMtm* NewL(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession);
1.283 +
1.284 + ~CImap4ClientMtm();
1.285 + void HandleEntryEvent(TMsvEntryEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
1.286 + void StoreL(); // uses a CMsvStore from the Session
1.287 + void RestoreL();
1.288 + CMsvOperation* ReplyL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus);
1.289 + CMsvOperation* ForwardL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus);
1.290 + TUint ValidateMessage(TUint aPartList);
1.291 + TMsvPartList Find(const TDesC& aTextToFind, TMsvPartList aPartList);
1.292 + void SaveMessageL();
1.293 + void LoadMessageL();
1.294 + IMPORT_C void StoreSettingsL(); // uses a CMsvStore from the session
1.295 + IMPORT_C void RestoreSettingsL();
1.296 +
1.297 + // --- RTTI functions ---
1.298 + TInt QueryCapability(TUid aCapability, TInt& aResponse);
1.299 + void InvokeSyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter);
1.300 + CMsvOperation* InvokeAsyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter, TRequestStatus& aCompletionStatus);
1.301 + // Addressees have no meaning in the text mtm.
1.302 + void AddAddresseeL(const TDesC& aRealAddress);
1.303 + void AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias);
1.304 + void RemoveAddressee(TInt aIndex);
1.305 +
1.306 + // Attachment functions to support the SendAs API
1.307 +
1.308 + IMPORT_C virtual void AddAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus);
1.309 + IMPORT_C virtual void AddAttachmentL(RFile& aFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus);
1.310 + IMPORT_C virtual void AddLinkedAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus);
1.311 + IMPORT_C virtual void AddEntryAsAttachmentL(TMsvId aAttachmentId, TRequestStatus& aStatus);
1.312 + IMPORT_C virtual void CreateAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus);
1.313 + IMPORT_C void CreateMessageL(TMsvId aServiceId);
1.314 +
1.315 + IMPORT_C virtual TMsvId DefaultServiceL() const;
1.316 + IMPORT_C virtual void RemoveDefaultServiceL();
1.317 + IMPORT_C virtual void ChangeDefaultServiceL(const TMsvId& aService);
1.318 +
1.319 +public: // Returning a list of all the offline operations for a service entry.
1.320 + IMPORT_C CImOperationQueueList* QueueListL(CMsvEntry& aServiceEntry);
1.321 +public: // Wrapper to settings
1.322 + IMPORT_C const CImImap4Settings& Imap4Settings() const;
1.323 + IMPORT_C void SetImap4SettingsL(const CImImap4Settings& aSettings);
1.324 +public: // inherited from MUndoOffLine
1.325 + virtual void UndoOffLineChangesL(const CImOffLineOperation& aDeleted, TMsvId aFolderId);
1.326 +protected:
1.327 + CImap4ClientMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession);
1.328 + void ConstructL();
1.329 + void ContextEntrySwitched(); // called after the context of this instance has been changed to another entry
1.330 +
1.331 +private:
1.332 + TBool ValidateAddress(const TPtrC& anAddress);
1.333 + void SendOnNextConnectionL();
1.334 + TMsvPartList DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList);
1.335 + void FilterAllOrNewMailsL(TInt aFunctionId,const CMsvEntrySelection& aSelection,TDes8& aParameter);
1.336 + void FilterMailSelectionL(const CMsvEntrySelection& aSelection,TDes8& aParameter);
1.337 + CMsvOperation* CopyMoveOrPopulateL(TInt aFunctionId,TDes8& aParameter,TRequestStatus& aCompletionStatus);
1.338 + void ConvertToPartialPopulate(TDes8& aParameter);
1.339 + // To check whether a partial fetch or full fetch of message has to be done.
1.340 + TBool IsPartialPopulate(TDes8& aParameter);
1.341 +
1.342 +private:
1.343 + CImImap4Settings iImImap4Settings;
1.344 + TImMessageField iTImMessageField;
1.345 + CImap4ClientSessionObserver* iImap4ClientSessionObserver;
1.346 + HBufC* iEmailAddressFormatString; // defines format of email address used by "Send as" API eg _L("/"%S/" <%S>")
1.347 + CImHeader* iHeader;
1.348 + CMsvEntrySelection* iMsvEntrySelection;
1.349 + CImImap4GetMail* iImIMAP4GetMail;
1.350 + CImEmailOperation* iImEmailOperation;
1.351 + TPckgBuf<TImImap4GetPartialMailInfo> iImap4GetPartialMailInfo;
1.352 + };
1.353 +
1.354 +class CImImap4GetMail : public CMsvOperation
1.355 +/** Encapsulates an operation to copy, move, and populate (i.e. download the full
1.356 +message body) IMAP4 emails from the remote inbox to any local folder.
1.357 +
1.358 +Note that the same operations are available by calling CImap4ClientMtm::InvokeAsyncFunctionL()
1.359 +with a suitable command.
1.360 +
1.361 +@publishedAll
1.362 +@released
1.363 +*/
1.364 + {
1.365 +public:
1.366 + IMPORT_C CMsvOperation* GetMailL(TInt aFunctionId, CImap4ClientMtm& aImap4ClientMtm, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo, TRequestStatus& aObserverRequestStatus);
1.367 + ~CImImap4GetMail();
1.368 + void DoCancel();
1.369 + void RunL();
1.370 + const TDesC8& ProgressL();
1.371 + const TDesC8& FinalProgress();
1.372 +private:
1.373 + CImImap4GetMail(CMsvSession& aMsvSession, CImap4ClientMtm& aImap4ClientMtm, TRequestStatus& aObserverRequestStatus);
1.374 + void ConstructL(TInt aFunctionId, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo);
1.375 + void SelectNextStateL(); // selects next state to go to
1.376 + void ChangeStateL(); // initiates the next state operation
1.377 + void SelectAndChangeToNextStateL();
1.378 + void RequestComplete(TInt aError);
1.379 + void Complete();
1.380 + void ConnectToMailboxL();
1.381 + void CopyMoveNewMessagesL(TBool aCopy);
1.382 + void CopyMoveMessageSelectionL(TBool aCopy);
1.383 + void CopyMoveAllMessagesL(TBool aCopy);
1.384 + void PopulateNewMessagesL();
1.385 + void PopulateAllMessagesL();
1.386 + void PopulateMessageSelectionL();
1.387 + void DisconnectFromMailboxL();
1.388 + void ResetProgress();
1.389 + void StoreProgressL();
1.390 +private:
1.391 + enum TImImap4GetMailState
1.392 + {
1.393 + EConnectToMailbox,
1.394 + ECopyNewMessages,
1.395 + EMoveNewMessages,
1.396 + EPopulateNewMessages,
1.397 + ECopyMessageSelection,
1.398 + EMoveMessageSelection,
1.399 + EPopulateMessageSelection,
1.400 + ECopyAllMessages,
1.401 + EMoveAllMessages,
1.402 + EPopulateAllMessages,
1.403 + EDisconnectFromMailbox,
1.404 + EFinished
1.405 + };
1.406 +
1.407 + CImap4ClientMtm& iImap4ClientMtm;
1.408 + CMsvEntrySelection* iMsvEntrySelection;
1.409 + CMsvOperation* iMsvOperation;
1.410 +
1.411 + TImap4GenericProgress iProgress;
1.412 + TImap4GenericProgress iErrorProgress;
1.413 + TImImap4GetMailState iState;
1.414 + TInt iCommand;
1.415 + TPckgBuf<TImap4GenericProgress> iProgressBuf;
1.416 + TPckgBuf<TImImap4GetPartialMailInfo> iImap4GetPartialMailInfo;
1.417 + };
1.418 +
1.419 +#endif // __IMPCMTM_H__