email/pop3andsmtpmtm/clientmtms/src/IMPCMTM.CPP
changeset 0 72b543305e3a
child 76 60a8a215b0ec
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     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 // IMAP4MTM.CPP
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "IMPCMTM.H"
       
    19 #include "MIUT_ERR.H"
       
    20 
       
    21 #include <barsc.h>		//RResourceFile
       
    22 #include <barsread.h>
       
    23 #include <bautils.h>
       
    24 #include <txtrich.h>
       
    25 #include <msvutils.h>
       
    26 #include <cemailaccounts.h>
       
    27 
       
    28 #include "MIUTMSG.H"	//CImEmailOperation
       
    29 #include "CONSYNC.H"
       
    30 #include <imcm.rsg>
       
    31 #include "IMCMUTIL.H"
       
    32 #include <e32base.h>
       
    33 #include <autosend.h>
       
    34 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    35 #include "miut_errconsts.h"
       
    36 #include "cimmessagepart.h"
       
    37 #include "timrfc822datefield.h"
       
    38 #include <mtmuidsdef.hrh>
       
    39 #endif
       
    40 
       
    41 #include <msvenhancesearchsortutil.h>
       
    42 
       
    43 _LIT(KMsvAutoSendExe, "Autosend.exe");
       
    44 const TUid KMsvAutoSendExeUid = {0x1000A402}; //268477442
       
    45 
       
    46 #define TODO//@
       
    47 
       
    48 
       
    49 //
       
    50 //  Session Observer for the Imap4 Client MTM  
       
    51 class CImap4ClientSessionObserver : public CBase , public MMsvSessionObserver
       
    52 	{
       
    53 public:
       
    54 	void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
       
    55 	};
       
    56 
       
    57 void CImap4ClientSessionObserver::HandleSessionEventL(TMsvSessionEvent /*aEvent*/, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
       
    58 	{
       
    59 	}
       
    60 
       
    61 
       
    62 //
       
    63 //  CImap4ClientMtm methods.
       
    64 
       
    65 
       
    66 /**
       
    67 @internalTechnology
       
    68 */
       
    69 /** IMAP4 client MTM factory function.
       
    70 
       
    71 This function is not called directly by messaging clients. To create a client MTM
       
    72 object, use CClientMtmRegistry::NewMtmL().
       
    73 
       
    74 @param aRegisteredMtmDll MTM registry information 
       
    75 @param aSession Message server session
       
    76 @return New IMAP4 client MTM object
       
    77 @see CClientMtmRegistry::NewMtmL()
       
    78 */
       
    79 EXPORT_C CImap4ClientMtm* CImap4ClientMtm::NewL(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession)
       
    80 	{
       
    81 	CImap4ClientMtm* self = new (ELeave) CImap4ClientMtm(aRegisteredMtmDll, aSession);
       
    82 	CleanupStack::PushL(self);
       
    83 	self->ConstructL();
       
    84 	CleanupStack::Pop();
       
    85 	return self;
       
    86 	}
       
    87 
       
    88 CImap4ClientMtm::CImap4ClientMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession)
       
    89 : CBaseMtm(aRegisteredMtmDll, aSession)
       
    90 	{
       
    91 	}
       
    92 
       
    93 void CImap4ClientMtm::ConstructL()
       
    94 	{
       
    95 	iImap4ClientSessionObserver = new (ELeave) CImap4ClientSessionObserver;
       
    96 	iHeader = CImHeader::NewLC();
       
    97 	CleanupStack::Pop();	// iHeader
       
    98 
       
    99 	//open the resource file
       
   100 	RFs fs;
       
   101 	User::LeaveIfError(fs.Connect());
       
   102 	CleanupClosePushL(fs);
       
   103 	//	Need to search for IMCM resource file on all drives -
       
   104 	//	it won't necessarily be on the same one as IMPC.DLL
       
   105 	//
       
   106 	TFileName fileName(KImEngineResourceFile);
       
   107 	MsvUtils::AddPathAndExtensionToResFileL(fileName);
       
   108 	BaflUtils::NearestLanguageFile( fs, fileName );		//	change to appropriate language
       
   109 
       
   110 	RResourceFile resourceFile;
       
   111 	resourceFile.OpenL(fs,fileName);
       
   112 	CleanupClosePushL(resourceFile);
       
   113 	HBufC8* buf = resourceFile.AllocReadLC(EMAIL_ADDRESS_FORMATTING_STRING);
       
   114 	TResourceReader reader;
       
   115 	reader.SetBuffer(buf);
       
   116 	iEmailAddressFormatString = (reader.ReadTPtrC()).AllocL();
       
   117 	CleanupStack::PopAndDestroy(3);// resourceFile (Close resourceFile), fs
       
   118 	}
       
   119 
       
   120 CImap4ClientMtm::~CImap4ClientMtm()
       
   121 /** Destructor. */
       
   122 	{
       
   123 	delete iImap4ClientSessionObserver;
       
   124 	delete iEmailAddressFormatString;
       
   125 	delete iHeader;
       
   126 	delete iMsvEntrySelection;
       
   127 	delete iImIMAP4GetMail;
       
   128 	delete iImEmailOperation;
       
   129 	}
       
   130 
       
   131 void CImap4ClientMtm::SaveMessageL()
       
   132 /** Empty implementation of base class function. 
       
   133 
       
   134 To edit an IMAP message, use CImEmailMessage.
       
   135 */
       
   136 	{
       
   137 	}
       
   138 
       
   139 EXPORT_C void CImap4ClientMtm::StoreSettingsL()
       
   140 /** If the current context of the client MTM is an IMAP4 service, stores settings 
       
   141 in the Central Repository. 
       
   142 
       
   143 @panic IMCM 33 MTM has no current context (debug builds only)
       
   144 @panic IMCM 44 Current context is not a service (debug builds only)
       
   145 */
       
   146 	{
       
   147 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EImpcNoCMsvEntrySet));
       
   148 
       
   149 	// check that current context is a service entry
       
   150 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvServiceEntry,gPanic(EImpcMTMNotAServiceEntry));
       
   151 
       
   152 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   153   	TImapAccount id;
       
   154 	account->GetImapAccountL(iMsvEntry->Entry().Id(), id);
       
   155 	account->SaveImapSettingsL(id, iImImap4Settings);
       
   156 	CleanupStack::PopAndDestroy(account);    
       
   157 	}
       
   158 
       
   159 void CImap4ClientMtm::LoadMessageL()
       
   160 /** Loads the cache with the message data for the current message context. 
       
   161 
       
   162 The current context should be an IMAP service or a message. 
       
   163 If the current context is an IMAP service, then the function loads the service settings
       
   164 from the Central Repository. This is the same behaviour as RestoreSettingsL().
       
   165 */
       
   166 	{
       
   167 	Body().Reset();
       
   168 	iHeader->Reset();
       
   169 	switch (iMsvEntry->Entry().iType.iUid)
       
   170 		{
       
   171 		case KUidMsvServiceEntryValue:
       
   172 			RestoreSettingsL();
       
   173 			break;
       
   174 		case KUidMsvMessageEntryValue:
       
   175 			{//restore header
       
   176 			if (!iMsvEntry->HasStoreL())
       
   177 				return;
       
   178 		
       
   179 				
       
   180 			// Get a reference to TMsvEnhanceSearchSortUtil  instance set by CMsvSearchsortOpOnHeaderBody class
       
   181 			// If advanced search and sort is being performed than do not load the message header and body.
       
   182 			// These are loaded when the search criteria is known in DoFindL()
       
   183 			// For API's other than CMsvSearchsortOpOnHeaderBody-> FindInHeaderBodyL(), a call to LoadMessageL()
       
   184 			// loads the body and the header.
       
   185 			TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   186 			
       
   187 			if ( searchsortutil == NULL )
       
   188 				{
       
   189 				CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   190 				CleanupStack::PushL(msvStore);
       
   191 				iHeader->RestoreL(*msvStore);
       
   192 				CleanupStack::PopAndDestroy();//store
       
   193 				CImEmailMessage* message=CImEmailMessage::NewLC(*iMsvEntry);
       
   194 				message->GetBodyTextL(iMsvEntry->Entry().Id(),CImEmailMessage::EThisMessageOnly,Body(),*iParaFormatLayer,*iCharFormatLayer);
       
   195 				CleanupStack::PopAndDestroy();//message	
       
   196 				break;
       
   197 				}
       
   198 			}
       
   199 		};
       
   200 	}
       
   201 
       
   202 EXPORT_C void CImap4ClientMtm::RestoreSettingsL()
       
   203 /** If the current context of the client MTM is on an IMAP4 service, restores settings 
       
   204 from the Central Repository. 
       
   205 
       
   206 The restored settings can be accessed through the Imap4Settings() function.
       
   207 
       
   208 @panic IMCM 33 MTM has no current context (debug builds only)
       
   209 */
       
   210     {
       
   211 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EImpcNoCMsvEntrySet));
       
   212 
       
   213 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   214   	TImapAccount id;
       
   215 	account->GetImapAccountL(iMsvEntry->Entry().Id(), id);
       
   216 	account->LoadImapSettingsL(id, iImImap4Settings);
       
   217 	CleanupStack::PopAndDestroy(account);    
       
   218 	}
       
   219 
       
   220 CMsvOperation* CImap4ClientMtm::ReplyL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   221 /** Creates an SMTP reply message to the current message context.
       
   222 
       
   223 @param aDestination Entry to which to assign the reply. 
       
   224 @param aPartList Defines the parts that are to be copied from the original 
       
   225 message into the reply.
       
   226 @param aCompletionStatus The request status to be completed when the operation 
       
   227 has finished.
       
   228 @return If successful, this is an asynchronously completing reply operation. 
       
   229 If failed, this is a completed operation, with status set to the relevant 
       
   230 error code. */
       
   231 	{
       
   232 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   233 	TUid messageType = KUidMsgTypeSMTP;
       
   234 	return CImEmailOperation::CreateReplyL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   235 	}
       
   236 
       
   237 CMsvOperation* CImap4ClientMtm::ForwardL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   238 /** Creates an forwarded SMTP message from the current message context. 
       
   239 
       
   240 @param aDestination Entry to which to assign the forwarded message.
       
   241 @param aPartList Defines the parts that are to be copied from the original 
       
   242 message into the forwarded message 
       
   243 @param aCompletionStatus The request status to be completed when the operation 
       
   244 has finished.
       
   245 @return If successful, this is an asynchronously completing forward message 
       
   246 operation. If failed, this is a completed operation, with status set to the 
       
   247 relevant error code. */
       
   248 	{
       
   249 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   250 	TUid messageType = KUidMsgTypeSMTP;
       
   251 	return CImEmailOperation::CreateForwardL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   252    }
       
   253 
       
   254 TUint CImap4ClientMtm::ValidateMessage(TUint aPartList)
       
   255 /** Validates the current message context.
       
   256 
       
   257 Only the message recipients and sender fields are checked for well-formed 
       
   258 addresses.
       
   259 
       
   260 @param aPartList Indicates the value of the message parts for which validation 
       
   261 is requested.
       
   262 @return Values of message parts. 
       
   263 
       
   264 @panic IMCM 33 MTM has no current context (debug builds only)
       
   265 */
       
   266 	{
       
   267 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EImpcNoCMsvEntrySet));
       
   268 	TBool retVal=0;
       
   269 	if (aPartList & KMsvMessagePartRecipient)
       
   270 		{
       
   271 		TBool valid = ETrue;
       
   272 		// check the recipient list for valid 'addresses' - ie no digits
       
   273 		for (TInt ii=0; ii < AddresseeList().Count(); ++ii)
       
   274 			if ( (valid = ValidateAddress((*iAddresseeList)[ii])) == EFalse)
       
   275 				continue;
       
   276 		retVal += (valid ? 0 : KMsvMessagePartRecipient);
       
   277 		}
       
   278 	if (aPartList & KMsvMessagePartOriginator)
       
   279 		{
       
   280 		// check the originator field for valid 'addresses' - ie no digits
       
   281 		if (!ValidateAddress(iMsvEntry->Entry().iDetails))
       
   282 			retVal += KMsvMessagePartOriginator;
       
   283 		}
       
   284 	return retVal;
       
   285 	}
       
   286 
       
   287 TBool CImap4ClientMtm::ValidateAddress(const TPtrC& anAddress)
       
   288 	{
       
   289 	return iTImMessageField.ValidInternetEmailAddress(anAddress);
       
   290 	}
       
   291 
       
   292 void CImap4ClientMtm::SendOnNextConnectionL()
       
   293 	{
       
   294 	TMsvId smtpServiceId = KMsvNullIndexEntryId;
       
   295 	TMsvId entry = iMsvEntry->Entry().Id();
       
   296 	if (iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue)
       
   297 		smtpServiceId = iMsvEntry->Entry().iRelatedId;
       
   298 	else if (iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue)
       
   299 		{
       
   300 		TMsvId id=iMsvEntry->Entry().iServiceId;
       
   301 		iMsvEntry->SetEntryL(iMsvEntry->Entry().iServiceId);		
       
   302 		smtpServiceId = iMsvEntry->Entry().iRelatedId;
       
   303 		iMsvEntry->SetEntryL(id);		
       
   304 		}
       
   305 
       
   306 	iMsvEntry->SetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   307 	CMsvEntrySelection* sel = iMsvEntry->ChildrenWithMtmL(KUidMsgTypeSMTP);
       
   308 	CleanupStack::PushL(sel);
       
   309 
       
   310 	// there is no need to start the autosend operation if there are no SMTP messages
       
   311 	// in the outbox
       
   312 
       
   313 	if(sel->Count())
       
   314 		{
       
   315 		TBuf<20> cmdString;
       
   316 		cmdString.Num(smtpServiceId, EDecimal);
       
   317 			RProcess p;
       
   318 			TInt error=p.Create(KMsvAutoSendExe, cmdString, TUidType(KNullUid, KNullUid, KMsvAutoSendExeUid));
       
   319 			if (error==KErrNone)
       
   320 				{
       
   321 				p.Resume();
       
   322 				p.Close();
       
   323 				}
       
   324 		}
       
   325 	CleanupStack::PopAndDestroy(sel);
       
   326 	iMsvEntry->SetEntryL(entry);
       
   327 	}
       
   328 
       
   329 TMsvPartList CImap4ClientMtm::DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   330 	{ 
       
   331 	CImClientMTMUtils* clientMTMUtils = CImClientMTMUtils::NewL();
       
   332 	CleanupStack::PushL(clientMTMUtils);
       
   333 
       
   334 	TMsvPartList retList = KMsvMessagePartNone;
       
   335 	CMsvFindText* findText = CMsvFindText::NewLC();
       
   336  
       
   337   	
       
   338 	// Get a reference to TMsvEnhanceSearchSortUtil  instance set by CMsvSearchsortOpOnHeaderBody class
       
   339 		
       
   340 	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   341 	
       
   342 	if( searchsortutil != NULL )
       
   343  		{
       
   344  		// Get Advanced search sort setting flag
       
   345  		TInt32 searchsortsetting=searchsortutil->GetSearchSortSetting();
       
   346  		
       
   347  		/* If the search is on message body than Load message Body 
       
   348  		 If the search is on message header than Load the message header
       
   349  		 Also set searchsortsetting flag EMessagePartBodyLoaded or EMessagePartHeaderLoaded 
       
   350  		 in TMsvEnhanceSearchSortUtil class
       
   351  		 This ensures that the body or header is not loaded twice if 2 query options
       
   352  		 are on the body */
       
   353  		
       
   354  		if(aPartList & KMsvMessagePartBody && !(searchsortsetting & EMessagePartBodyLoaded))  	
       
   355    			{
       
   356    			CImEmailMessage* message=CImEmailMessage::NewLC(*iMsvEntry);
       
   357 			message->GetBodyTextL(iMsvEntry->Entry().Id(),CImEmailMessage::EThisMessageOnly,Body(),*iParaFormatLayer,*iCharFormatLayer);
       
   358 			CleanupStack::PopAndDestroy();//message
       
   359 			searchsortutil->SetSearchSortSetting(EMessagePartBodyLoaded);
       
   360    			}
       
   361    		else if(!(searchsortsetting & EMessagePartHeaderLoaded))
       
   362    			{
       
   363    			// Load the header
       
   364 			CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   365 			CleanupStack::PushL(msvStore);
       
   366 			iHeader->RestoreL(*msvStore);
       
   367 			CleanupStack::PopAndDestroy();//store
       
   368 			searchsortutil->SetSearchSortSetting(EMessagePartHeaderLoaded);	
       
   369    			}
       
   370    			
       
   371    		// Issue the Find request
       
   372 		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);
       
   373 		
       
   374 		/* If the search didn't succeed, than search in the details field of TMsvEntry class. It holds the From field
       
   375 		   If the search is on subject, than look in description field of TMsvEntry class.	*/
       
   376 		   
       
   377 		if(!retList)
       
   378 			{
       
   379 			if (aPartList & KMsvMessagePartFrom)
       
   380 				{
       
   381 				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDetails, aPartList) ? retList|=KMsvMessagePartOriginator : retList;	
       
   382 				}
       
   383  			if (aPartList & KMsvMessagePartSubject)
       
   384  				{
       
   385  				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDescription, aPartList) ? retList|=KMsvMessagePartDescription : retList;	
       
   386  				}
       
   387 			}
       
   388 		
       
   389 		/* Copy the sort data if sorting is specified.
       
   390 		 The operations being performed could be only be sort or it could be search and sort
       
   391 		 If the operation is search and sort than copy the sort data only if the
       
   392 		 search operation succeeded	*/
       
   393 		if ((searchsortsetting & EMessagePartSort ) || ((searchsortsetting & EMessagePartSearchSort) && (searchsortsetting & EMessagePartLastQueryOption) && (retList)))
       
   394    			{
       
   395    			/* Copy the data to be sorted from the header stream.
       
   396    			   This done by setting iExtensionData to point to the field being copied */
       
   397    			if (iHeader)
       
   398    				{
       
   399    				if (searchsortsetting & EMessagePartToSort )
       
   400    					{
       
   401 	   				SetExtensionData((TAny*)&iHeader->ToRecipients());
       
   402    					}
       
   403    				else if(searchsortsetting & EMessagePartCcSort)
       
   404    					{
       
   405    					SetExtensionData((TAny*)&iHeader->CcRecipients());
       
   406 	   				}
       
   407    				else if(searchsortsetting & EMessagePartBccSort)
       
   408     				{
       
   409     				SetExtensionData((TAny*)&iHeader->BccRecipients());
       
   410 	    			}
       
   411     			else if(searchsortsetting & EMessagePartFromSort)
       
   412     				{
       
   413     				SetExtensionData((TAny*)(iHeader->From().Ptr()));
       
   414     				}
       
   415 				else if(searchsortsetting & EMessagePartSubjectSort)
       
   416 					{
       
   417 					SetExtensionData((TAny*)(iHeader->Subject().Ptr()));
       
   418 					}
       
   419     			}
       
   420    			else // Header not present. Copy sort data from TMsvEntry details and description field
       
   421    	   			{
       
   422 	   		    if(searchsortsetting & EMessagePartFromSort)
       
   423 	   		    	{
       
   424 	   		    	SetExtensionData((TAny*)&iMsvEntry->Entry().iDetails);	
       
   425 	   		    	}
       
   426 	  			else if(searchsortsetting & EMessagePartSubjectSort)
       
   427    					{
       
   428    					SetExtensionData((TAny*)&iMsvEntry->Entry().iDescription);		
       
   429    					}
       
   430    	   			}
       
   431    			}
       
   432  		}
       
   433 	else
       
   434 		{
       
   435 
       
   436 		// Old implementation for searching
       
   437 		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);
       
   438 		
       
   439 		if(!retList)
       
   440 			{
       
   441 			if (aPartList & KMsvMessagePartOriginator)
       
   442 				{
       
   443 				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDetails, aPartList) ? retList|=KMsvMessagePartOriginator : retList;	
       
   444 				}
       
   445  			if (aPartList & KMsvMessagePartDescription)
       
   446  				{
       
   447  				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDescription, aPartList) ? retList|=KMsvMessagePartDescription : retList;	
       
   448  				}
       
   449 			}
       
   450 		}
       
   451 	CleanupStack::PopAndDestroy(findText);
       
   452 	CleanupStack::PopAndDestroy(clientMTMUtils); 
       
   453 	return retList;
       
   454 	}
       
   455 
       
   456 TMsvPartList CImap4ClientMtm::Find(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   457 /** Searches the specified message part(s) for the plain-text version of the text 
       
   458 to be found. 
       
   459 
       
   460 @param aTextToFind The plain-text version of the text to be found. 
       
   461 @param aPartList Indicates the message parts which should be searched.
       
   462 @return If the text was not found, or searching is unsupported, 0. If the text 
       
   463 was found, a bitmask of the TMsvPartList IDs for each part in which the text 
       
   464 was present. */
       
   465 	{
       
   466  	TMsvPartList retList = KMsvMessagePartNone;
       
   467  	TRAPD(ret, retList = DoFindL(aTextToFind, aPartList));
       
   468    	return retList;
       
   469 	}
       
   470 
       
   471 TInt CImap4ClientMtm::QueryCapability(TUid aCapability, TInt& aResponse)
       
   472 /** Queries if the MTM supports a particular capability, specified by a UID.
       
   473 
       
   474 @param aCapability UID of capability to be queried. See MTMDEF.HRH for 
       
   475 definition of UIDs. 
       
   476 @param aResponse Response value. The format of the response varies according 
       
   477 to the capability. 
       
   478 @return KErrNone: aCapability is a recognised value and a response is returned 
       
   479 KErrNotSupported: aCapability is not a recognised value 
       
   480 */
       
   481 	{
       
   482 	TInt error = KErrNone;
       
   483    const TInt KImap4MaxTextMessageSize = 0xFFFF;
       
   484 	switch (aCapability.iUid)
       
   485 		{
       
   486 	case KUidMtmQueryMaxBodySizeValue:
       
   487 	case KUidMtmQueryMaxTotalMsgSizeValue:
       
   488 		aResponse = KImap4MaxTextMessageSize;
       
   489 		break;
       
   490 	case KUidMtmQuerySupportedBodyValue:
       
   491 		aResponse = KMtm7BitBody + KMtm8BitBody + KMtm16BitBody + KMtmBinaryBody;
       
   492 		break;
       
   493    // Supported
       
   494 	case KUidMtmQueryCanReceiveMsgValue:		
       
   495    case KUidMtmQuerySupportAttachmentsValue:
       
   496    case KUidMtmQuerySupportsFolderValue:
       
   497 		break;
       
   498 	// Not supported
       
   499 	case KUidMtmQueryOffLineAllowedValue:	
       
   500 	case KUidMtmQueryCanSendMsgValue:		
       
   501 	default:
       
   502 		aResponse = ETrue;
       
   503 		return KErrNotSupported;
       
   504 		}
       
   505 	return error;
       
   506 	}
       
   507 
       
   508 void CImap4ClientMtm::InvokeSyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter)
       
   509 /** Invokes synchronous IMAP-specific operations.
       
   510 
       
   511 @param aFunctionId ID of the requested function. Supported IDs are #KIMAP4MTMIsConnected and #KIMAP4MTMBusy.
       
   512 @param aSelection Collection of function entries to invoke.
       
   513 @param aParameter Buffer containing input and output parameters. 
       
   514 
       
   515 @panic IMCM 33 MTM has no current context (debug builds only)
       
   516 @leave KErrNotSupported Function does not provide function specified by aFunctionId
       
   517 @see #KIMAP4MTMIsConnected 
       
   518 @see #KIMAP4MTMBusy
       
   519 */
       
   520 	{
       
   521 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EImpcNoCMsvEntrySet));
       
   522 	TInt error = KErrNone;
       
   523 	switch (aFunctionId)
       
   524 		{
       
   525 	case KIMAP4MTMIsConnected:
       
   526    case KIMAP4MTMBusy:
       
   527 		{
       
   528 		CMsvOperationActiveSchedulerWait *wait = CMsvOperationActiveSchedulerWait::NewLC();
       
   529 		CMsvOperation* operation = Session().TransferCommandL(aSelection, aFunctionId, aParameter, wait->iStatus);
       
   530 		CleanupStack::PushL(operation);
       
   531 		wait->iStatus = KRequestPending;
       
   532 		wait->Start();
       
   533       error = operation->iStatus.Int();
       
   534 		CleanupStack::PopAndDestroy(2); //operation, wait
       
   535 		// return the result via aParameter as a TInt packaged into a TDes8
       
   536 		TPckgBuf<TInt> resultPackage(error);
       
   537 		aParameter.Copy(resultPackage);
       
   538       return;
       
   539 		}
       
   540 	default:
       
   541 		error=KErrNotSupported;
       
   542 		break;
       
   543 		}
       
   544 	User::LeaveIfError(error);
       
   545 	}
       
   546 
       
   547 CMsvOperation* CImap4ClientMtm::InvokeAsyncFunctionL(TInt aFunctionId,
       
   548 												const CMsvEntrySelection& aSelection, 
       
   549 												TDes8& aParameter, 
       
   550 												TRequestStatus& aCompletionStatus)
       
   551 /** Invokes asynchronous IMAP-specific operations.
       
   552 
       
   553 This provides support for a large number of IMAP-specific functions, including
       
   554 operations to:
       
   555 
       
   556 - Connect and logon to a remote server
       
   557 - Synchronise headers
       
   558 - Subscribe to mailboxes
       
   559 - Populate messages
       
   560 - Copy messages
       
   561 - Move messages
       
   562 - Create messages
       
   563 - Set offline behaviour
       
   564 
       
   565 For details of operations, see #TImap4Cmds.
       
   566 
       
   567 @param aFunctionId Specifies which operation to perform e.g. connect, copy 
       
   568 new mail etc. The specific operations are defined by the #TImap4Cmds enumeration. 
       
   569 @param aSelection A selection of messages. The use is dependant upon the command 
       
   570 specified by @c aFunctionID.
       
   571 @param aParameter Use is dependant upon the command specified by @c aFunctionID
       
   572 @param aCompletionStatus The status when the operation completes. 
       
   573 @leave KErrNotFound The selection of email to be moved or copied is empty
       
   574 @leave KErrNotSupported The specified operation is not recognised
       
   575 @return If successful, this is an asynchronously completing operation. If failed, 
       
   576 this is a completed operation, with status set to the relevant error code. 
       
   577 @panic IMCM 33 MTM has no current context (debug builds only)
       
   578 @see TImap4Cmds */
       
   579 	{
       
   580     __ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EImpcNoCMsvEntrySet));
       
   581 	CMsvOperation* operation = NULL;
       
   582 	switch (aFunctionId)
       
   583 		{
       
   584 	case KIMAP4MTMConnect:
       
   585 	case KIMAP4MTMConnectAndSynchronise:
       
   586 	case KIMAP4MTMDisconnect:
       
   587 		if (aFunctionId!=KIMAP4MTMDisconnect)
       
   588 			{
       
   589 			RestoreSettingsL();
       
   590 			if (iImImap4Settings.AutoSendOnConnect()) //hope iImPop3Settings is restored by this stage
       
   591 				{
       
   592 				TRAPD(err,SendOnNextConnectionL());  //ignore the error and continue with connecting
       
   593 				}
       
   594 			}
       
   595 		operation = (Session().TransferCommandL(aSelection, aFunctionId, aParameter, aCompletionStatus));
       
   596 		break;
       
   597 	case KIMAP4MTMCancelBackgroundSynchronise:
       
   598 	case KIMAP4MTMStartBatch:
       
   599 	case KIMAP4MTMEndBatch:
       
   600 	case KIMAP4MTMBusy:
       
   601 	case KIMAP4MTMSelect:
       
   602 	case KIMAP4MTMSynchronise:
       
   603 	case KIMAP4MTMSyncTree:
       
   604 	case KIMAP4MTMSyncSubscription:
       
   605 	case KIMAP4MTMFullSync:
       
   606 	case KIMAP4MTMLocalSubscribe:
       
   607 	case KIMAP4MTMLocalUnsubscribe:
       
   608 	case KIMAP4MTMInboxNewSync:
       
   609 	case KIMAP4MTMFolderFullSync:
       
   610 	case KIMAP4MTMWaitForBackground:
       
   611 	case KIMAP4MTMRenameFolder:
       
   612 	case KIMAP4MTMUndeleteAll:
       
   613 	case KIMAP4MTMCancelOffLineOperations:
       
   614 	case KIMAP4MTMPopulate:
       
   615 		{
       
   616 		if(aFunctionId == KIMAP4MTMPopulate)
       
   617 			{
       
   618 			ConvertToPartialPopulate(aParameter);
       
   619 			return (Session().TransferCommandL(aSelection, aFunctionId, iImap4GetPartialMailInfo, aCompletionStatus));
       
   620 			}
       
   621 		operation = (Session().TransferCommandL(aSelection, aFunctionId, aParameter, aCompletionStatus));
       
   622 		}
       
   623 		break;
       
   624 	case KIMAP4MTMConnectAndSyncCompleteAfterConnect:
       
   625 	case KIMAP4MTMConnectAndSyncCompleteAfterFullSync:
       
   626 	case KIMAP4MTMConnectAndSyncCompleteAfterDisconnect:
       
   627 		{
       
   628 		TImapConnectionCompletionState connectAndSyncCompleteState = EAfterConnect;
       
   629 		switch (aFunctionId)
       
   630 			{
       
   631 			case KIMAP4MTMConnectAndSyncCompleteAfterConnect:
       
   632 				connectAndSyncCompleteState = EAfterConnect;
       
   633 				break;
       
   634 			case KIMAP4MTMConnectAndSyncCompleteAfterFullSync:
       
   635 				connectAndSyncCompleteState = EAfterFullSync;
       
   636 				break;
       
   637 			case KIMAP4MTMConnectAndSyncCompleteAfterDisconnect:
       
   638 				connectAndSyncCompleteState = EAfterDisconnection;
       
   639 				break;
       
   640 			default:
       
   641 				break;
       
   642 			}
       
   643 
       
   644 		MMsvImapConnectionObserver* connectionObserver;
       
   645 		TPckgC<MMsvImapConnectionObserver*> paramPack(connectionObserver);
       
   646 		paramPack.Set(aParameter);
       
   647 		connectionObserver = paramPack();
       
   648 
       
   649 		operation = CImapConnectAndSyncOp::NewL(Session(),
       
   650 												aSelection,
       
   651 												*this,
       
   652 												CActive::EPriorityStandard,
       
   653 												aCompletionStatus,
       
   654 												connectAndSyncCompleteState,
       
   655 												connectionObserver);
       
   656 		}
       
   657 		break;
       
   658 	case KIMAP4MTMCopyNewMailWhenAlreadyConnected:
       
   659 	case KIMAP4MTMCopyAllMailWhenAlreadyConnected:
       
   660 	case KIMAP4MTMCopyMailSelectionWhenAlreadyConnected:
       
   661 	case KIMAP4MTMMoveNewMailWhenAlreadyConnected:
       
   662 	case KIMAP4MTMMoveMailSelectionWhenAlreadyConnected:
       
   663 	case KIMAP4MTMMoveAllMailWhenAlreadyConnected:
       
   664 	case KIMAP4MTMPopulateNewMailWhenAlreadyConnected:
       
   665 	case KIMAP4MTMPopulateAllMailWhenAlreadyConnected:
       
   666 	case KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected:
       
   667 		{
       
   668 		delete iMsvEntrySelection;
       
   669 		iMsvEntrySelection = new(ELeave) CMsvEntrySelection();
       
   670 		ConvertToPartialPopulate(aParameter);
       
   671 		switch (aFunctionId)
       
   672 			{
       
   673 			case KIMAP4MTMCopyNewMailWhenAlreadyConnected:
       
   674 			case KIMAP4MTMCopyAllMailWhenAlreadyConnected:
       
   675 			case KIMAP4MTMMoveNewMailWhenAlreadyConnected:
       
   676 			case KIMAP4MTMMoveAllMailWhenAlreadyConnected:
       
   677 			case KIMAP4MTMPopulateNewMailWhenAlreadyConnected:
       
   678 			case KIMAP4MTMPopulateAllMailWhenAlreadyConnected:
       
   679 				{
       
   680 				FilterAllOrNewMailsL(aFunctionId,aSelection,iImap4GetPartialMailInfo);
       
   681 				}
       
   682 				break;
       
   683 			case KIMAP4MTMCopyMailSelectionWhenAlreadyConnected:
       
   684 			case KIMAP4MTMMoveMailSelectionWhenAlreadyConnected:
       
   685 			case KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected:
       
   686 				{
       
   687 				FilterMailSelectionL(aSelection,iImap4GetPartialMailInfo);
       
   688 				}
       
   689 				break;
       
   690 			}
       
   691 
       
   692 		// only need to do copy/move if the selection is not empty
       
   693 		if (iMsvEntrySelection->Count()>0)
       
   694 			{
       
   695 			return CopyMoveOrPopulateL(aFunctionId,iImap4GetPartialMailInfo,aCompletionStatus);
       
   696 			}
       
   697 		else
       
   698 			operation = CMsvCompletedOperation::NewL(Session(), KUidMsgTypeIMAP4, KNullDesC8, iMsvEntry->Entry().iServiceId, aCompletionStatus);	
       
   699 		}
       
   700 		break;
       
   701 	case KIMAP4MTMConnectAndCopyNewMailAndStayOnline:
       
   702 	case KIMAP4MTMConnectAndCopyNewMailAndDisconnect:
       
   703 	case KIMAP4MTMConnectAndCopyAllMailAndStayOnline:
       
   704 	case KIMAP4MTMConnectAndCopyAllMailAndDisconnect:
       
   705 	case KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline:
       
   706 	case KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect:
       
   707 	case KIMAP4MTMConnectAndMoveNewMailAndStayOnline:
       
   708 	case KIMAP4MTMConnectAndMoveNewMailAndDisconnect:
       
   709 	case KIMAP4MTMConnectAndMoveAllMailAndStayOnline:
       
   710 	case KIMAP4MTMConnectAndMoveAllMailAndDisconnect:
       
   711 	case KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline:
       
   712 	case KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect:
       
   713 	case KIMAP4MTMConnectAndPopulateNewMailAndStayOnline:
       
   714 	case KIMAP4MTMConnectAndPopulateNewMailAndDisconnect:
       
   715 	case KIMAP4MTMConnectAndPopulateAllMailAndStayOnline:
       
   716 	case KIMAP4MTMConnectAndPopulateAllMailAndDisconnect:
       
   717 	case KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline:
       
   718 	case KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect:
       
   719 		{
       
   720 		ConvertToPartialPopulate(aParameter);
       
   721 		return iImIMAP4GetMail->GetMailL(aFunctionId, *this, aSelection, iImap4GetPartialMailInfo, aCompletionStatus);
       
   722 		}
       
   723 	case KIMAP4MTMCreateNewEmailMessage:
       
   724 	case KIMAP4MTMCreateReplyEmailMessage:
       
   725 	case KIMAP4MTMCreateForwardEmailMessage:
       
   726 	case KIMAP4MTMCreateForwardAsAttachmentEmailMessage:
       
   727 	case KIMAP4MTMCreateReceiptEmailMessage:
       
   728 		{
       
   729 		TImCreateMessageOptions createMessageOptions;	
       
   730 		TPckgC<TImCreateMessageOptions> paramPack(createMessageOptions);
       
   731 		paramPack.Set(aParameter);
       
   732 		switch (aFunctionId)
       
   733 			{
       
   734 		case KIMAP4MTMCreateNewEmailMessage:
       
   735 			return iImEmailOperation->CreateNewL(aCompletionStatus, iMsvEntry->Session(), aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   736 		case KIMAP4MTMCreateReplyEmailMessage:
       
   737 			return iImEmailOperation->CreateReplyL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   738 		case KIMAP4MTMCreateForwardEmailMessage:
       
   739 			return iImEmailOperation->CreateForwardL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   740 		case KIMAP4MTMCreateForwardAsAttachmentEmailMessage:
       
   741 			return iImEmailOperation->CreateForwardAsAttachmentL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   742 		case KIMAP4MTMCreateReceiptEmailMessage:
       
   743 			return iImEmailOperation->CreateReceiptL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   744 		default:
       
   745 			User::Leave(KErrNotSupported);
       
   746 			return NULL;	// shouldn't really get here!
       
   747 			}
       
   748 		}
       
   749 	default:
       
   750 		User::Leave(KErrNotSupported);
       
   751 		return NULL;
       
   752 		}
       
   753 	return operation;
       
   754 }
       
   755 
       
   756 /** Converts the full download information to partial download informations with parameters 
       
   757 for partial download information set to  defaults. This package will later be interpreted by 
       
   758 server to check whether it is for full download or partial download.
       
   759 
       
   760 @param aParameter Contains information about full fetch of a message or
       
   761 partial fetch of a message .
       
   762 */
       
   763 void CImap4ClientMtm::ConvertToPartialPopulate(TDes8& aParameter)
       
   764 	{
       
   765 	if(aParameter.Length() == sizeof(TImImap4GetPartialMailInfo))
       
   766 		{
       
   767 		iImap4GetPartialMailInfo.Copy(aParameter);
       
   768 		}
       
   769 	else
       
   770 		{
       
   771 		TImImap4GetMailInfo imap4GetMailInfo;	
       
   772 		TPckgC<TImImap4GetMailInfo> paramPack(imap4GetMailInfo);
       
   773 		paramPack.Set(aParameter);
       
   774 		// Copy TImImap4GetMailInfo information into TImImap4GetPartialMailInfo
       
   775 		TImImap4GetPartialMailInfo imap4GetPartialMailInfo;
       
   776 		imap4GetPartialMailInfo.iGetMailBodyParts = paramPack().iGetMailBodyParts;
       
   777 		imap4GetPartialMailInfo.iMaxEmailSize = paramPack().iMaxEmailSize;
       
   778 		imap4GetPartialMailInfo.iDestinationFolder = paramPack().iDestinationFolder;
       
   779 
       
   780 		// Set the remaining members to default so that the server can check 
       
   781 		// if these are defaults, then this package is for TImImap4GetMailInfo
       
   782 		imap4GetPartialMailInfo.iTotalSizeLimit	= KMaxTInt;
       
   783 		imap4GetPartialMailInfo.iBodyTextSizeLimit = KMaxTInt;
       
   784 		imap4GetPartialMailInfo.iAttachmentSizeLimit = KMaxTInt;
       
   785 		imap4GetPartialMailInfo.iPartialMailOptions = ENoSizeLimits;
       
   786 		
       
   787 		iImap4GetPartialMailInfo = imap4GetPartialMailInfo;
       
   788 		}
       
   789 	}
       
   790 
       
   791 /** Returns whether aParameter contains information for partial fetch of full fetch
       
   792 
       
   793 @param aParameter Contains information about full fetch of a message or
       
   794 partial fetch of a message .
       
   795 
       
   796 @return ETrue if aParamter contains information for partial fetch
       
   797 else EFalse indicates it has information for full download of a message
       
   798 */
       
   799 TBool CImap4ClientMtm::IsPartialPopulate(TDes8& aParameter)
       
   800 	{
       
   801 	TBool isPartialPopulate = EFalse;
       
   802 	if(aParameter.Length() == sizeof(TImImap4GetPartialMailInfo))
       
   803 		{
       
   804 		TImImap4GetPartialMailInfo iImapGetPartialMailInfo;
       
   805 		TPckgC<TImImap4GetPartialMailInfo>	pkgPartial(iImapGetPartialMailInfo);
       
   806 		pkgPartial.Set(aParameter);
       
   807 
       
   808 		if(pkgPartial().iPartialMailOptions == ENoSizeLimits &&
       
   809 			pkgPartial().iTotalSizeLimit == KMaxTInt &&
       
   810 			pkgPartial().iBodyTextSizeLimit == KMaxTInt && 
       
   811 			pkgPartial().iAttachmentSizeLimit == KMaxTInt && 
       
   812 			(pkgPartial().iGetMailBodyParts == EGetImap4EmailHeaders || 
       
   813 			pkgPartial().iGetMailBodyParts == EGetImap4EmailBodyText ||
       
   814 			pkgPartial().iGetMailBodyParts == EGetImap4EmailBodyTextAndAttachments ||
       
   815 			pkgPartial().iGetMailBodyParts == EGetImap4EmailAttachments ||
       
   816 			pkgPartial().iGetMailBodyParts == EGetImap4EmailBodyAlternativeText))
       
   817 			{
       
   818 			isPartialPopulate = EFalse;
       
   819 			}
       
   820 		else
       
   821 			{
       
   822 			isPartialPopulate = ETrue;
       
   823 			}
       
   824 		}
       
   825 	else
       
   826 		{
       
   827 		isPartialPopulate = EFalse;
       
   828 		}
       
   829 	return isPartialPopulate;
       
   830 	}
       
   831 
       
   832 /** Copies or moves the selection only if the selection is not empty
       
   833 
       
   834 @param aFunctionId Specifies which operation to perform e.g. copy new mail, Move or Populate.
       
   835 The specific operations are defined by the TImap4Cmds enumeration. 
       
   836 @param aParameter Use is dependant upon the command specified by aFunctionID
       
   837 @param aCompletionStatus The status when the operation completes. 
       
   838 @return If successful, this is an asynchronously completing operation. If failed, 
       
   839 this is a completed operation, with status set to the relevant error code. 
       
   840 */
       
   841 CMsvOperation* CImap4ClientMtm::CopyMoveOrPopulateL(TInt aFunctionId,TDes8& aParameter,TRequestStatus& aCompletionStatus)
       
   842 	{
       
   843 	// set entry to the parent of the selection of messages
       
   844 	// assumes the selection of messages have the same parent i.e. in the same folder
       
   845 	CMsvOperation* operation = NULL;
       
   846 	TMsvEmailEntry entry;
       
   847 	TMsvId service = KMsvNullIndexEntryId;
       
   848 	iMsvEntry->Session().GetEntry((*iMsvEntrySelection)[0], service, entry);
       
   849 	iMsvEntry->SetEntryL(entry.Parent());
       
   850 	
       
   851 	// Unpackage TImImap4GetPartialMailInfo
       
   852 	TImImap4GetPartialMailInfo imap4GetMailInfo;	
       
   853 	TPckgC<TImImap4GetPartialMailInfo> paramPack(imap4GetMailInfo);
       
   854 	paramPack.Set(aParameter);	
       
   855 
       
   856 	if ((aFunctionId == KIMAP4MTMCopyNewMailWhenAlreadyConnected) ||
       
   857 		(aFunctionId == KIMAP4MTMCopyMailSelectionWhenAlreadyConnected) ||
       
   858 		(aFunctionId == KIMAP4MTMCopyAllMailWhenAlreadyConnected))
       
   859 		{
       
   860 		return iMsvEntry->CopyL(*iMsvEntrySelection, paramPack().iDestinationFolder, aCompletionStatus);
       
   861 		}
       
   862 	else if ((aFunctionId == KIMAP4MTMMoveNewMailWhenAlreadyConnected) ||
       
   863 		(aFunctionId == KIMAP4MTMMoveMailSelectionWhenAlreadyConnected) ||
       
   864 		(aFunctionId == KIMAP4MTMMoveAllMailWhenAlreadyConnected))
       
   865 		{
       
   866 		return iMsvEntry->MoveL(*iMsvEntrySelection, paramPack().iDestinationFolder, aCompletionStatus);
       
   867 		}
       
   868 	else //KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected,KIMAP4MTMPopulateNewMailWhenAlreadyConnected,KIMAP4MTMPopulateAllMailWhenAlreadyConnected
       
   869 		{
       
   870 		operation = Session().TransferCommandL(*iMsvEntrySelection, KIMAP4MTMPopulate, paramPack, aCompletionStatus);		
       
   871 		return operation;
       
   872 		}
       
   873 	}
       
   874 
       
   875 /** Filter the selection of messages for all mails or new mails
       
   876 
       
   877 @param aFunctionId Specifies which operation to perform e.g. connect, copy 
       
   878 new mail etc. The specific operations are defined by the TImap4Cmds enumeration. 
       
   879 @param aSelection A selection of messages. The use is dependant upon the command 
       
   880 specified by aFunctionID.
       
   881 @param aParameter Use is dependant upon the command specified by aFunctionID . 
       
   882 This can have information for full fetch or partial fetch of a message. 
       
   883 */
       
   884 void CImap4ClientMtm::FilterAllOrNewMailsL(TInt aFunctionId,	const CMsvEntrySelection& aSelection,TDes8& aParameter)
       
   885 	{
       
   886 	iMsvEntry->SetEntryL(aSelection[1]); // set entry to the folder from which to copy/move
       
   887 	// get a selection of messages
       
   888 	CMsvEntrySelection* msvEntrySelection = iMsvEntry->ChildrenWithTypeL(KUidMsvMessageEntry);
       
   889 	CleanupStack::PushL(msvEntrySelection);
       
   890 	TMsvId messageId;
       
   891 	// get a selection of messages which are new - i.e have new flag set.
       
   892 	//	from the selection of messages under the service
       
   893 	for (TInt i=0; i<msvEntrySelection->Count(); i++)
       
   894 		{
       
   895 		messageId = (*msvEntrySelection)[i];
       
   896 		TMsvEmailEntry entry;
       
   897 		TMsvId service = KMsvNullIndexEntryId;
       
   898 		iMsvEntry->Session().GetEntry(messageId, service, entry);
       
   899 
       
   900 		TImImap4GetPartialMailInfo imap4GetPartialMailInfo;	
       
   901 		TPckgC<TImImap4GetPartialMailInfo> paramPack(imap4GetPartialMailInfo);
       
   902 		paramPack.Set(aParameter);
       
   903 			
       
   904         TBool isComplete = ! ((entry.Complete() && entry.PartialDownloaded()) ||
       
   905 							 	(!entry.Complete() && 
       
   906 							 		(!entry.BodyTextComplete() 
       
   907 							 		|| (paramPack().iGetMailBodyParts ==  EGetImap4EmailBodyTextAndAttachments)) 
       
   908 							 		   && !entry.PartialDownloaded()));
       
   909 		if ((aFunctionId == KIMAP4MTMCopyNewMailWhenAlreadyConnected) ||
       
   910 			(aFunctionId == KIMAP4MTMMoveNewMailWhenAlreadyConnected) ||
       
   911 			(aFunctionId == KIMAP4MTMPopulateNewMailWhenAlreadyConnected))
       
   912 			{
       
   913 
       
   914 			if(aFunctionId == KIMAP4MTMPopulateNewMailWhenAlreadyConnected && IsPartialPopulate(aParameter) && !isComplete)
       
   915 				{
       
   916 				if ((entry.iType == KUidMsvMessageEntry) && (entry.New()))
       
   917 					iMsvEntrySelection->AppendL(messageId);
       
   918 				}
       
   919 			else
       
   920 				{
       
   921 				if ((entry.iType == KUidMsvMessageEntry) && (entry.New()) && (entry.iSize <= paramPack().iMaxEmailSize))
       
   922 					{
       
   923 					if ((isComplete && aFunctionId == KIMAP4MTMPopulateNewMailWhenAlreadyConnected) ||
       
   924 					 	(entry.Parent() == paramPack().iDestinationFolder && (aFunctionId == KIMAP4MTMMoveNewMailWhenAlreadyConnected || isComplete)))
       
   925 						{
       
   926 						// Selected entries are filtered from the original list if this is a 
       
   927 						// populate operation and the message is complete.
       
   928 						//
       
   929 						// Note that a copy to local operation where the destination folder is
       
   930 						// the same as the source folder is equivalent to a populate operation
       
   931 						// as the contents of the message are fetched to the local mirror folder
       
   932 						// and hence complete messages are removed from the list in this case.
       
   933 						//
       
   934 						// Move operations where the source and destination folder are the same
       
   935 						// are not supported and are also filtered from the original list.
       
   936 						}
       
   937 					else
       
   938 						{
       
   939 						iMsvEntrySelection->AppendL(messageId);
       
   940 						}
       
   941 					}
       
   942 				}
       
   943 			}
       
   944 		else // KIMAP4MTMCopyAllMailWhenAlreadyConnected, KIMAP4MTMMoveAllMailWhenAlreadyConnected, KIMAP4MTMPopulateAllMailWhenAlreadyConnected
       
   945 			{
       
   946 			
       
   947 			if(aFunctionId == KIMAP4MTMPopulateAllMailWhenAlreadyConnected && IsPartialPopulate(aParameter) && !isComplete)
       
   948 				{
       
   949 				if ((entry.iType == KUidMsvMessageEntry) && !entry.Complete())
       
   950 					iMsvEntrySelection->AppendL(messageId);
       
   951 				}
       
   952 			else
       
   953 				{
       
   954 				if ((entry.iType == KUidMsvMessageEntry) && (entry.iSize <= paramPack().iMaxEmailSize))
       
   955 					{
       
   956 					if ((isComplete && aFunctionId == KIMAP4MTMPopulateAllMailWhenAlreadyConnected) ||
       
   957 					 (entry.Parent() == paramPack().iDestinationFolder && (aFunctionId == KIMAP4MTMMoveAllMailWhenAlreadyConnected || isComplete)))
       
   958 						{
       
   959 						// Selected entries are filtered from the original list if this is a 
       
   960 						// populate operation and the message is complete.
       
   961 						//
       
   962 						// Note that a copy to local operation where the destination folder is
       
   963 						// the same as the source folder is equivalent to a populate operation
       
   964 						// as the contents of the message are fetched to the local mirror folder
       
   965 						// and hence complete messages are removed from the list in this case.
       
   966 						//
       
   967 						// Move operations where the source and destination folder are the same
       
   968 						// are not supported and are also filtered from the original list.
       
   969 						}
       
   970 					else
       
   971 						{
       
   972 						iMsvEntrySelection->AppendL(messageId);
       
   973 						}
       
   974 					}
       
   975 				}
       
   976 			}
       
   977 		}
       
   978 	CleanupStack::PopAndDestroy(); //msvEntrySelection;
       
   979 	}	
       
   980 
       
   981 /** Filters the mails selected for partial fetch or full fetch of messages
       
   982 
       
   983 @param aSelection A selection of messages. The use is dependant upon the command 
       
   984 specified by aFunctionID.
       
   985 @param aParameter Use is dependant upon the command specified by aFunctionID . 
       
   986 This can have information for full fetch or partial fetch of a message. 
       
   987 */
       
   988 void CImap4ClientMtm::FilterMailSelectionL(const CMsvEntrySelection& aSelection,TDes8& aParameter)
       
   989 	{
       
   990 	iMsvEntry->SetEntryL(aSelection[0]); // set entry to service
       
   991 	TMsvId messageId;
       
   992 	// get the selection of messages from aSelection (note first element of the
       
   993 	// CMsvEntrySelection is the service which is then followed by any messages
       
   994 	for (TInt i=0; i<aSelection.Count(); i++)
       
   995 		{
       
   996 		messageId = (aSelection)[i];
       
   997 		if (i>0) // since 1st element is the service
       
   998 			{
       
   999 			TMsvEmailEntry entry;
       
  1000 			TMsvId service = KMsvNullIndexEntryId;			
       
  1001 			User::LeaveIfError(iMsvEntry->Session().GetEntry(messageId, service, entry));
       
  1002 			TImImap4GetPartialMailInfo imap4GetPartialMailInfo;	
       
  1003 			TPckgC<TImImap4GetPartialMailInfo> paramPack(imap4GetPartialMailInfo);
       
  1004 			paramPack.Set(aParameter);
       
  1005 			
       
  1006 			  TBool isComplete = ! ((entry.Complete() && entry.PartialDownloaded()) ||
       
  1007 								 	(!entry.Complete() && 
       
  1008 								 		(!entry.BodyTextComplete() 
       
  1009 					 					|| (paramPack().iGetMailBodyParts ==  EGetImap4EmailBodyTextAndAttachments)) 
       
  1010 					 		   			   && !entry.PartialDownloaded()));
       
  1011 
       
  1012 			if(IsPartialPopulate(aParameter) && !isComplete)
       
  1013 				{
       
  1014 				if ((entry.iType == KUidMsvMessageEntry))
       
  1015 					iMsvEntrySelection->AppendL(messageId);	
       
  1016 				}
       
  1017 			else
       
  1018 				{
       
  1019 
       
  1020 				if ((entry.iType == KUidMsvMessageEntry) && (entry.iSize <= paramPack().iMaxEmailSize))
       
  1021 					{
       
  1022 					if(entry.Parent() == paramPack().iDestinationFolder && isComplete)
       
  1023 						{
       
  1024 						// do not append if this is a populate operation and the message is complete
       
  1025 						}
       
  1026 					else
       
  1027 						{
       
  1028 						iMsvEntrySelection->AppendL(messageId);			
       
  1029 						}
       
  1030 					}
       
  1031 				}
       
  1032 			}
       
  1033 		}
       
  1034 	}
       
  1035 
       
  1036 void CImap4ClientMtm::HandleEntryEvent(TMsvEntryEvent /*aEvent*/, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
       
  1037 	{    
       
  1038 	}
       
  1039 
       
  1040 //
       
  1041 // CImImap4Settings wrapper functions
       
  1042 EXPORT_C void CImap4ClientMtm::SetImap4SettingsL(const CImImap4Settings& aSettings)
       
  1043 /** Sets the IMAP4 email service settings.
       
  1044 
       
  1045 This can be called at any time to override any current email settings (if 
       
  1046 they exist). However, new settings are only used by the MTM if they have been 
       
  1047 stored and then a new IMAP4 email session has been started: i.e. settings 
       
  1048 cannot be changed in mid-session.
       
  1049 
       
  1050 @param aSettings New IMAP4 service settings */
       
  1051     {
       
  1052     iImImap4Settings.CopyL(aSettings);
       
  1053     }
       
  1054 
       
  1055 EXPORT_C const CImImap4Settings& CImap4ClientMtm::Imap4Settings() const
       
  1056 /** Gets the IMAP4 email service settings currently being used by the client MTM, 
       
  1057 if they exist. 
       
  1058 
       
  1059 If no settings exist, then an empty settings object will be returned by this 
       
  1060 function. Settings will only exist if a prior call has been made to the RestoreL() 
       
  1061 function when the client MTM was positioned over an IMAP4 service in the message 
       
  1062 store.
       
  1063 
       
  1064 @return IMAP4 service settings */
       
  1065     {
       
  1066     return iImImap4Settings;
       
  1067     }
       
  1068 
       
  1069 //
       
  1070 // inherited from MUndoOffLine. This method is responsible for undoing
       
  1071 // an offline operation.
       
  1072 /**
       
  1073 This function is not supported.
       
  1074 
       
  1075 @param aDeleted Unused
       
  1076 @param aFolderId Unused
       
  1077 */
       
  1078 void CImap4ClientMtm::UndoOffLineChangesL(const CImOffLineOperation& /*aDeleted*/, TMsvId /*aFolderId*/)
       
  1079 //
       
  1080 // This method receives an offline operation struct the user wishes to cancel.
       
  1081 // The offline operation will already have been removed from the store of the
       
  1082 // folder. All that needs to be done is actually undo the operation itself.
       
  1083 // For instance, if an offline operation moved a message to another folder, this
       
  1084 // is the time to move the message back.
       
  1085 // This is probably best done by theserver dll, as the move has to be done without
       
  1086 // doing it on the remote server.
       
  1087 //
       
  1088     {
       
  1089     TODO//
       
  1090 
       
  1091     }
       
  1092 
       
  1093 //
       
  1094 // Returning a list of all the offline operations for a service entry.
       
  1095 
       
  1096 /**
       
  1097 @internalTechnology
       
  1098 */
       
  1099 
       
  1100 EXPORT_C CImOperationQueueList* CImap4ClientMtm::QueueListL(CMsvEntry& aServiceEntry)
       
  1101 	{
       
  1102 	return CImOperationQueueList::NewL(aServiceEntry, this);
       
  1103 	}
       
  1104 
       
  1105 void CImap4ClientMtm::AddAddresseeL(const TDesC& aRealAddress) 
       
  1106 /** Message address function required by the base class, but not used for IMAP. 
       
  1107 
       
  1108 To modify message address information, use the address functions in CImHeader.
       
  1109 
       
  1110 @param aRealAddress Address. */
       
  1111     {
       
  1112     __ASSERT_DEBUG(iAddresseeList != NULL, gPanic(EImpcNoAddresseeList));
       
  1113     iAddresseeList->AppendL(aRealAddress);
       
  1114     }
       
  1115 
       
  1116 void CImap4ClientMtm::AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias) 
       
  1117 /** Message address function required by the base class, but not used for IMAP. 
       
  1118 
       
  1119 To modify message address information, use the address functions in CImHeader.
       
  1120 
       
  1121 @param aRealAddress Address.
       
  1122 @param aAlias Alias information. */
       
  1123     {
       
  1124 	 __ASSERT_DEBUG(iAddresseeList != NULL, gPanic(EImpcNoAddresseeList));
       
  1125 	HBufC* emailAddress = HBufC::NewLC(aRealAddress.Length()+aAlias.Length()+iEmailAddressFormatString->Length()-4);
       
  1126 	emailAddress->Des().Format(*iEmailAddressFormatString,&aAlias,&aRealAddress);
       
  1127 	iAddresseeList->AppendL(aRealAddress);
       
  1128 	CleanupStack::PopAndDestroy();	// emailAddress
       
  1129 	}
       
  1130 
       
  1131 void CImap4ClientMtm::RemoveAddressee(TInt aIndex) 
       
  1132 /** Message address function required by the base class, but not used for IMAP. 
       
  1133 
       
  1134 To modify message address information, use the address functions in CImHeader.
       
  1135 
       
  1136 @param aIndex Index of address to be removed. */
       
  1137     {
       
  1138     __ASSERT_DEBUG(iAddresseeList != NULL, gPanic(EImpcNoAddresseeList));
       
  1139     iAddresseeList->Delete(aIndex);
       
  1140     }
       
  1141 
       
  1142 void CImap4ClientMtm::ContextEntrySwitched() 
       
  1143     {
       
  1144     } 
       
  1145 
       
  1146 
       
  1147 // Attachment functions to support the SendAs API
       
  1148 
       
  1149 /** Unsupported client MTM base class function.
       
  1150 
       
  1151 To modify message attachments, use CImEmailMessage.
       
  1152 
       
  1153 @param aFilePath Unused
       
  1154 @param aMimeType Unused
       
  1155 @param aCharset Unused
       
  1156 @param aStatus Unused
       
  1157 @leave KErrNotSupported Function not supported.
       
  1158  */
       
  1159 EXPORT_C void CImap4ClientMtm::AddAttachmentL(const TDesC& /*aFilePath*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
  1160 	{
       
  1161 	User::Leave(KErrNotSupported);
       
  1162 	}
       
  1163 
       
  1164 /** Unsupported client MTM base class function.
       
  1165 
       
  1166 To modify message attachments, use CImEmailMessage.
       
  1167 
       
  1168 @param aFile Unused
       
  1169 @param aMimeType Unused
       
  1170 @param aCharset Unused
       
  1171 @param aStatus Unused
       
  1172 @leave KErrNotSupported Function not supported.
       
  1173  */	
       
  1174 EXPORT_C void CImap4ClientMtm::AddAttachmentL(RFile& /*aFile*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
  1175 	{
       
  1176 	User::Leave(KErrNotSupported);
       
  1177 	}
       
  1178 	
       
  1179 /** Unsupported client MTM base class function.
       
  1180 
       
  1181 To modify message attachments, use CImEmailMessage.
       
  1182 
       
  1183 @param aFilePath Unused
       
  1184 @param aMimeType Unused
       
  1185 @param aCharset Unused
       
  1186 @param aStatus Unused
       
  1187 @leave KErrNotSupported Function not supported.
       
  1188  */
       
  1189 EXPORT_C void CImap4ClientMtm::AddLinkedAttachmentL(const TDesC& /*aFilePath*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
  1190 	{
       
  1191 	User::Leave(KErrNotSupported);
       
  1192 	}
       
  1193 	
       
  1194 /** Unsupported client MTM base class function.
       
  1195 
       
  1196 To modify message attachments, use CImEmailMessage.
       
  1197 
       
  1198 @param aAttachmentId Unused
       
  1199 @param aStatus Unused
       
  1200 @leave KErrNotSupported Function not supported.
       
  1201  */
       
  1202 EXPORT_C void CImap4ClientMtm::AddEntryAsAttachmentL(TMsvId /*aAttachmentId*/, TRequestStatus& /*aStatus*/)
       
  1203 	{
       
  1204 	User::Leave(KErrNotSupported);
       
  1205 	}
       
  1206 	
       
  1207 /** Unsupported client MTM base class function.
       
  1208 
       
  1209 To modify message attachments, use CImEmailMessage.
       
  1210 
       
  1211 @param aFileName Unused
       
  1212 @param aAttachmentFile Unused
       
  1213 @param aMimeType Unused
       
  1214 @param aCharset Unused
       
  1215 @param aStatus Unused
       
  1216 @leave KErrNotSupported Function not supported.
       
  1217  */
       
  1218 EXPORT_C void CImap4ClientMtm::CreateAttachmentL(const TDesC& /*aFileName*/, RFile& /*aAttachmentFile*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
  1219 	{
       
  1220 	User::Leave(KErrNotSupported);
       
  1221 	}
       
  1222 
       
  1223 EXPORT_C void CImap4ClientMtm::CreateMessageL(TMsvId /*aServiceId*/)
       
  1224 /** Unsupported client MTM base class function.
       
  1225 
       
  1226 To create a new message, use CImEmailOperation.
       
  1227 
       
  1228 @param aServiceId Unused 
       
  1229 @leave KErrNotSupported Function not supported.
       
  1230 */
       
  1231 	{
       
  1232 	User::Leave(KErrNotSupported);
       
  1233 	}
       
  1234 
       
  1235 /** Unsupported client MTM base class function.
       
  1236 
       
  1237 @return KErrNotSupported Function not supported.
       
  1238 @leave KErrNotSupported Function not supported.
       
  1239 */
       
  1240 EXPORT_C TMsvId CImap4ClientMtm::DefaultServiceL() const
       
  1241 	{
       
  1242 	User::Leave(KErrNotSupported);
       
  1243 	return KErrNotSupported;
       
  1244 	}
       
  1245 	
       
  1246 /** Unsupported client MTM base class function.
       
  1247 
       
  1248 @leave KErrNotSupported Function not supported.
       
  1249 */
       
  1250 EXPORT_C void CImap4ClientMtm::RemoveDefaultServiceL()
       
  1251 	{
       
  1252 	User::Leave(KErrNotSupported);
       
  1253 	}
       
  1254 
       
  1255 /** Unsupported client MTM base class function.
       
  1256 
       
  1257 @param aService Unused
       
  1258 @leave KErrNotSupported Function not supported.
       
  1259 */
       
  1260 EXPORT_C void CImap4ClientMtm::ChangeDefaultServiceL(const TMsvId& /*aService*/)
       
  1261 	{
       
  1262 	User::Leave(KErrNotSupported);
       
  1263 	}
       
  1264 
       
  1265 
       
  1266 /*
       
  1267 //	Imap4GetMail
       
  1268 */
       
  1269 EXPORT_C CMsvOperation* CImImap4GetMail::GetMailL(TInt aFunctionId, CImap4ClientMtm& aImap4ClientMtm, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo, TRequestStatus& aObserverRequestStatus)
       
  1270 /** Creates and begins a new IMAP4 get mail operation.
       
  1271 
       
  1272 Note that the function should be, though is not, marked as static. The workaround
       
  1273 is to call the function using a NULL CImImap4GetMail pointer:
       
  1274 @code
       
  1275 CImImap4GetMail* gm = NULL;
       
  1276 CMsvOperation* gmOp = gm->GetMailL(id, mtm, sel, info, status);
       
  1277 @endcode
       
  1278 
       
  1279 Alternatively, instead of using this class, call 
       
  1280 CImap4ClientMtm::InvokeAsyncFunctionL() directly. Any functionality
       
  1281 accessible through this class can also be accessed through that function. 
       
  1282 
       
  1283 @param aFunctionId Type of operation to perform, a TImap4Cmds value. Permitted commands are:
       
  1284 
       
  1285 Copy commands:
       
  1286 
       
  1287 - #KIMAP4MTMConnectAndCopyNewMailAndStayOnline
       
  1288 - #KIMAP4MTMConnectAndCopyNewMailAndDisconnect
       
  1289 - #KIMAP4MTMConnectAndCopyAllMailAndStayOnline
       
  1290 - #KIMAP4MTMConnectAndCopyAllMailAndDisconnect
       
  1291 - #KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline
       
  1292 - #KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect
       
  1293 
       
  1294 Move commands:
       
  1295 
       
  1296 - #KIMAP4MTMConnectAndMoveNewMailAndStayOnline
       
  1297 - #KIMAP4MTMConnectAndMoveNewMailAndDisconnect
       
  1298 - #KIMAP4MTMConnectAndMoveAllMailAndStayOnline
       
  1299 - #KIMAP4MTMConnectAndMoveAllMailAndDisconnect
       
  1300 - #KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline
       
  1301 - #KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect
       
  1302 
       
  1303 Populate commands:
       
  1304 
       
  1305 - #KIMAP4MTMConnectAndPopulateNewMailAndStayOnline
       
  1306 - #KIMAP4MTMConnectAndPopulateNewMailAndDisconnect
       
  1307 - #KIMAP4MTMConnectAndPopulateAllMailAndStayOnline
       
  1308 - #KIMAP4MTMConnectAndPopulateAllMailAndDisconnect
       
  1309 - #KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline
       
  1310 - #KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect
       
  1311 
       
  1312 @param aImap4ClientMtm A reference to the IMAP4 Client MTM that wants to perform 
       
  1313 the Get Mail operation.
       
  1314 @param aMsvEntrySelection A selection of messages that need to be copied/moved 
       
  1315 to a local folder. The first entry in this selection MUST be the service. 
       
  1316 Other IDs can be appended to the selection depending on which operation is 
       
  1317 to be performed. For the 'copy new', 'copy all', 'move new', 'move all', 'populate 
       
  1318 new', 'populate all' situations, the folder from which the messages are to 
       
  1319 be copied, moved or populated should be appended after the service ID. For 
       
  1320 all the other situations (i.e. copying, moving or populating a selection of 
       
  1321 messages), the selection of messages should be appended after the service 
       
  1322 ID. Please note that the selection of messages MUST have the same parent i.e. 
       
  1323 MUST be in the same folder.
       
  1324 @param aImap4GetMailInfo A packaged TImImap4GetMailInfo object storing the 
       
  1325 maximum message size, the destination folder ID, and what message parts are 
       
  1326 required. For populate commands, this can be a packaged TImImap4GetPartialMailInfo 
       
  1327 object, specifying separate size limits for body text and attachments.
       
  1328 @param aObserverRequestStatus The status to be completed when the get mail 
       
  1329 operation has completed.
       
  1330 @return The new message operation object through which the get operation can 
       
  1331 be controlled.
       
  1332 
       
  1333 @see TImap4Cmds
       
  1334 @see TImImap4GetMailInfo 
       
  1335 @see TImImap4GetPartialMailInfo
       
  1336 */
       
  1337 	{
       
  1338 	CImImap4GetMail* self = new(ELeave) CImImap4GetMail(aImap4ClientMtm.Session(), aImap4ClientMtm, aObserverRequestStatus);
       
  1339 	CleanupStack::PushL(self);
       
  1340 	self->ConstructL(aFunctionId, aMsvEntrySelection, aImap4GetMailInfo);
       
  1341 	CleanupStack::Pop(); //self
       
  1342 	return self;
       
  1343 	}
       
  1344 
       
  1345 CImImap4GetMail::~CImImap4GetMail()
       
  1346 /** Destructor. */
       
  1347 	{
       
  1348 	Cancel();
       
  1349 	delete iMsvEntrySelection;
       
  1350 	delete iMsvOperation;
       
  1351 	}
       
  1352 
       
  1353 const TDesC8& CImImap4GetMail::FinalProgress()
       
  1354 /** Gets information about a completed operation.
       
  1355 
       
  1356 @return Packaged TImap4GenericProgress holding progress information. 
       
  1357 @panic IMCM 30 Operation has not completed
       
  1358 @see TImap4GenericProgress */
       
  1359 	{
       
  1360 	__ASSERT_ALWAYS(!IsActive(), gPanic(EMiutActiveInFinalProgress));
       
  1361 
       
  1362 	const TDesC8& opProgress = iMsvOperation->FinalProgress();
       
  1363 
       
  1364 	if (opProgress.Length())
       
  1365 		{
       
  1366 		// if an error was encountered during the Get New Mail operation then need to 
       
  1367 		// return this as part of the final progresse.  If no error was encoutered then
       
  1368 		// return iProgress
       
  1369 		TImap4GenericProgress prog;	
       
  1370 		TPckgC<TImap4GenericProgress> paramPack(prog);
       
  1371 		paramPack.Set(opProgress);
       
  1372 		TImap4GenericProgress progress=paramPack();
       
  1373 		if (iErrorProgress.iErrorCode != KErrNone)
       
  1374 			{
       
  1375 			progress.iMsgsToDo = iErrorProgress.iMsgsToDo;
       
  1376 			progress.iBytesDone = iErrorProgress.iBytesDone;
       
  1377 			progress.iErrorCode = iErrorProgress.iErrorCode;
       
  1378 			progress.iImap4SubStateProgress = iErrorProgress.iImap4SubStateProgress;
       
  1379 			}
       
  1380 		else 
       
  1381 			progress.iImap4SubStateProgress = progress.iState;
       
  1382 
       
  1383 		switch(iCommand)
       
  1384 			{
       
  1385 			case KIMAP4MTMConnectAndCopyNewMailAndStayOnline:
       
  1386 			case KIMAP4MTMConnectAndCopyNewMailAndDisconnect:
       
  1387 				progress.iState= TImap4GenericProgress::ECopyNewMail;
       
  1388 				break;
       
  1389 			case KIMAP4MTMConnectAndMoveNewMailAndStayOnline:
       
  1390 			case KIMAP4MTMConnectAndMoveNewMailAndDisconnect:
       
  1391 				progress.iState = TImap4GenericProgress::EMoveNewMail;
       
  1392 				break;
       
  1393 			case KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline:
       
  1394 			case KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect:
       
  1395 				progress.iState = TImap4GenericProgress::ECopyMailSelection;
       
  1396 				break;
       
  1397 			case KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline:
       
  1398 			case KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect:
       
  1399 				progress.iState = TImap4GenericProgress::EMoveMailSelection;
       
  1400 				break;
       
  1401 			case KIMAP4MTMConnectAndCopyAllMailAndStayOnline:
       
  1402 			case KIMAP4MTMConnectAndCopyAllMailAndDisconnect:
       
  1403 				progress.iState = TImap4GenericProgress::ECopyAllMail;
       
  1404 				break;
       
  1405 			case KIMAP4MTMConnectAndMoveAllMailAndStayOnline:
       
  1406 			case KIMAP4MTMConnectAndMoveAllMailAndDisconnect:
       
  1407 				progress.iState = TImap4GenericProgress::EMoveAllMail;
       
  1408 				break;
       
  1409 			case KIMAP4MTMConnectAndPopulateNewMailAndStayOnline:
       
  1410 			case KIMAP4MTMConnectAndPopulateNewMailAndDisconnect:
       
  1411 				progress.iState = TImap4GenericProgress::EPopulateNewMail;
       
  1412 				break;
       
  1413 			case KIMAP4MTMConnectAndPopulateAllMailAndStayOnline:
       
  1414 			case KIMAP4MTMConnectAndPopulateAllMailAndDisconnect:
       
  1415 				progress.iState = TImap4GenericProgress::EPopulateAllMail;
       
  1416 				break;
       
  1417 			case KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline:
       
  1418 			case KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect:
       
  1419 				progress.iState = TImap4GenericProgress::EPopulateMailSelection;
       
  1420 				break;
       
  1421 			}
       
  1422 		
       
  1423 		iProgressBuf = progress;
       
  1424 		}
       
  1425 	return iProgressBuf;
       
  1426 	}
       
  1427 
       
  1428 void CImImap4GetMail::ResetProgress()
       
  1429 	{
       
  1430 	switch(iCommand)
       
  1431 		{
       
  1432 		case KIMAP4MTMConnectAndCopyNewMailAndStayOnline:
       
  1433 		case KIMAP4MTMConnectAndCopyNewMailAndDisconnect:
       
  1434 			iProgress.iState = TImap4GenericProgress::ECopyNewMail;
       
  1435 			break;
       
  1436 		case KIMAP4MTMConnectAndMoveNewMailAndStayOnline:
       
  1437 		case KIMAP4MTMConnectAndMoveNewMailAndDisconnect:
       
  1438 			iProgress.iState = TImap4GenericProgress::EMoveNewMail;
       
  1439 			break;
       
  1440 		case KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline:
       
  1441 		case KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect:
       
  1442 			iProgress.iState = TImap4GenericProgress::ECopyMailSelection;
       
  1443 			break;
       
  1444 		case KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline:
       
  1445 		case KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect:
       
  1446 			iProgress.iState = TImap4GenericProgress::EMoveMailSelection;
       
  1447 			break;
       
  1448 		case KIMAP4MTMConnectAndCopyAllMailAndStayOnline:
       
  1449 		case KIMAP4MTMConnectAndCopyAllMailAndDisconnect:
       
  1450 			iProgress.iState = TImap4GenericProgress::ECopyAllMail;
       
  1451 			break;
       
  1452 		case KIMAP4MTMConnectAndMoveAllMailAndStayOnline:
       
  1453 		case KIMAP4MTMConnectAndMoveAllMailAndDisconnect:
       
  1454 			iProgress.iState = TImap4GenericProgress::EMoveAllMail;
       
  1455 			break;
       
  1456 		case KIMAP4MTMConnectAndPopulateNewMailAndStayOnline:
       
  1457 		case KIMAP4MTMConnectAndPopulateNewMailAndDisconnect:
       
  1458 			iProgress.iState = TImap4GenericProgress::EPopulateNewMail;
       
  1459 			break;
       
  1460 		case KIMAP4MTMConnectAndPopulateAllMailAndStayOnline:
       
  1461 		case KIMAP4MTMConnectAndPopulateAllMailAndDisconnect:
       
  1462 			iProgress.iState = TImap4GenericProgress::EPopulateAllMail;
       
  1463 			break;
       
  1464 		case KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline:
       
  1465 		case KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect:
       
  1466 			iProgress.iState = TImap4GenericProgress::EPopulateMailSelection;
       
  1467 			break;
       
  1468 		}
       
  1469 	iProgress.iMsgsToDo = 0;
       
  1470 	iProgress.iBytesDone = 0;
       
  1471 	iProgress.iErrorCode = KErrNone;
       
  1472 	}
       
  1473 
       
  1474 const TDesC8& CImImap4GetMail::ProgressL()
       
  1475 /** Gets information on the progress of the operation. 
       
  1476 
       
  1477 @return Packaged TImap4GenericProgress holding progress information. 
       
  1478 @see TImap4GenericProgress */
       
  1479 	{
       
  1480 	const TDesC8& opProgress = iMsvOperation->ProgressL();
       
  1481 
       
  1482 	if (opProgress.Length())
       
  1483 		{
       
  1484 		// need to get Sub operation progress and put this into iImap4SubStateProgress
       
  1485 		TImap4GenericProgress prog;	
       
  1486 		TPckgC<TImap4GenericProgress> paramPack(prog);
       
  1487 		paramPack.Set(opProgress);
       
  1488 		TImap4GenericProgress progress=paramPack();	
       
  1489 
       
  1490 		progress.iImap4SubStateProgress = progress.iState;
       
  1491 		switch(iCommand)
       
  1492 			{
       
  1493 			case KIMAP4MTMConnectAndCopyNewMailAndStayOnline:
       
  1494 			case KIMAP4MTMConnectAndCopyNewMailAndDisconnect:
       
  1495 				progress.iState = TImap4GenericProgress::ECopyNewMail;
       
  1496 				break;
       
  1497 			case KIMAP4MTMConnectAndMoveNewMailAndStayOnline:
       
  1498 			case KIMAP4MTMConnectAndMoveNewMailAndDisconnect:
       
  1499 				progress.iState = TImap4GenericProgress::EMoveNewMail;
       
  1500 				break;
       
  1501 			case KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline:
       
  1502 			case KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect:
       
  1503 				progress.iState = TImap4GenericProgress::ECopyMailSelection;
       
  1504 				break;
       
  1505 			case KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline:
       
  1506 			case KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect:
       
  1507 				progress.iState = TImap4GenericProgress::EMoveMailSelection;
       
  1508 				break;
       
  1509 			case KIMAP4MTMConnectAndCopyAllMailAndStayOnline:
       
  1510 			case KIMAP4MTMConnectAndCopyAllMailAndDisconnect:
       
  1511 				progress.iState = TImap4GenericProgress::ECopyAllMail;
       
  1512 				break;
       
  1513 			case KIMAP4MTMConnectAndMoveAllMailAndStayOnline:
       
  1514 			case KIMAP4MTMConnectAndMoveAllMailAndDisconnect:
       
  1515 				progress.iState = TImap4GenericProgress::EMoveAllMail;
       
  1516 				break;
       
  1517 			case KIMAP4MTMConnectAndPopulateNewMailAndStayOnline:
       
  1518 			case KIMAP4MTMConnectAndPopulateNewMailAndDisconnect:
       
  1519 				progress.iState = TImap4GenericProgress::EPopulateNewMail;
       
  1520 				break;
       
  1521 			case KIMAP4MTMConnectAndPopulateAllMailAndStayOnline:
       
  1522 			case KIMAP4MTMConnectAndPopulateAllMailAndDisconnect:
       
  1523 				progress.iState = TImap4GenericProgress::EPopulateAllMail;
       
  1524 				break;
       
  1525 			case KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline:
       
  1526 			case KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect:
       
  1527 				progress.iState = TImap4GenericProgress::EPopulateMailSelection;
       
  1528 				break;
       
  1529 			}
       
  1530 		iProgressBuf = progress;
       
  1531 		}
       
  1532 	return iProgressBuf;
       
  1533 	}
       
  1534 
       
  1535 void CImImap4GetMail::StoreProgressL()
       
  1536 	{
       
  1537 	const TDesC8& opProgress = iMsvOperation->ProgressL();
       
  1538 
       
  1539 	if (opProgress.Length())
       
  1540 		{
       
  1541 		TImap4GenericProgress prog;	
       
  1542 		TPckgC<TImap4GenericProgress> paramPack(prog);
       
  1543 		paramPack.Set(opProgress);
       
  1544 		TImap4GenericProgress progress=paramPack();	
       
  1545 
       
  1546 		iProgress.iMsgsToDo = progress.iMsgsToDo;
       
  1547 		iProgress.iBytesDone = progress.iBytesDone;
       
  1548 		iProgress.iState = progress.iState;
       
  1549 		iProgress.iImap4SubStateProgress = progress.iState;
       
  1550 		
       
  1551 		// only write the error code if no error has previously been set
       
  1552 		if ((iProgress.iErrorCode == KErrNone) && (iErrorProgress.iErrorCode == KErrNone))
       
  1553 			{
       
  1554 			if (iStatus.Int() != KErrNone)				
       
  1555 				iProgress.iErrorCode = iStatus.Int();
       
  1556 			else
       
  1557 				iProgress.iErrorCode = progress.iErrorCode;
       
  1558 			}
       
  1559 		}
       
  1560 	}
       
  1561 
       
  1562 void CImImap4GetMail::DoCancel()
       
  1563 	{
       
  1564 	iMsvOperation->Cancel();
       
  1565 	TRequestStatus* st = &iObserverRequestStatus;
       
  1566 	User::RequestComplete(st, KErrCancel);
       
  1567 	}
       
  1568 
       
  1569 CImImap4GetMail::CImImap4GetMail(CMsvSession& aMsvSession, CImap4ClientMtm& aImap4ClientMtm, TRequestStatus& aObserverRequestStatus)
       
  1570 	: CMsvOperation(aMsvSession, EPriorityStandard, aObserverRequestStatus),
       
  1571 	iImap4ClientMtm(aImap4ClientMtm)
       
  1572 	{
       
  1573 	}
       
  1574 
       
  1575 void CImImap4GetMail::ConstructL(TInt aFunctionId, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aImap4GetMailInfo)
       
  1576 	{
       
  1577 	iMsvEntrySelection = aMsvEntrySelection.CopyL();
       
  1578 	
       
  1579 	iImap4GetPartialMailInfo.Copy(aImap4GetMailInfo);
       
  1580 	iCommand = aFunctionId;
       
  1581 
       
  1582 	CActiveScheduler::Add(this);
       
  1583 	ResetProgress();
       
  1584 	iState = EConnectToMailbox;
       
  1585 	ChangeStateL();
       
  1586 	iObserverRequestStatus = KRequestPending;
       
  1587 	SetActive();
       
  1588 	}
       
  1589 
       
  1590 void CImImap4GetMail::Complete()
       
  1591 	{
       
  1592 	// complete the observer with error
       
  1593 	TRequestStatus* status=&iObserverRequestStatus;
       
  1594 	User::RequestComplete(status,KErrNone);
       
  1595 	}
       
  1596 
       
  1597 void CImImap4GetMail::SelectAndChangeToNextStateL()
       
  1598 	{
       
  1599 	SelectNextStateL();
       
  1600 	ChangeStateL();
       
  1601 	}
       
  1602 
       
  1603 void CImImap4GetMail::RunL()
       
  1604 	{
       
  1605 	TInt error = KErrNone;
       
  1606 	if (iState != EFinished)
       
  1607 		{
       
  1608 		// store progress if connecting, copying/moving new/all/selected messages.
       
  1609 		if ((iState == EConnectToMailbox) || (iState == ECopyNewMessages) ||
       
  1610 			(iState == ECopyAllMessages) ||	(iState == ECopyMessageSelection) ||
       
  1611 			(iState == EMoveNewMessages) || (iState == EMoveAllMessages) ||
       
  1612 			(iState == EMoveMessageSelection) || (iState == EPopulateNewMessages) || 
       
  1613 			(iState == EPopulateAllMessages) ||	(iState == EPopulateMessageSelection))
       
  1614 			StoreProgressL();
       
  1615 		if (iProgress.iErrorCode != KErrNone)
       
  1616 			{
       
  1617 			// There has been an error in the previous operation - remember the error.
       
  1618 			iErrorProgress.iMsgsToDo = iProgress.iMsgsToDo;
       
  1619 			iErrorProgress.iMsgsDone = iProgress.iMsgsDone;
       
  1620 			iErrorProgress.iErrorCode = iProgress.iErrorCode;
       
  1621 
       
  1622 			// reset progress error code
       
  1623 			iProgress.iErrorCode = KErrNone;
       
  1624 
       
  1625 			// update the state that the error occured.
       
  1626 			switch (iState)
       
  1627 				{
       
  1628 				case EConnectToMailbox:
       
  1629 					iErrorProgress.iImap4SubStateProgress = TImap4GenericProgress::EConnecting;
       
  1630 					Complete();
       
  1631 					return;
       
  1632 				case ECopyNewMessages:
       
  1633 				case ECopyAllMessages:
       
  1634 				case ECopyMessageSelection:
       
  1635 					iErrorProgress.iImap4SubStateProgress = TImap4GenericProgress::ECopying;
       
  1636 					// The next state is disconnect so continue!
       
  1637 					break;
       
  1638 				case EMoveNewMessages:
       
  1639 				case EMoveAllMessages:
       
  1640 				case EMoveMessageSelection:
       
  1641 					iErrorProgress.iImap4SubStateProgress = TImap4GenericProgress::EMoving;
       
  1642 					// The next state is disconnect so continue!
       
  1643 					break;
       
  1644 				case EPopulateNewMessages:
       
  1645 				case EPopulateAllMessages:
       
  1646 				case EPopulateMessageSelection:
       
  1647 					iErrorProgress.iImap4SubStateProgress = TImap4GenericProgress::EFetching;
       
  1648 					// The next state is disconnect so continue!
       
  1649 					break;
       
  1650 				case EDisconnectFromMailbox:
       
  1651 					iErrorProgress.iImap4SubStateProgress = TImap4GenericProgress::EDisconnecting;
       
  1652 					Complete();
       
  1653 					return;
       
  1654 				default:
       
  1655 					Complete();
       
  1656 					return;
       
  1657 				}
       
  1658 			}
       
  1659 		TRAP(error, SelectAndChangeToNextStateL());
       
  1660 		if ((error == KErrNone) && (iState != EFinished))
       
  1661 			SetActive();
       
  1662 		else if (error != KErrNone)
       
  1663 			{
       
  1664 			// if iState == EFinished, then we don't need to complete - done previously
       
  1665 			TRequestStatus* st = &iObserverRequestStatus;
       
  1666 			User::RequestComplete(st, error);
       
  1667 			}
       
  1668 		}
       
  1669 	}
       
  1670 
       
  1671 void CImImap4GetMail::SelectNextStateL()
       
  1672 	{
       
  1673 	switch (iState)
       
  1674 		{
       
  1675 		case EConnectToMailbox:
       
  1676 			if (iProgress.iErrorCode == KErrNone)
       
  1677 				{
       
  1678 				switch(iCommand)
       
  1679 					{
       
  1680 					case KIMAP4MTMConnectAndCopyNewMailAndStayOnline:
       
  1681 					case KIMAP4MTMConnectAndCopyNewMailAndDisconnect:
       
  1682 						iState = ECopyNewMessages;
       
  1683 						break;
       
  1684 					case KIMAP4MTMConnectAndMoveNewMailAndStayOnline:
       
  1685 					case KIMAP4MTMConnectAndMoveNewMailAndDisconnect:
       
  1686 						iState = EMoveNewMessages;
       
  1687 						break;
       
  1688 					case KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline:
       
  1689 					case KIMAP4MTMConnectAndCopyMailSelectionAndDisconnect:
       
  1690 						iState = ECopyMessageSelection;
       
  1691 						break;
       
  1692 					case KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline:
       
  1693 					case KIMAP4MTMConnectAndMoveMailSelectionAndDisconnect:
       
  1694 						iState = EMoveMessageSelection;
       
  1695 						break;
       
  1696 					case KIMAP4MTMConnectAndCopyAllMailAndStayOnline:
       
  1697 					case KIMAP4MTMConnectAndCopyAllMailAndDisconnect:
       
  1698 						iState = ECopyAllMessages;
       
  1699 						break;
       
  1700 					case KIMAP4MTMConnectAndMoveAllMailAndStayOnline:
       
  1701 					case KIMAP4MTMConnectAndMoveAllMailAndDisconnect:
       
  1702 						iState = EMoveAllMessages;
       
  1703 						break;
       
  1704 					case KIMAP4MTMConnectAndPopulateNewMailAndStayOnline:
       
  1705 					case KIMAP4MTMConnectAndPopulateNewMailAndDisconnect:
       
  1706 						iState = EPopulateNewMessages;
       
  1707 						break;
       
  1708 					case KIMAP4MTMConnectAndPopulateAllMailAndStayOnline:
       
  1709 					case KIMAP4MTMConnectAndPopulateAllMailAndDisconnect:
       
  1710 						iState = EPopulateAllMessages;
       
  1711 						break;
       
  1712 					case KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline:
       
  1713 					case KIMAP4MTMConnectAndPopulateMailSelectionAndDisconnect:
       
  1714 						iState = EPopulateMessageSelection;
       
  1715 						break;
       
  1716 					}
       
  1717 				}
       
  1718 			else 
       
  1719 				iState = EDisconnectFromMailbox;
       
  1720 			break;
       
  1721 		case ECopyNewMessages:
       
  1722 		case ECopyAllMessages:
       
  1723 		case ECopyMessageSelection:
       
  1724 		case EMoveNewMessages:
       
  1725 		case EMoveAllMessages:
       
  1726 		case EMoveMessageSelection:
       
  1727 		case EPopulateNewMessages:
       
  1728 		case EPopulateAllMessages:
       
  1729 		case EPopulateMessageSelection:
       
  1730 			if ((iCommand == KIMAP4MTMConnectAndCopyNewMailAndStayOnline) ||
       
  1731 				(iCommand == KIMAP4MTMConnectAndCopyAllMailAndStayOnline) ||
       
  1732 				(iCommand == KIMAP4MTMConnectAndCopyMailSelectionAndStayOnline) ||
       
  1733 				(iCommand == KIMAP4MTMConnectAndMoveNewMailAndStayOnline) ||
       
  1734 				(iCommand == KIMAP4MTMConnectAndMoveAllMailAndStayOnline) ||
       
  1735 				(iCommand == KIMAP4MTMConnectAndMoveMailSelectionAndStayOnline) ||
       
  1736 				(iCommand == KIMAP4MTMConnectAndPopulateNewMailAndStayOnline) ||
       
  1737 				(iCommand == KIMAP4MTMConnectAndPopulateAllMailAndStayOnline) ||
       
  1738 				(iCommand == KIMAP4MTMConnectAndPopulateMailSelectionAndStayOnline))
       
  1739 				{
       
  1740 				iState = EFinished;
       
  1741 				}
       
  1742 			else
       
  1743 				iState = EDisconnectFromMailbox;
       
  1744 			break;
       
  1745 		case EDisconnectFromMailbox:
       
  1746 			iState = EFinished;
       
  1747 			break;
       
  1748 		default:
       
  1749 			User::LeaveIfError(KErrNotSupported);
       
  1750 			break;
       
  1751 		}
       
  1752 	}
       
  1753 
       
  1754 void CImImap4GetMail::ChangeStateL()
       
  1755 	{
       
  1756 	switch (iState)
       
  1757 		{
       
  1758 		case EConnectToMailbox:
       
  1759 			ConnectToMailboxL();
       
  1760 			break;
       
  1761 		case ECopyNewMessages:
       
  1762 			CopyMoveNewMessagesL(ETrue);
       
  1763 			break;
       
  1764 		case EMoveNewMessages:
       
  1765 			CopyMoveNewMessagesL(EFalse);
       
  1766 			break;
       
  1767 		case ECopyMessageSelection:
       
  1768 			CopyMoveMessageSelectionL(ETrue);
       
  1769 			break;
       
  1770 		case EMoveMessageSelection:
       
  1771 			CopyMoveMessageSelectionL(EFalse);
       
  1772 			break;
       
  1773 		case ECopyAllMessages:
       
  1774 			CopyMoveAllMessagesL(ETrue);
       
  1775 			break;
       
  1776 		case EMoveAllMessages:
       
  1777 			CopyMoveAllMessagesL(EFalse);
       
  1778 			break;
       
  1779 		case EPopulateNewMessages:
       
  1780 			PopulateNewMessagesL();
       
  1781 			break;
       
  1782 		case EPopulateAllMessages:
       
  1783 			PopulateAllMessagesL();
       
  1784 			break;
       
  1785 		case EPopulateMessageSelection:
       
  1786 			PopulateMessageSelectionL();
       
  1787 			break;
       
  1788 		case EDisconnectFromMailbox:
       
  1789 			DisconnectFromMailboxL();
       
  1790 			break;
       
  1791 		case EFinished:
       
  1792 			{
       
  1793 			TRequestStatus* status=&iObserverRequestStatus;
       
  1794 			User::RequestComplete(status,KErrNone);
       
  1795 			}
       
  1796 		}
       
  1797 	}
       
  1798 
       
  1799 void CImImap4GetMail::RequestComplete(TInt aError)
       
  1800 	{
       
  1801 	iStatus = KRequestPending;
       
  1802 	TRequestStatus* status=&iStatus;
       
  1803 	User::RequestComplete(status,aError);
       
  1804 	}
       
  1805 
       
  1806 void CImImap4GetMail::ConnectToMailboxL()
       
  1807 	{
       
  1808 	ResetProgress();
       
  1809 	iProgress.iImap4SubStateProgress = TImap4GenericProgress::EConnecting;
       
  1810 	delete iMsvOperation;
       
  1811 	iMsvOperation=NULL;
       
  1812 	iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMConnect, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1813 	}
       
  1814 
       
  1815 void CImImap4GetMail::CopyMoveNewMessagesL(TBool aCopy)
       
  1816 	{
       
  1817 	ResetProgress();
       
  1818 	delete iMsvOperation;
       
  1819 	iMsvOperation=NULL;
       
  1820 	if (aCopy)
       
  1821 		{
       
  1822 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::ECopying;
       
  1823 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMCopyNewMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1824 		}
       
  1825 	else
       
  1826 		{
       
  1827 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::EMoving;
       
  1828 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMMoveNewMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1829 		}
       
  1830 	}
       
  1831 
       
  1832 void CImImap4GetMail::CopyMoveMessageSelectionL(TBool aCopy)
       
  1833 	{
       
  1834 	ResetProgress();
       
  1835 	delete iMsvOperation;
       
  1836 	iMsvOperation=NULL;
       
  1837 	if (aCopy)
       
  1838 		{
       
  1839 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::ECopying;
       
  1840 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMCopyMailSelectionWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1841 		}
       
  1842 	else
       
  1843 		{
       
  1844 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::EMoving;
       
  1845 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMMoveMailSelectionWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1846 		}
       
  1847 	}
       
  1848 
       
  1849 void CImImap4GetMail::CopyMoveAllMessagesL(TBool aCopy)
       
  1850 	{
       
  1851 	ResetProgress();
       
  1852 	delete iMsvOperation;
       
  1853 	iMsvOperation=NULL;
       
  1854 	if (aCopy)
       
  1855 		{
       
  1856 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::ECopying;
       
  1857 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMCopyAllMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1858 		}
       
  1859 	else
       
  1860 		{
       
  1861 		iProgress.iImap4SubStateProgress = TImap4GenericProgress::EMoving;
       
  1862 		iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMMoveAllMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1863 		}
       
  1864 	}
       
  1865 
       
  1866 void CImImap4GetMail::PopulateNewMessagesL()
       
  1867 	{
       
  1868 	ResetProgress();
       
  1869 	delete iMsvOperation;
       
  1870 	iMsvOperation=NULL;
       
  1871 	iProgress.iImap4SubStateProgress = TImap4GenericProgress::EFetching;
       
  1872 	iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMPopulateNewMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1873 	}
       
  1874 
       
  1875 void CImImap4GetMail::PopulateAllMessagesL()
       
  1876 	{
       
  1877 	ResetProgress();
       
  1878 	delete iMsvOperation;
       
  1879 	iMsvOperation=NULL;
       
  1880 	iProgress.iImap4SubStateProgress = TImap4GenericProgress::EFetching;
       
  1881 	iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMPopulateAllMailWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1882 	}
       
  1883 
       
  1884 void CImImap4GetMail::PopulateMessageSelectionL()
       
  1885 	{
       
  1886 	ResetProgress();
       
  1887 	delete iMsvOperation;
       
  1888 	iMsvOperation=NULL;
       
  1889 	iProgress.iImap4SubStateProgress = TImap4GenericProgress::EFetching;
       
  1890 	iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1891 	}
       
  1892 
       
  1893 void CImImap4GetMail::DisconnectFromMailboxL()
       
  1894 	{
       
  1895 	//don't reset progress so that no. of messages copied are still remembered
       
  1896 	iProgress.iImap4SubStateProgress = TImap4GenericProgress::EDisconnecting;
       
  1897 	delete iMsvOperation;
       
  1898 	iMsvOperation=NULL;
       
  1899 	iMsvOperation=iImap4ClientMtm.InvokeAsyncFunctionL(KIMAP4MTMDisconnect, *iMsvEntrySelection, iImap4GetPartialMailInfo, iStatus);
       
  1900 	}
       
  1901