email/pop3andsmtpmtm/clientmtms/src/POPCMTM.CPP
changeset 0 72b543305e3a
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 // Client MTM for the POP3 protocol
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <bautils.h>	// BaflUtils
       
    19 #include <mtmdef.h>		//KUidMtmQueryxxx & TMsvPartList flags
       
    20 
       
    21 #include <barsc.h>		//RResourceFile
       
    22 #include <barsread.h>
       
    23 #include <msvftext.h>
       
    24 #include <cemailaccounts.h>
       
    25 
       
    26 #include "POPCMTM.H"
       
    27 #include "POP3SET.H"		//CImPop3Settings
       
    28 #include <imcm.rsg>
       
    29 #include "MIUT_ERR.H"
       
    30 #include "IMCMMAIN.H"
       
    31 #include "IMCMUTIL.H"
       
    32 #include <autosend.h>
       
    33 #include <msvenhancesearchsortutil.h>
       
    34 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    35 #include <mtmuidsdef.hrh>
       
    36 #include "miut_errconsts.h"
       
    37 #include "cimmessagepart.h"
       
    38 #endif
       
    39 
       
    40 #if defined (_UNICODE)
       
    41 	#define KUidMsgInternetMailEditorDLL	0x10003C53  // (268450899)
       
    42 #else
       
    43 	#define KUidMsgInternetMailEditorDLL	0x100011AC  // (268439980)
       
    44 #endif
       
    45 
       
    46 _LIT(KMsvAutoSendExe, "Autosend.exe");
       
    47 const TUid KMsvAutoSendExeUid = {0x1000A402}; //268477442
       
    48 
       
    49 /**
       
    50 @internalTechnology 
       
    51 */
       
    52 
       
    53 EXPORT_C CPop3ClientMtm* CPop3ClientMtm::NewL(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aMsvSession)
       
    54 	{
       
    55 	CPop3ClientMtm* self = new(ELeave) CPop3ClientMtm(aRegisteredMtmDll, aMsvSession);
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL();
       
    58 	CleanupStack::Pop();
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 CPop3ClientMtm::CPop3ClientMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aMsvSession)
       
    63 : CBaseMtm(aRegisteredMtmDll, aMsvSession)
       
    64 	{
       
    65 	__DECLARE_NAME(_S("CPop3ClientMtm"));
       
    66 	}
       
    67 
       
    68 void CPop3ClientMtm::ConstructL()
       
    69 	{
       
    70 	iImPop3Settings = new (ELeave) CImPop3Settings;
       
    71 	iHeader = CImHeader::NewLC();
       
    72 	CleanupStack::Pop();	// iHeader
       
    73 	
       
    74 	//open the resource file
       
    75 	RResourceFile resourceFile;
       
    76 	OpenResourceFileL(resourceFile, Session().FileSession());
       
    77 	CleanupClosePushL(resourceFile);
       
    78 
       
    79 	HBufC8* buf = resourceFile.AllocReadLC(EMAIL_ADDRESS_FORMATTING_STRING);
       
    80 	TResourceReader reader;
       
    81 	reader.SetBuffer(buf);
       
    82 	iEmailAddressFormatString = (reader.ReadTPtrC()).AllocL();
       
    83 	CleanupStack::PopAndDestroy(2); // resourceFile (Close resourceFile), buf
       
    84 	}
       
    85 
       
    86 CPop3ClientMtm::~CPop3ClientMtm()
       
    87 /** Destructor. */
       
    88 	{
       
    89 	delete iEmailAddressFormatString;
       
    90 	delete iImPop3Settings;
       
    91 	delete iImPOP3GetMail;
       
    92 	delete iHeader;
       
    93 	}
       
    94 
       
    95 void CPop3ClientMtm::SaveMessageL()
       
    96 /** Client MTM base class function, with an empty implementation. */
       
    97 	{
       
    98 	}
       
    99 
       
   100 void CPop3ClientMtm::LoadMessageL()
       
   101 /** Loads the cache with the message data for the current context. */
       
   102 	{
       
   103 	Body().Reset();
       
   104 	iHeader->Reset();
       
   105 	switch (iMsvEntry->Entry().iType.iUid)
       
   106 		{
       
   107 		case KUidMsvServiceEntryValue:
       
   108 			RestoreSettingsL();
       
   109 			break;
       
   110 		case KUidMsvMessageEntryValue:
       
   111 			{//restore header
       
   112 			if (!iMsvEntry->HasStoreL())
       
   113 				return;
       
   114 			
       
   115 		// Get a reference to TMsvEnhanceSearchSortUtil  instance set by CMsvSearchsortOpOnHeaderBody class
       
   116 		// If advanced search and sort is being performed than do not load the message header and body.
       
   117 		// These are loaded when the search criteria is known in FindL()
       
   118 		// For API's other than CMsvSearchsortOpOnHeaderBody-> FindInHeaderBodyL(), a call to LoadMessageL()
       
   119 		// loads the body and the header.
       
   120 				
       
   121 			TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   122 			if ( searchsortutil == NULL )
       
   123 				{
       
   124 				// Load message Body
       
   125 				CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   126 				CleanupStack::PushL(msvStore);
       
   127 			
       
   128 		   		if (! msvStore->IsPresentL(KUidMsgFileIMailHeader) )
       
   129 		    		{
       
   130 		    		CleanupStack::PopAndDestroy(); //store
       
   131 		    		return;
       
   132 		    		}
       
   133 
       
   134 				//Restore the header
       
   135 				iHeader->RestoreL(*msvStore);
       
   136 				CleanupStack::PopAndDestroy();//store
       
   137 				CImEmailMessage* message=CImEmailMessage::NewLC(*iMsvEntry);
       
   138 				message->GetBodyTextL(iMsvEntry->Entry().Id(),CImEmailMessage::EThisMessageOnly,Body(),*iParaFormatLayer,*iCharFormatLayer);
       
   139 				CleanupStack::PopAndDestroy();//message	
       
   140 				break;
       
   141 				
       
   142 				}
       
   143 			}
       
   144 		};
       
   145 	}
       
   146 
       
   147 EXPORT_C void CPop3ClientMtm::StoreSettingsL()
       
   148 /** Stores the current service settings from the object's cache in to the Central 
       
   149 Repository for the current entry.
       
   150 
       
   151 The current entry must be a service. */
       
   152 	{
       
   153 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EPopcMTMNoCMsvEntrySet));
       
   154 	
       
   155 	// check that current context is a service entry - Assuming that StoreL() is ONLY used to write to Service Entry. True?!
       
   156 	__ASSERT_DEBUG(iMsvEntry->Entry().iType==KUidMsvServiceEntry,gPanic(EPopcMTMNotAServiceEntry));
       
   157 
       
   158 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   159 	TPopAccount id;
       
   160 	account->GetPopAccountL(iMsvEntry->Entry().Id(), id);
       
   161 	account->SavePopSettingsL(id, *iImPop3Settings);
       
   162 	CleanupStack::PopAndDestroy(account);    
       
   163 	}
       
   164 
       
   165 EXPORT_C void CPop3ClientMtm::RestoreSettingsL()
       
   166 /** Loads into the object's cache the service settings from the Central Repository for
       
   167 the current entry.
       
   168 
       
   169 The current entry must be a service. */
       
   170 	{
       
   171 	if (iMsvEntry->Entry().iType==KUidMsvServiceEntry)
       
   172 		{
       
   173 		CEmailAccounts* account = CEmailAccounts::NewLC();
       
   174 		TPopAccount id;
       
   175 		account->GetPopAccountL(iMsvEntry->Entry().Id(), id);
       
   176 		account->LoadPopSettingsL(id, *iImPop3Settings);
       
   177 		CleanupStack::PopAndDestroy(account);    
       
   178 		}
       
   179 	}
       
   180 
       
   181 void CPop3ClientMtm::SendOnNextConnectionL()
       
   182 	{
       
   183 	TMsvId smtpServiceId = KMsvNullIndexEntryId;
       
   184 	TMsvId entry = iMsvEntry->Entry().Id();
       
   185 	if (iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue)
       
   186 		smtpServiceId = iMsvEntry->Entry().iRelatedId;
       
   187 	else if (iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue)
       
   188 		{
       
   189 		TMsvId id=iMsvEntry->Entry().iServiceId;
       
   190 		iMsvEntry->SetEntryL(iMsvEntry->Entry().iServiceId);		
       
   191 		smtpServiceId = iMsvEntry->Entry().iRelatedId;
       
   192 		iMsvEntry->SetEntryL(id);		
       
   193 		}
       
   194 
       
   195 	iMsvEntry->SetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   196 	CMsvEntrySelection* sel = iMsvEntry->ChildrenWithMtmL(KUidMsgTypeSMTP);
       
   197 	CleanupStack::PushL(sel);
       
   198 
       
   199 	// there is no need to start the autosend operation if there are no SMTP messages
       
   200 	// in the outbox
       
   201 
       
   202 	if(sel->Count())
       
   203 		{
       
   204 		TBuf<20> cmdString;
       
   205 		cmdString.Num(smtpServiceId, EDecimal);
       
   206 			RProcess p;
       
   207 			TInt error=p.Create(KMsvAutoSendExe, cmdString, TUidType(KNullUid, KNullUid, KMsvAutoSendExeUid));
       
   208 			if (error==KErrNone)
       
   209 				{
       
   210 				p.Resume();
       
   211 				p.Close();
       
   212 				}
       
   213 		}
       
   214 	CleanupStack::PopAndDestroy(sel);
       
   215 	iMsvEntry->SetEntryL(entry);
       
   216 	}
       
   217 
       
   218 CMsvOperation* CPop3ClientMtm::ReplyL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   219 /** Creates a reply message to the current message context.
       
   220 
       
   221 The reply is an SMTP message.
       
   222 
       
   223 @return	If successful, this is an asynchronously completing reply operation. 
       
   224 If failed, this is a completed operation, with status set to the relevant error code. 
       
   225 @param aDestination The entry to which to assign the reply 
       
   226 @param aPartList Defines the parts that are to be copied from the original message into the reply
       
   227 @param aCompletionStatus The request status to be completed when the operation has finished 
       
   228 */
       
   229 	{
       
   230 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   231 	TUid messageType = KUidMsgTypeSMTP;
       
   232 	return iImEmailOperation->CreateReplyL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   233 	}
       
   234 
       
   235 CMsvOperation* CPop3ClientMtm::ForwardL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   236 /** Creates a forwarded message from the current message context.
       
   237 
       
   238 The forwarded message is an SMTP message.
       
   239 
       
   240 @return	If successful, this is an asynchronously completing forward message operation. 
       
   241 If failed, this is a completed operation, with status set to the relevant error code. 
       
   242 @param aDestination The entry to which to assign the forwarded message  
       
   243 @param aPartList Defines the parts that are to be copied from the original message into the forwarded message 
       
   244 @param aCompletionStatus The request status to be completed when the operation has finished 
       
   245 */
       
   246 	{
       
   247 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   248 	TUid messageType = KUidMsgTypeSMTP;
       
   249 	return iImEmailOperation->CreateForwardL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   250 	}
       
   251 
       
   252 TUint CPop3ClientMtm::ValidateMessage(TMsvPartList /*aPartList*/)
       
   253 	/** Client MTM base class function, with an empty implementation.
       
   254 	
       
   255 	@param aPartList Unused
       
   256 	@return Unused */
       
   257 	{
       
   258 	return KMsvMessagePartRecipient;
       
   259 	}
       
   260 
       
   261 TBool CPop3ClientMtm::ValidateAddress(const TPtrC& anAddress)
       
   262 	{
       
   263 	return iTImMessageField.ValidInternetEmailAddress(anAddress);
       
   264 	}
       
   265 
       
   266 TMsvPartList CPop3ClientMtm::DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   267    	{
       
   268    	CImClientMTMUtils* clientMTMUtils = CImClientMTMUtils::NewL();
       
   269    	CleanupStack::PushL(clientMTMUtils);
       
   270    
       
   271    	TMsvPartList retList = KMsvMessagePartNone;
       
   272     
       
   273  	// For POP3 mail we need to search the entry as well as the header. This is because the header stream might not be present.
       
   274  	CMsvFindText* findText = CMsvFindText::NewLC();
       
   275   
       
   276   	// Get a reference to TMsvEnhanceSearchSortUtil instance set by CMsvSearchsortOpOnHeaderBody class
       
   277 	
       
   278  	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   279  	
       
   280  	// searchsortuitl variable will not be NULL for Advanced Search and Sort called from CMsvSearchsortOpOnHeaderBody
       
   281  	// For the old implementation, it will be NULL
       
   282   	if( searchsortutil != NULL )
       
   283  		{
       
   284  		// Get the searchsort setting flags
       
   285  		TInt32 searchsortsetting=searchsortutil->GetSearchSortSetting();
       
   286  		
       
   287  		// The body was not loaded in LoadMessageL()
       
   288  		// If 2 search query options are on the body or on the header, than it sets EMessagePartBodyLoaded flag
       
   289  		// of searchsortsetting
       
   290  		if(aPartList & KMsvMessagePartBody && !(searchsortsetting & EMessagePartBodyLoaded))  	
       
   291    			{
       
   292    			// Restore Body
       
   293    			CImEmailMessage* message=CImEmailMessage::NewLC(*iMsvEntry);
       
   294 			message->GetBodyTextL(iMsvEntry->Entry().Id(),CImEmailMessage::EThisMessageOnly,Body(),*iParaFormatLayer,*iCharFormatLayer);
       
   295 			CleanupStack::PopAndDestroy();//message
       
   296 			searchsortutil->SetSearchSortSetting(EMessagePartBodyLoaded);
       
   297    			}
       
   298    		else if(!(searchsortsetting & EMessagePartHeaderLoaded))
       
   299    			{
       
   300  			// Restore header
       
   301 			CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   302   			CleanupStack::PushL(msvStore);
       
   303 			
       
   304 		   	if (! msvStore->IsPresentL(KUidMsgFileIMailHeader) )
       
   305 		    	{
       
   306 		    	CleanupStack::PopAndDestroy(); //store
       
   307 		    	return 0;
       
   308 		    	}
       
   309 
       
   310 			iHeader->RestoreL(*msvStore);
       
   311 			CleanupStack::PopAndDestroy();//store
       
   312 			searchsortutil->SetSearchSortSetting(EMessagePartHeaderLoaded);
       
   313 			}
       
   314    		
       
   315    		// Issue the find request
       
   316    		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);
       
   317    		
       
   318    		/* If the search didn't succeed, than search in the details field of TMsvEntry class. It holds the From field
       
   319 		   If the search is on subject, than look in description field of TMsvEntry class.	*/
       
   320    		if(!retList)
       
   321  			{
       
   322  			if (aPartList & KMsvMessagePartFrom)
       
   323  				{
       
   324  				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDetails, aPartList) ? retList|=KMsvMessagePartOriginator : retList;
       
   325  				}
       
   326 	 		if (aPartList & KMsvMessagePartSubject)
       
   327 	 			{
       
   328 		 		findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDescription, aPartList) ? retList|=KMsvMessagePartDescription : retList;
       
   329 		 		}
       
   330  			}
       
   331  			
       
   332  		/* Copy the sort data if sorting is specified.
       
   333 		 The operations being performed could be only be sort or it could be search and sort
       
   334 		 If the operation is search and sort than copy the sort data only if the
       
   335 		 search operation succeeded	*/   		
       
   336    		if ((searchsortsetting & EMessagePartSort ) || (((searchsortsetting & EMessagePartSearchSort) && (searchsortsetting & EMessagePartLastQueryOption) && (retList))))
       
   337    			{
       
   338    			/* Copy the data to be sorted from the header stream.
       
   339    			   This done by setting iExtensionData to point to the field being copied */
       
   340 	   		if (iHeader)
       
   341    				{
       
   342    				if (searchsortsetting & EMessagePartToSort )
       
   343    					{
       
   344 	   				SetExtensionData((TAny*)&iHeader->ToRecipients()); 
       
   345    					}
       
   346    				else if(searchsortsetting & EMessagePartCcSort)
       
   347    					{
       
   348 	   				SetExtensionData((TAny*)&iHeader->CcRecipients());
       
   349    					}
       
   350  	  			else if(searchsortsetting & EMessagePartBccSort)
       
   351     				{
       
   352     				SetExtensionData((TAny*)&iHeader->BccRecipients());
       
   353     				}
       
   354 	    		else if(searchsortsetting & EMessagePartFromSort)
       
   355     				{
       
   356     				SetExtensionData((TAny*)(iHeader->From().Ptr()));
       
   357     				}
       
   358 				else if(searchsortsetting & EMessagePartSubjectSort)
       
   359 					{
       
   360 					SetExtensionData((TAny*)(iHeader->Subject().Ptr()));	
       
   361 					}
       
   362     			}
       
   363    			else  // Header not present only originator and description is available 
       
   364    	   			{ 
       
   365    		    	if(searchsortsetting & EMessagePartFromSort)
       
   366    		    		{
       
   367    		    		SetExtensionData((TAny*)&iMsvEntry->Entry().iDetails);
       
   368    		    		}
       
   369  				else if(searchsortsetting & EMessagePartSubjectSort)
       
   370  					{
       
   371  					SetExtensionData((TAny*)&iMsvEntry->Entry().iDescription);		
       
   372  					}
       
   373   				}
       
   374    			}
       
   375    		
       
   376    		}
       
   377    	else // Old implementation for search
       
   378    		{
       
   379 
       
   380 		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);
       
   381    		if(!retList)
       
   382  			{
       
   383  			if (aPartList & KMsvMessagePartOriginator)
       
   384  				{
       
   385  				findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDetails, aPartList) ? retList|=KMsvMessagePartOriginator : retList;
       
   386  				}
       
   387 	 		if (aPartList & KMsvMessagePartDescription)
       
   388 	 			{
       
   389 		 		findText->FindTextL(aTextToFind, iMsvEntry->Entry().iDescription, aPartList) ? retList|=KMsvMessagePartDescription : retList;
       
   390 		 		}
       
   391  			}
       
   392  		
       
   393    		}
       
   394 	CleanupStack::PopAndDestroy(findText);
       
   395 	CleanupStack::PopAndDestroy(); //clientMTMUtils
       
   396 
       
   397   	return retList;
       
   398  	}
       
   399  
       
   400 TMsvPartList CPop3ClientMtm::Find(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   401 /** Searches the specified message part(s) for the plain-text version of the text 
       
   402 to be found.
       
   403 
       
   404 @param aTextToFind The plain-text version of the text to be found. 
       
   405 @param aPartList Indicates the message parts which should be searched. 
       
   406 @return If the text was not found, or searching is unsupported, 0. If the text 
       
   407 was found, a bitmask of the TMsvPartList IDs for each part in which the text 
       
   408 was present. */
       
   409  	{
       
   410  	TMsvPartList retList = KMsvMessagePartNone;
       
   411  	TRAPD(ret, retList = DoFindL(aTextToFind, aPartList));
       
   412    	return retList;
       
   413    	}
       
   414 
       
   415 void CPop3ClientMtm::AddAddresseeL(const TDesC& aRealAddress)
       
   416 /** Adds an addressee for the current context.
       
   417 
       
   418 @param aRealAddress String representing an address to be added to the list 
       
   419 for the current message */
       
   420 	{
       
   421 	iAddresseeList->AppendL(aRealAddress);
       
   422 	}
       
   423 
       
   424 void CPop3ClientMtm::AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias)
       
   425 /** Adds an addressee with an alias for the current context.
       
   426 
       
   427 @param aRealAddress String representing an address to be added to the list 
       
   428 for the current message 
       
   429 @param aAlias Alias information */
       
   430 	{
       
   431 	HBufC* emailAddress = HBufC::NewLC(aRealAddress.Length()+aAlias.Length()+iEmailAddressFormatString->Length()-4);
       
   432 	emailAddress->Des().Format(*iEmailAddressFormatString,&aAlias,&aRealAddress);
       
   433 	iAddresseeList->AppendL(aRealAddress);
       
   434 	CleanupStack::PopAndDestroy();	// emailAddress
       
   435 	}
       
   436 
       
   437 void CPop3ClientMtm::RemoveAddressee(TInt aIndex)
       
   438 /** Removes an address from the current address list.
       
   439 
       
   440 @param aIndex Index of address to be removed */
       
   441 	{
       
   442 	if (iAddresseeList->Count() > aIndex)
       
   443 		iAddresseeList->Delete(aIndex);
       
   444 	}
       
   445 
       
   446 void CPop3ClientMtm::ContextEntrySwitched()
       
   447 	{
       
   448 	iImPop3Settings->Reset();
       
   449 	iHeader->Reset();
       
   450 	Body().Reset();	
       
   451 	}
       
   452 
       
   453 TInt CPop3ClientMtm::QueryCapability(TUid aCapability, TInt& aResponse)
       
   454 /** Queries if the MTM supports a particular capability, specified by a UID.
       
   455 
       
   456 @param aCapability UID of capability to be queried 
       
   457 @param aResponse Response value. The format of the response varies according 
       
   458 to the capability. 
       
   459 @return KErrNone: aCapability is a recognised value and a response is returned 
       
   460 KErrNotSupported: aCapability is not a recognised value */
       
   461 	{
       
   462 	TInt error = KErrNone;
       
   463 	// Supported
       
   464 	switch (aCapability.iUid)
       
   465 		{
       
   466 	case KUidMtmQueryMaxBodySizeValue:
       
   467 	case KUidMtmQueryMaxTotalMsgSizeValue:
       
   468 		aResponse = KMaxTInt;
       
   469 		break;
       
   470 	case KUidMsvMtmQueryEditorUidValue:
       
   471 		aResponse = KUidMsgInternetMailEditorDLL;
       
   472 		break;
       
   473 	case KUidMtmQuerySupportedBodyValue:
       
   474 		aResponse = KMtm7BitBody + KMtm8BitBody + KMtm16BitBody + KMtmBinaryBody;
       
   475 		break;
       
   476 	case KUidMtmQuerySupportAttachmentsValue:
       
   477 	case KUidMtmQueryCanReceiveMsgValue:		
       
   478 		break;
       
   479 	// All others - Not Supported:
       
   480 	default:
       
   481 		error = KErrNotSupported;
       
   482 		}
       
   483 	return error;
       
   484 	}
       
   485 
       
   486 EXPORT_C void CPop3ClientMtm::SetSettingsL(const CImPop3Settings& aSettings)
       
   487 /** Copies the specified service settings to the cached service settings.
       
   488 
       
   489 @param aSettings New service settings */
       
   490 	{
       
   491 	iImPop3Settings->CopyL(aSettings);
       
   492 	}
       
   493 
       
   494 EXPORT_C const CImPop3Settings& CPop3ClientMtm::Settings() const
       
   495 /** Gets the current cached service settings.
       
   496 
       
   497 @return The current cached service settings */
       
   498 	{
       
   499 	return *iImPop3Settings;
       
   500 	}
       
   501 
       
   502 void CPop3ClientMtm::InvokeSyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter)
       
   503 /** Invokes synchronous POP3-specific operations.
       
   504 
       
   505 @param aFunctionId ID of the requested operation. The only supported operation 
       
   506 is KPOP3MTMIsConnected.
       
   507 @param aSelection Selection of message entries. This is used if the operation 
       
   508 requires message entries to work on. 
       
   509 @param aParameter Buffer containing input and output parameters. The format 
       
   510 of this is specific to the operation. */
       
   511 	{
       
   512 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EPopcMTMNoCMsvEntrySet));
       
   513 
       
   514 	TInt error = KErrNone;
       
   515 	switch (aFunctionId)
       
   516 		{
       
   517 		case KPOP3MTMIsConnected:
       
   518 			{
       
   519 			CMsvOperationActiveSchedulerWait* synchOperation;
       
   520 			synchOperation=CMsvOperationActiveSchedulerWait::NewLC();
       
   521 			CMsvOperation* operation = Session().TransferCommandL(aSelection, KPOP3MTMIsConnected, aParameter, synchOperation->iStatus);
       
   522 			synchOperation->Start();
       
   523 			CleanupStack::PushL(operation);
       
   524 			error = operation->iStatus.Int();
       
   525 			CleanupStack::PopAndDestroy(2);	// synchOperation, operation
       
   526 
       
   527 			TPop3Progress progress;
       
   528 			progress.iErrorCode = error;
       
   529 
       
   530 			TPckgBuf<TPop3Progress> resultPackage(progress);
       
   531 			aParameter.Copy(resultPackage);
       
   532 			return;
       
   533 			}
       
   534 		default:
       
   535 			error=KErrNotSupported;
       
   536 			__ASSERT_DEBUG(EFalse,gPanic(EPopcUnknownSyncFunction));
       
   537 		}
       
   538 
       
   539 	User::LeaveIfError(error);
       
   540 	}
       
   541 
       
   542 CMsvOperation* CPop3ClientMtm::InvokeAsyncFunctionL(TInt aFunctionId,
       
   543 													const CMsvEntrySelection& aSelection,
       
   544 												    TDes8& aParameter, 
       
   545 												    TRequestStatus& aCompletionStatus)
       
   546 /** Invokes asynchronous POP3-specific operations.
       
   547 
       
   548 @param aFunctionId Specifies which operation to perform e.g. connect, copy 
       
   549 new mail etc. The specific operations are defined by the TPop3Cmds enumeration. 
       
   550 
       
   551 @param aSelection A selection of messages that need to be copied/moved to a 
       
   552 local folder. The first entry in this selection MUST be the service. 
       
   553 @param aParameter Contains information such as the destination folder ID for 
       
   554 Get Mail operations. For get mail type functionality, this information must 
       
   555 be packaged as a TImPop3GetMailInfo package buffer. 
       
   556 @param aCompletionStatus The status when the operation completes. 
       
   557 @leave KErrNotFound The selection of email to be moved or copied is empty
       
   558 @leave KErrNotSupported The specified operation is not recognised
       
   559 @return If successful, this is an asynchronously completing operation. If failed, 
       
   560 this is a completed operation, with status set to the relevant error code. 
       
   561 @see TImPop3GetMailInfo
       
   562 @see TPop3Cmds */
       
   563 	{
       
   564 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(EPopcMTMNoCMsvEntrySet));
       
   565 
       
   566 	
       
   567 
       
   568 	switch(aFunctionId)
       
   569 		{
       
   570 		case KPOP3MTMConnect:
       
   571 		case KPOP3MTMDisconnect:
       
   572 		case KPOP3MTMCancelOfflineOperations:
       
   573 			if (aFunctionId==KPOP3MTMConnect)
       
   574 				{
       
   575 				RestoreSettingsL();
       
   576 				if (iImPop3Settings->AutoSendOnConnect()) 
       
   577 					{
       
   578 					TRAPD(err,SendOnNextConnectionL());  //ignore the error and continue with connecting
       
   579 					}
       
   580 				}
       
   581 			return (Session().TransferCommandL(aSelection, aFunctionId, aParameter, aCompletionStatus));
       
   582 		case KPOP3MTMCopyNewMailWhenAlreadyConnected:
       
   583 		case KPOP3MTMMoveNewMailWhenAlreadyConnected:
       
   584 		case KPOP3MTMCopyMailSelectionWhenAlreadyConnected:
       
   585 		case KPOP3MTMMoveMailSelectionWhenAlreadyConnected:
       
   586 		case KPOP3MTMCopyAllMailWhenAlreadyConnected:
       
   587 		case KPOP3MTMMoveAllMailWhenAlreadyConnected:
       
   588 			{
       
   589 			__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue, gPanic(EPopcMTMNotAServiceEntry));
       
   590 			TPckgBuf<TImPop3GetMailInfo> optionsBuf;
       
   591 			optionsBuf.Copy(aParameter);
       
   592 			const TImPop3GetMailInfo& options=optionsBuf();
       
   593 
       
   594 			CMsvEntrySelection *entrySelection=NULL;
       
   595 			TBool newMailOnly=EFalse;			
       
   596 			switch (aFunctionId)
       
   597 				{
       
   598 				case KPOP3MTMCopyNewMailWhenAlreadyConnected:
       
   599 				case KPOP3MTMMoveNewMailWhenAlreadyConnected:
       
   600 					newMailOnly=ETrue;
       
   601 				case KPOP3MTMCopyAllMailWhenAlreadyConnected:
       
   602 				case KPOP3MTMMoveAllMailWhenAlreadyConnected:
       
   603 					{
       
   604 					entrySelection=FilteredChildrenLC(newMailOnly,options.iMaxEmailSize);
       
   605 					}
       
   606 					break;
       
   607 				case KPOP3MTMCopyMailSelectionWhenAlreadyConnected:
       
   608 				case KPOP3MTMMoveMailSelectionWhenAlreadyConnected:
       
   609 					{
       
   610 					entrySelection=FilteredSelectionLC(options.iMaxEmailSize,aSelection);
       
   611 					}
       
   612 					break;
       
   613 				default:
       
   614 					User::Leave(KErrNotSupported);
       
   615 				}
       
   616 			// only need to do copy/move if the selection is not empty
       
   617 			CMsvOperation *op=NULL;
       
   618 			if (entrySelection->Count()>0)
       
   619 				{
       
   620 				if ((aFunctionId == KPOP3MTMCopyNewMailWhenAlreadyConnected) ||
       
   621 					(aFunctionId == KPOP3MTMCopyMailSelectionWhenAlreadyConnected) ||
       
   622 					(aFunctionId == KPOP3MTMCopyAllMailWhenAlreadyConnected))
       
   623 					{
       
   624 					op=iMsvEntry->CopyL(*entrySelection, options.iDestinationFolder, aCompletionStatus);
       
   625 					}
       
   626 				else if ((aFunctionId == KPOP3MTMMoveNewMailWhenAlreadyConnected) ||
       
   627 					(aFunctionId == KPOP3MTMMoveMailSelectionWhenAlreadyConnected) ||
       
   628 					(aFunctionId == KPOP3MTMMoveAllMailWhenAlreadyConnected))
       
   629 					{
       
   630 					op=iMsvEntry->MoveL(*entrySelection, options.iDestinationFolder, aCompletionStatus);
       
   631 					}
       
   632 				}
       
   633 			else
       
   634 				op=CMsvCompletedOperation::NewL(Session(), KUidMsgTypePOP3, KNullDesC8, iMsvEntry->Entry().iServiceId, aCompletionStatus);
       
   635 			CleanupStack::PopAndDestroy(entrySelection);
       
   636 			return op;
       
   637 			}
       
   638 
       
   639 		case KPOP3MTMPopulate:
       
   640 		case KPOP3MTMPopulateNew:
       
   641 		case KPOP3MTMPopulateAll:
       
   642 			{
       
   643 			__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue, gPanic(EPopcMTMNotAServiceEntry));
       
   644 			TImPop3PopulateOptions options;
       
   645 			TImPop3PopulateOptions::UnpackL(aParameter,options);
       
   646 
       
   647 			CMsvEntrySelection *entrySelection;
       
   648 			if(aFunctionId==KPOP3MTMPopulateNew || aFunctionId==KPOP3MTMPopulateAll)
       
   649 				{
       
   650 				entrySelection=FilteredChildrenLC(aFunctionId==KPOP3MTMPopulateNew,options.MaxEmailSize());				
       
   651 				}
       
   652 			else
       
   653 				{
       
   654 				entrySelection=FilteredSelectionLC(options.MaxEmailSize(),aSelection);
       
   655 				}
       
   656 
       
   657 			CMsvOperation *op=NULL;
       
   658 			if (entrySelection->Count()>0)
       
   659 				{
       
   660 				entrySelection->InsertL(0,aSelection[0]);
       
   661 				op=(Session().TransferCommandL(*entrySelection, KPOP3MTMPopulate, aParameter, aCompletionStatus));
       
   662 				}
       
   663 			else
       
   664 				op=CMsvCompletedOperation::NewL(Session(), KUidMsgTypePOP3, KNullDesC8, iMsvEntry->Entry().iServiceId, aCompletionStatus);
       
   665 			
       
   666 			CleanupStack::PopAndDestroy(entrySelection);
       
   667 			return op;
       
   668 			}		
       
   669 
       
   670 		case KPOP3MTMConnectAndCopyNewMailAndStayOnline:
       
   671 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyNewMailAndStayOnline);
       
   672 		case KPOP3MTMConnectAndCopyNewMailAndDisconnect:
       
   673 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyNewMailAndDisconnect);
       
   674 		case KPOP3MTMConnectAndMoveNewMailAndStayOnline:
       
   675 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveNewMailAndStayOnline);
       
   676 		case KPOP3MTMConnectAndMoveNewMailAndDisconnect:
       
   677 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveNewMailAndDisconnect);
       
   678 		case KPOP3MTMConnectAndCopyMailSelectionAndStayOnline:
       
   679 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyMailSelectionAndStayOnline);
       
   680 		case KPOP3MTMConnectAndCopyMailSelectionAndDisconnect:
       
   681 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyMailSelectionAndDisconnect);
       
   682 		case KPOP3MTMConnectAndMoveMailSelectionAndStayOnline:
       
   683 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveMailSelectionAndStayOnline);
       
   684 		case KPOP3MTMConnectAndMoveMailSelectionAndDisconnect:
       
   685 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveMailSelectionAndDisconnect);
       
   686 		case KPOP3MTMConnectAndCopyAllMailAndStayOnline:
       
   687 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyAllMailAndStayOnline);
       
   688 		case KPOP3MTMConnectAndCopyAllMailAndDisconnect:
       
   689 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndCopyAllMailAndDisconnect);
       
   690 		case KPOP3MTMConnectAndMoveAllMailAndStayOnline:
       
   691 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveAllMailAndStayOnline);
       
   692 		case KPOP3MTMConnectAndMoveAllMailAndDisconnect:
       
   693 			return iImPOP3GetMail->GetMailL(*this, aCompletionStatus, aSelection, aParameter, CImPOP3GetMail::EConnectAndMoveAllMailAndDisconnect);
       
   694 		case KPOP3MTMCreateNewEmailMessage:
       
   695 		case KPOP3MTMCreateReplyEmailMessage:
       
   696 		case KPOP3MTMCreateForwardEmailMessage:
       
   697 		case KPOP3MTMCreateForwardAsAttachmentEmailMessage:
       
   698 		case KPOP3MTMCreateReceiptEmailMessage:
       
   699 			{
       
   700 			TImCreateMessageOptions createMessageOptions;	
       
   701 			TPckgC<TImCreateMessageOptions> paramPack(createMessageOptions);
       
   702 			paramPack.Set(aParameter);
       
   703 			switch (aFunctionId)
       
   704 				{
       
   705 			case KPOP3MTMCreateNewEmailMessage:
       
   706 				return iImEmailOperation->CreateNewL(aCompletionStatus, iMsvEntry->Session(), aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   707 			case KPOP3MTMCreateReplyEmailMessage:
       
   708 				return iImEmailOperation->CreateReplyL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   709 			case KPOP3MTMCreateForwardEmailMessage:
       
   710 				return iImEmailOperation->CreateForwardL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   711 			case KPOP3MTMCreateForwardAsAttachmentEmailMessage:
       
   712 				return iImEmailOperation->CreateForwardAsAttachmentL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   713 			case KPOP3MTMCreateReceiptEmailMessage:
       
   714 				return iImEmailOperation->CreateReceiptL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   715 			default:
       
   716 				User::Leave(KErrNotSupported);
       
   717 				return NULL;	// shouldn't really get here!
       
   718 				}
       
   719 			}
       
   720 		default:
       
   721 			User::Leave(KErrNotSupported);
       
   722 			return NULL;	// shouldn't really get here!
       
   723 		}
       
   724 	}
       
   725 
       
   726 // Attachment functions to support the SendAs API
       
   727 
       
   728 // Attachment functions to support the SendAs API
       
   729 
       
   730 /** Unsupported client MTM base class function.
       
   731 
       
   732 @param aFilePath Unused
       
   733 @param aMimeType Unused
       
   734 @param aCharset Unused
       
   735 @param aStatus Unused
       
   736  */
       
   737 EXPORT_C void CPop3ClientMtm::AddAttachmentL(const TDesC& /*aFilePath*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
   738 	{
       
   739 	User::Leave(KErrNotSupported);
       
   740 	}
       
   741 
       
   742 /** Unsupported client MTM base class function.
       
   743 
       
   744 @param aFile Unused
       
   745 @param aMimeType Unused
       
   746 @param aCharset Unused
       
   747 @param aStatus Unused
       
   748  */	
       
   749 EXPORT_C void CPop3ClientMtm::AddAttachmentL(RFile& /*aFile*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
   750 	{
       
   751 	User::Leave(KErrNotSupported);
       
   752 	}
       
   753 	
       
   754 /** Unsupported client MTM base class function.
       
   755 
       
   756 @param aFilePath Unused
       
   757 @param aMimeType Unused
       
   758 @param aCharset Unused
       
   759 @param aStatus Unused
       
   760  */
       
   761 EXPORT_C void CPop3ClientMtm::AddLinkedAttachmentL(const TDesC& /*aFilePath*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
   762 	{
       
   763 	User::Leave(KErrNotSupported);
       
   764 	}
       
   765 	
       
   766 /** Unsupported client MTM base class function.
       
   767 
       
   768 @param aAttachmentId Unused
       
   769 @param aStatus Unused
       
   770  */
       
   771 EXPORT_C void CPop3ClientMtm::AddEntryAsAttachmentL(TMsvId /*aAttachmentId*/, TRequestStatus& /*aStatus*/)
       
   772 	{
       
   773 	User::Leave(KErrNotSupported);
       
   774 	}
       
   775 	
       
   776 /** Unsupported client MTM base class function.
       
   777 
       
   778 @param aFileName Unused
       
   779 @param aAttachmentFile Unused
       
   780 @param aMimeType Unused
       
   781 @param aCharset Unused
       
   782 @param aStatus Unused
       
   783  */
       
   784 EXPORT_C void CPop3ClientMtm::CreateAttachmentL(const TDesC& /*aFileName*/, RFile& /*aAttachmentFile*/, const TDesC8& /*aMimeType*/, TUint /*aCharset*/, TRequestStatus& /*aStatus*/)
       
   785 	{
       
   786 	User::Leave(KErrNotSupported);
       
   787 	}
       
   788 
       
   789 EXPORT_C void CPop3ClientMtm::CreateMessageL(TMsvId /*aServiceId*/)
       
   790 /** Unsupported client MTM base class function.
       
   791 
       
   792 @param aServiceId Unused */
       
   793 	{
       
   794 	User::Leave(KErrNotSupported);
       
   795 	}
       
   796 
       
   797 CMsvEntrySelection* CPop3ClientMtm::FilteredChildrenLC(TBool aNewOnly, TInt aMaxEmailSize)
       
   798 	{
       
   799 	CMsvEntrySelection *selection= new (ELeave) CMsvEntrySelection;
       
   800 	CleanupDeletePushL(selection);
       
   801 	
       
   802 	TInt count = iMsvEntry->Count();
       
   803 	// get a selection of messages which are new - i.e have new flag set
       
   804 	// and those which are smaller than iMaxEmailSize
       
   805 	for (TInt i=0; i<count; ++i)
       
   806 		{
       
   807 		const TMsvEmailEntry &entry = (*iMsvEntry)[i];
       
   808 		if (entry.iType==KUidMsvMessageEntry)
       
   809 			{
       
   810 			if ((!aNewOnly || entry.New()) &&
       
   811 				(entry.iSize <= aMaxEmailSize))
       
   812 				selection->AppendL(entry.Id());
       
   813 			}
       
   814 		}
       
   815 	return selection;
       
   816 	}
       
   817 
       
   818 CMsvEntrySelection* CPop3ClientMtm::FilteredSelectionLC(TInt aMaxEmailSize, const CMsvEntrySelection& aSelection)
       
   819 	{
       
   820 	CMsvEntrySelection *selection= new (ELeave) CMsvEntrySelection;
       
   821 	CleanupDeletePushL(selection);
       
   822 	TInt count = aSelection.Count();
       
   823 	
       
   824 	for (TInt i=1; i<count; ++i)
       
   825 		{
       
   826 		const TMsvEmailEntry &entry = iMsvEntry->ChildDataL((aSelection)[i]);
       
   827 		if ((entry.iType==KUidMsvMessageEntry)&&(entry.iSize <= aMaxEmailSize))
       
   828 			{
       
   829 			selection->AppendL(entry.Id());
       
   830 			}
       
   831 		}
       
   832 	return selection;
       
   833 	}
       
   834 
       
   835 /**
       
   836 Gets the default POP service.
       
   837 
       
   838 @return
       
   839 The default service
       
   840 
       
   841 @leave 
       
   842 KErrNotFound If default service setting does not exist.
       
   843 */
       
   844 EXPORT_C TMsvId CPop3ClientMtm::DefaultServiceL() const
       
   845 	{
       
   846 	User::Leave(KErrNotSupported);
       
   847 	return KErrNotSupported;
       
   848 	}
       
   849 
       
   850 /**
       
   851 Removes the default POP service.
       
   852 */	
       
   853 EXPORT_C void CPop3ClientMtm::RemoveDefaultServiceL()
       
   854 	{
       
   855 	User::Leave(KErrNotSupported);
       
   856 	}
       
   857 
       
   858 /**
       
   859 Sets the default POP service.
       
   860 
       
   861 @param	aService
       
   862 The default service
       
   863 */	
       
   864 EXPORT_C void CPop3ClientMtm::ChangeDefaultServiceL(const TMsvId& /*aService*/)
       
   865 	{
       
   866 	User::Leave(KErrNotSupported);
       
   867 	}
       
   868 
       
   869 
       
   870 EXPORT_C CMsvOperation* CImPOP3GetMail::GetMailL(CPop3ClientMtm& aPop3ClientMtm, TRequestStatus& aObserverRequestStatus, const CMsvEntrySelection& aMsvEntrySelection, TDes8& aPop3GetMailInfo, TImPOP3GetMailType aPOP3GetMailType)
       
   871 /** Creates and begins a new POP3 get mail operation.
       
   872 
       
   873 @param aPop3ClientMtm A reference to the POP3 Client MTM that wants to perform 
       
   874 the Get Mail operation.
       
   875 @param aObserverRequestStatus The status to be completed when the get mail 
       
   876 operation has completed.
       
   877 @param aMsvEntrySelection A selection of messages that need to be copied/moved 
       
   878 to a local folder. The first entry in this selection MUST be the service.
       
   879 @param aPop3GetMailInfo A packaged TImPop3GetMailInfo object, which sets the 
       
   880 maximum message size and the destination folder ID.
       
   881 @param aPOP3GetMailType Type of operation to perform
       
   882 @return The new CImPOP3GetMail object through which the get operation can be 
       
   883 controlled. */
       
   884 	{
       
   885 	CImPOP3GetMail* self = new(ELeave) CImPOP3GetMail(aPop3ClientMtm.Session(), aObserverRequestStatus, aPop3ClientMtm, aPOP3GetMailType);
       
   886 	CleanupStack::PushL(self);
       
   887 	self->ConstructL(aMsvEntrySelection, aPop3GetMailInfo);
       
   888 	CleanupStack::Pop(); //self
       
   889 	return self;
       
   890 	}
       
   891 
       
   892 EXPORT_C CImPOP3GetMail::~CImPOP3GetMail()
       
   893 /** Destructor. */
       
   894 	{
       
   895 	Cancel();
       
   896 	delete iMsvEntrySelection;
       
   897 	delete iMsvOperation;
       
   898 	}
       
   899 
       
   900 EXPORT_C const TDesC8& CImPOP3GetMail::FinalProgress()
       
   901 /** Gets information about a completed operation.
       
   902 
       
   903 @return Packaged TPop3Progress holding progress information. 
       
   904 @see TPop3Progress */
       
   905 	{
       
   906 	__ASSERT_ALWAYS(!IsActive(), gPanic(EMiutActiveInFinalProgress));
       
   907 
       
   908 	const TDesC8& opProgress = iMsvOperation->FinalProgress();
       
   909 
       
   910 	if (opProgress.Length())
       
   911 		{
       
   912 		// if an error was encountered during the Get New Mail operation then need to 
       
   913 		// return this as part of the final progresse.  If no error was encoutered then
       
   914 		// return iProgress
       
   915 		TPop3Progress prog;	
       
   916 		TPckgC<TPop3Progress> paramPack(prog);
       
   917 		paramPack.Set(opProgress);
       
   918 		TPop3Progress progress=paramPack();
       
   919 		if (iErrorProgress.iErrorCode != KErrNone)
       
   920 			{
       
   921 			progress.iTotalMsgs = iErrorProgress.iTotalMsgs;
       
   922 			progress.iMsgsToProcess = iErrorProgress.iMsgsToProcess;
       
   923 			progress.iBytesDone = iErrorProgress.iBytesDone;
       
   924 			progress.iTotalBytes = iErrorProgress.iTotalBytes;
       
   925 			progress.iErrorCode = iErrorProgress.iErrorCode;
       
   926 			progress.iPop3SubStateProgress = iErrorProgress.iPop3SubStateProgress;
       
   927 			}
       
   928 		else 
       
   929 			progress.iPop3SubStateProgress = progress.iPop3Progress;
       
   930 
       
   931 		switch(iPOP3GetMailType)
       
   932 			{
       
   933 			case EConnectAndCopyNewMailAndStayOnline:
       
   934 			case EConnectAndCopyNewMailAndDisconnect:
       
   935 				progress.iPop3Progress = TPop3Progress::EPopCopyNewMail;
       
   936 				break;
       
   937 			case EConnectAndMoveNewMailAndStayOnline:
       
   938 			case EConnectAndMoveNewMailAndDisconnect:
       
   939 				progress.iPop3Progress = TPop3Progress::EPopMoveNewMail;
       
   940 				break;
       
   941 			case EConnectAndCopyMailSelectionAndStayOnline:
       
   942 			case EConnectAndCopyMailSelectionAndDisconnect:
       
   943 				progress.iPop3Progress = TPop3Progress::EPopCopyMailSelection;
       
   944 				break;
       
   945 			case EConnectAndMoveMailSelectionAndStayOnline:
       
   946 			case EConnectAndMoveMailSelectionAndDisconnect:
       
   947 				progress.iPop3Progress = TPop3Progress::EPopMoveMailSelection;
       
   948 				break;
       
   949 			case EConnectAndCopyAllMailAndStayOnline:
       
   950 			case EConnectAndCopyAllMailAndDisconnect:
       
   951 				progress.iPop3Progress = TPop3Progress::EPopCopyAllMail;
       
   952 				break;
       
   953 			case EConnectAndMoveAllMailAndStayOnline:
       
   954 			case EConnectAndMoveAllMailAndDisconnect:
       
   955 				progress.iPop3Progress = TPop3Progress::EPopMoveAllMail;
       
   956 				break;
       
   957 			}
       
   958 		
       
   959 		iProgressBuf = progress;
       
   960 		}
       
   961 	return iProgressBuf;
       
   962 	}
       
   963 
       
   964 void CImPOP3GetMail::ResetProgress()
       
   965 	{
       
   966 	switch(iPOP3GetMailType)
       
   967 		{
       
   968 		case EConnectAndCopyNewMailAndStayOnline:
       
   969 		case EConnectAndCopyNewMailAndDisconnect:
       
   970 			iProgress.iPop3Progress = TPop3Progress::EPopCopyNewMail;
       
   971 			break;
       
   972 		case EConnectAndMoveNewMailAndStayOnline:
       
   973 		case EConnectAndMoveNewMailAndDisconnect:
       
   974 			iProgress.iPop3Progress = TPop3Progress::EPopMoveNewMail;
       
   975 			break;
       
   976 		case EConnectAndCopyMailSelectionAndStayOnline:
       
   977 		case EConnectAndCopyMailSelectionAndDisconnect:
       
   978 			iProgress.iPop3Progress = TPop3Progress::EPopCopyMailSelection;
       
   979 			break;
       
   980 		case EConnectAndMoveMailSelectionAndStayOnline:
       
   981 		case EConnectAndMoveMailSelectionAndDisconnect:
       
   982 			iProgress.iPop3Progress = TPop3Progress::EPopMoveMailSelection;
       
   983 			break;
       
   984 		case EConnectAndCopyAllMailAndStayOnline:
       
   985 		case EConnectAndCopyAllMailAndDisconnect:
       
   986 			iProgress.iPop3Progress = TPop3Progress::EPopCopyAllMail;
       
   987 			break;
       
   988 		case EConnectAndMoveAllMailAndStayOnline:
       
   989 		case EConnectAndMoveAllMailAndDisconnect:
       
   990 			iProgress.iPop3Progress = TPop3Progress::EPopMoveAllMail;
       
   991 		}
       
   992 	iProgress.iTotalMsgs = 0;
       
   993 	iProgress.iMsgsToProcess = 0;
       
   994 	iProgress.iBytesDone = 0;
       
   995 	iProgress.iTotalBytes = 0;
       
   996 	iProgress.iErrorCode = KErrNone;
       
   997 	}
       
   998 
       
   999 const TDesC8& CImPOP3GetMail::ProgressL()
       
  1000 /** Gets information on the progress of the operation. 
       
  1001 
       
  1002 @return Packaged TPop3Progress holding progress information. 
       
  1003 @see TPop3Progress */
       
  1004 	{
       
  1005 	const TDesC8& opProgress = iMsvOperation->ProgressL();
       
  1006 
       
  1007 	if (opProgress.Length())
       
  1008 		{
       
  1009 		// need to get Sub operation progress and put this into iPop3SubStateProgress
       
  1010 		TPop3Progress prog;	
       
  1011 		TPckgC<TPop3Progress> paramPack(prog);
       
  1012 		paramPack.Set(opProgress);
       
  1013 		TPop3Progress progress=paramPack();	
       
  1014 
       
  1015 		progress.iPop3SubStateProgress = progress.iPop3Progress;
       
  1016 		switch(iPOP3GetMailType)
       
  1017 			{
       
  1018 			case EConnectAndCopyNewMailAndStayOnline:
       
  1019 			case EConnectAndCopyNewMailAndDisconnect:
       
  1020 				progress.iPop3Progress = TPop3Progress::EPopCopyNewMail;
       
  1021 				break;
       
  1022 			case EConnectAndMoveNewMailAndStayOnline:
       
  1023 			case EConnectAndMoveNewMailAndDisconnect:
       
  1024 				progress.iPop3Progress = TPop3Progress::EPopMoveNewMail;
       
  1025 				break;
       
  1026 			case EConnectAndCopyMailSelectionAndStayOnline:
       
  1027 			case EConnectAndCopyMailSelectionAndDisconnect:
       
  1028 				progress.iPop3Progress = TPop3Progress::EPopCopyMailSelection;
       
  1029 				break;
       
  1030 			case EConnectAndMoveMailSelectionAndStayOnline:
       
  1031 			case EConnectAndMoveMailSelectionAndDisconnect:
       
  1032 				progress.iPop3Progress = TPop3Progress::EPopMoveMailSelection;
       
  1033 				break;
       
  1034 			case EConnectAndCopyAllMailAndStayOnline:
       
  1035 			case EConnectAndCopyAllMailAndDisconnect:
       
  1036 				progress.iPop3Progress = TPop3Progress::EPopCopyAllMail;
       
  1037 				break;
       
  1038 			case EConnectAndMoveAllMailAndStayOnline:
       
  1039 			case EConnectAndMoveAllMailAndDisconnect:
       
  1040 				progress.iPop3Progress = TPop3Progress::EPopMoveAllMail;
       
  1041 			}
       
  1042 		iProgressBuf = progress;
       
  1043 		}
       
  1044 	return iProgressBuf;
       
  1045 	}
       
  1046 
       
  1047 void CImPOP3GetMail::StoreProgressL()
       
  1048 	{
       
  1049 	const TDesC8& opProgress = iMsvOperation->ProgressL();
       
  1050 
       
  1051 	if (opProgress.Length())
       
  1052 		{
       
  1053 		TPop3Progress prog;	
       
  1054 		TPckgC<TPop3Progress> paramPack(prog);
       
  1055 		paramPack.Set(opProgress);
       
  1056 		TPop3Progress progress=paramPack();	
       
  1057 
       
  1058 		iProgress.iTotalMsgs = progress.iTotalMsgs;
       
  1059 		iProgress.iMsgsToProcess = progress.iMsgsToProcess;
       
  1060 		iProgress.iBytesDone = progress.iBytesDone;
       
  1061 		iProgress.iTotalBytes = progress.iTotalBytes;
       
  1062 		iProgress.iPop3SubStateProgress = progress.iPop3Progress;
       
  1063 		
       
  1064 		// only write the error code if no error has previously been set
       
  1065 		if ((iProgress.iErrorCode == KErrNone) && (iErrorProgress.iErrorCode == KErrNone))
       
  1066 			{
       
  1067 			if (iStatus.Int() != KErrNone)				
       
  1068 				iProgress.iErrorCode = iStatus.Int();
       
  1069 			else
       
  1070 				iProgress.iErrorCode = progress.iErrorCode;
       
  1071 			}
       
  1072 		iProgressBuf = progress;
       
  1073 		}
       
  1074 	}
       
  1075 
       
  1076 void CImPOP3GetMail::DoCancel()
       
  1077 	{
       
  1078 	iMsvOperation->Cancel();
       
  1079 	TRequestStatus* st = &iObserverRequestStatus;
       
  1080 	User::RequestComplete(st, KErrCancel);
       
  1081 	}
       
  1082 
       
  1083 CImPOP3GetMail::CImPOP3GetMail(CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus, CPop3ClientMtm& aPop3ClientMtm, TImPOP3GetMailType aPOP3GetMailType)
       
  1084 	: CMsvOperation(aMsvSession, EPriorityStandard, aObserverRequestStatus),
       
  1085 	iPop3ClientMtm(aPop3ClientMtm),
       
  1086 	iPOP3GetMailType(aPOP3GetMailType)
       
  1087 	{
       
  1088 	__DECLARE_NAME(_S("CImPOP3GetMail"));
       
  1089 	}
       
  1090 
       
  1091 void CImPOP3GetMail::ConstructL(const CMsvEntrySelection& aMsvEntrySelection, TDes8& aPop3GetMailInfo)
       
  1092 	{
       
  1093 	iMsvEntrySelection = aMsvEntrySelection.CopyL();
       
  1094 	
       
  1095 	iPop3GetMailInfo.Copy(aPop3GetMailInfo);
       
  1096 
       
  1097 	CActiveScheduler::Add(this);
       
  1098 	ResetProgress();
       
  1099 	iState = EConnectToMailbox;
       
  1100 	ChangeStateL();
       
  1101 	iObserverRequestStatus = KRequestPending;
       
  1102 	SetActive();
       
  1103 	}
       
  1104 
       
  1105 void CImPOP3GetMail::Complete()
       
  1106 	{
       
  1107 	// complete the observer with error
       
  1108 	TRequestStatus* status=&iObserverRequestStatus;
       
  1109 	User::RequestComplete(status,KErrNone);
       
  1110 	}
       
  1111 
       
  1112 void CImPOP3GetMail::SelectAndChangeToNextStateL()
       
  1113 	{
       
  1114 	SelectNextStateL();
       
  1115 	ChangeStateL();
       
  1116 	}
       
  1117 
       
  1118 void CImPOP3GetMail::RunL()
       
  1119 	{
       
  1120 	TInt error = KErrNone;
       
  1121 	if (iState != EFinished)
       
  1122 		{
       
  1123 		// store progress if connecting, copying/moving new/all/selected messages.
       
  1124 		if ((iState == EConnectToMailbox) || (iState == ECopyNewMessages) ||
       
  1125 			(iState == ECopyAllMessages) ||	(iState == ECopyMessageSelection) ||
       
  1126 			(iState == EMoveNewMessages) || (iState == EMoveAllMessages) ||
       
  1127 			(iState == EMoveMessageSelection))
       
  1128 			{
       
  1129 			StoreProgressL();
       
  1130 			}
       
  1131 			
       
  1132 		if (iProgress.iErrorCode != KErrNone)
       
  1133 			{
       
  1134 			// There has been an error in the previous operation - remember the error.
       
  1135 			iErrorProgress.iTotalMsgs = iProgress.iTotalMsgs;
       
  1136 			iErrorProgress.iMsgsToProcess = iProgress.iMsgsToProcess;
       
  1137 			iErrorProgress.iBytesDone = iProgress.iBytesDone;
       
  1138 			iErrorProgress.iTotalBytes = iProgress.iTotalBytes;
       
  1139 			iErrorProgress.iErrorCode = iProgress.iErrorCode;
       
  1140 
       
  1141 			// reset progress error code
       
  1142 			iProgress.iErrorCode = KErrNone;
       
  1143 
       
  1144 			// update the state that the error occured.
       
  1145 			switch (iState)
       
  1146 				{
       
  1147 				case EConnectToMailbox:
       
  1148 					iErrorProgress.iPop3SubStateProgress = TPop3Progress::EPopConnecting;
       
  1149 					Complete();
       
  1150 					return;
       
  1151 				case ECopyNewMessages:
       
  1152 				case ECopyAllMessages:
       
  1153 				case ECopyMessageSelection:
       
  1154 					iErrorProgress.iPop3SubStateProgress = TPop3Progress::EPopCopying;
       
  1155 					// The next state is disconnect so continue!
       
  1156 					break;
       
  1157 				case EMoveNewMessages:
       
  1158 				case EMoveAllMessages:
       
  1159 				case EMoveMessageSelection:
       
  1160 					iErrorProgress.iPop3SubStateProgress = TPop3Progress::EPopMoving;
       
  1161 					// The next state is disconnect so continue!
       
  1162 					break;
       
  1163 				case EDisconnectFromMailbox:
       
  1164 					iErrorProgress.iPop3SubStateProgress = TPop3Progress::EPopDisconnecting;
       
  1165 					Complete();
       
  1166 					return;
       
  1167 				default:
       
  1168 					Complete();
       
  1169 					return;
       
  1170 				}
       
  1171 			}
       
  1172 			
       
  1173 			else if (iProgress.iPop3SubStateProgress == TPop3Progress::EPopDisconnected)
       
  1174 			{
       
  1175 			// Connection has dropped, so complete the operation
       
  1176 			Complete();
       
  1177 			return;
       
  1178 			}				
       
  1179 		}
       
  1180 		
       
  1181 		TRAP(error, SelectAndChangeToNextStateL());
       
  1182 		if ((error == KErrNone) && (iState != EFinished))
       
  1183 			{
       
  1184 			SetActive();
       
  1185 			}			
       
  1186 		else if (error != KErrNone)
       
  1187 			{
       
  1188 			// if iState == EFinished, then we don't need to complete - done previously
       
  1189 			TRequestStatus* st = &iObserverRequestStatus;
       
  1190 			User::RequestComplete(st, error);
       
  1191 			}
       
  1192 	}
       
  1193 
       
  1194 void CImPOP3GetMail::SelectNextStateL()
       
  1195 	{
       
  1196 	switch (iState)
       
  1197 		{
       
  1198 		case EConnectToMailbox:
       
  1199 			if (iProgress.iErrorCode == KErrNone)
       
  1200 				{
       
  1201 				switch(iPOP3GetMailType)
       
  1202 					{
       
  1203 					case EConnectAndCopyNewMailAndStayOnline:
       
  1204 					case EConnectAndCopyNewMailAndDisconnect:
       
  1205 						iState = ECopyNewMessages;
       
  1206 						break;
       
  1207 					case EConnectAndMoveNewMailAndStayOnline:
       
  1208 					case EConnectAndMoveNewMailAndDisconnect:
       
  1209 						iState = EMoveNewMessages;
       
  1210 						break;
       
  1211 					case EConnectAndCopyMailSelectionAndStayOnline:
       
  1212 					case EConnectAndCopyMailSelectionAndDisconnect:
       
  1213 						iState = ECopyMessageSelection;
       
  1214 						break;
       
  1215 					case EConnectAndMoveMailSelectionAndStayOnline:
       
  1216 					case EConnectAndMoveMailSelectionAndDisconnect:
       
  1217 						iState = EMoveMessageSelection;
       
  1218 						break;
       
  1219 					case EConnectAndCopyAllMailAndStayOnline:
       
  1220 					case EConnectAndCopyAllMailAndDisconnect:
       
  1221 						iState = ECopyAllMessages;
       
  1222 						break;
       
  1223 					case EConnectAndMoveAllMailAndStayOnline:
       
  1224 					case EConnectAndMoveAllMailAndDisconnect:
       
  1225 						iState = EMoveAllMessages;
       
  1226 						break;
       
  1227 					}
       
  1228 				}
       
  1229 			else 
       
  1230 				iState = EDisconnectFromMailbox;
       
  1231 			break;
       
  1232 		case ECopyNewMessages:
       
  1233 		case EMoveNewMessages:
       
  1234 		case ECopyMessageSelection:
       
  1235 		case EMoveMessageSelection:
       
  1236 		case ECopyAllMessages:
       
  1237 		case EMoveAllMessages:
       
  1238 			if ((iPOP3GetMailType == EConnectAndCopyNewMailAndStayOnline) ||
       
  1239 				(iPOP3GetMailType == EConnectAndMoveNewMailAndStayOnline) ||
       
  1240 				(iPOP3GetMailType == EConnectAndCopyMailSelectionAndStayOnline) ||
       
  1241 				(iPOP3GetMailType == EConnectAndMoveMailSelectionAndStayOnline) ||
       
  1242 				(iPOP3GetMailType == EConnectAndCopyAllMailAndStayOnline) ||
       
  1243 				(iPOP3GetMailType == EConnectAndMoveAllMailAndStayOnline))
       
  1244 				{
       
  1245 				iState = EFinished;
       
  1246 				}
       
  1247 			else
       
  1248 				if ((iProgress.iErrorCode == KErrNone) && (iErrorProgress.iErrorCode == KErrNone) || (iProgress.iErrorCode == KErrDiskFull))
       
  1249 					{
       
  1250    					iState = EDisconnectFromMailbox;
       
  1251 					}
       
  1252 				else
       
  1253 					// The POPS MTM will already have disconnected if it has completed with an error
       
  1254 					{
       
  1255 					iState = EFinished;
       
  1256 				}
       
  1257 			break;
       
  1258 		case EDisconnectFromMailbox:
       
  1259 			iState = EFinished;
       
  1260 			break;
       
  1261 		default:
       
  1262 			User::LeaveIfError(KErrNotSupported);
       
  1263 			break;
       
  1264 		}
       
  1265 	}
       
  1266 
       
  1267 void CImPOP3GetMail::ChangeStateL()
       
  1268 	{
       
  1269 	switch (iState)
       
  1270 		{
       
  1271 		case EConnectToMailbox:
       
  1272 			ConnectToMailboxL();
       
  1273 			break;
       
  1274 		case ECopyNewMessages:
       
  1275 			CopyMoveNewMessagesL(ETrue);
       
  1276 			break;
       
  1277 		case EMoveNewMessages:
       
  1278 			CopyMoveNewMessagesL(EFalse);
       
  1279 			break;
       
  1280 		case ECopyMessageSelection:
       
  1281 			CopyMoveMessageSelectionL(ETrue);
       
  1282 			break;
       
  1283 		case EMoveMessageSelection:
       
  1284 			CopyMoveMessageSelectionL(EFalse);
       
  1285 			break;
       
  1286 		case ECopyAllMessages:
       
  1287 			CopyMoveAllMessagesL(ETrue);
       
  1288 			break;
       
  1289 		case EMoveAllMessages:
       
  1290 			CopyMoveAllMessagesL(EFalse);
       
  1291 			break;
       
  1292 		case EDisconnectFromMailbox:
       
  1293 			DisconnectFromMailboxL();
       
  1294 			break;
       
  1295 		case EFinished:
       
  1296 			{
       
  1297 			TRequestStatus* status=&iObserverRequestStatus;
       
  1298 			User::RequestComplete(status,KErrNone);
       
  1299 			}
       
  1300 		}
       
  1301 	}
       
  1302 
       
  1303 void CImPOP3GetMail::RequestComplete(TInt aError)
       
  1304 	{
       
  1305 	iStatus = KRequestPending;
       
  1306 	TRequestStatus* status=&iStatus;
       
  1307 	iStatus=KRequestPending;
       
  1308 	User::RequestComplete(status,aError);
       
  1309 	}
       
  1310 
       
  1311 void CImPOP3GetMail::ConnectToMailboxL()
       
  1312 	{
       
  1313 	ResetProgress();
       
  1314 	iProgress.iPop3SubStateProgress = TPop3Progress::EPopConnecting;
       
  1315 	delete iMsvOperation;
       
  1316 	iMsvOperation=NULL;
       
  1317 	iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMConnect, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1318 	}
       
  1319 
       
  1320 void CImPOP3GetMail::CopyMoveNewMessagesL(TBool aCopy)
       
  1321 	{
       
  1322 	ResetProgress();
       
  1323 	delete iMsvOperation;
       
  1324 	iMsvOperation=NULL;
       
  1325 	if (aCopy)
       
  1326 		{
       
  1327 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopCopying;
       
  1328 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMCopyNewMailWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1329 		}
       
  1330 	else
       
  1331 		{
       
  1332 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopMoving;
       
  1333 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMMoveNewMailWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1334 		}
       
  1335 	}
       
  1336 
       
  1337 void CImPOP3GetMail::CopyMoveMessageSelectionL(TBool aCopy)
       
  1338 	{
       
  1339 	ResetProgress();
       
  1340 	delete iMsvOperation;
       
  1341 	iMsvOperation=NULL;
       
  1342 	if (aCopy)
       
  1343 		{
       
  1344 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopCopying;
       
  1345 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMCopyMailSelectionWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1346 		}
       
  1347 	else
       
  1348 		{
       
  1349 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopMoving;
       
  1350 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMMoveMailSelectionWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1351 		}
       
  1352 	}
       
  1353 
       
  1354 void CImPOP3GetMail::CopyMoveAllMessagesL(TBool aCopy)
       
  1355 	{
       
  1356 	ResetProgress();
       
  1357 	delete iMsvOperation;
       
  1358 	iMsvOperation=NULL;
       
  1359 	if (aCopy)
       
  1360 		{
       
  1361 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopCopying;
       
  1362 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMCopyAllMailWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1363 		}
       
  1364 	else
       
  1365 		{
       
  1366 		iProgress.iPop3SubStateProgress = TPop3Progress::EPopMoving;
       
  1367 		iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMMoveAllMailWhenAlreadyConnected, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1368 		}
       
  1369 	}
       
  1370 
       
  1371 void CImPOP3GetMail::DisconnectFromMailboxL()
       
  1372 	{
       
  1373 	//don't reset progress so that no. of messages copied are still remembered
       
  1374 	iProgress.iPop3SubStateProgress = TPop3Progress::EPopDisconnecting;
       
  1375 	delete iMsvOperation;
       
  1376 	iMsvOperation=NULL;
       
  1377 	iMsvOperation=iPop3ClientMtm.InvokeAsyncFunctionL(KPOP3MTMDisconnect, *iMsvEntrySelection, iPop3GetMailInfo, iStatus);
       
  1378 	}