email/pop3andsmtpmtm/clientmtms/src/SMTCMTM.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 // Client MTM for the SMTP protocol
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <bautils.h>	// BaflUtils::NearestLanguageFile()
       
    19 #include <txtrich.h>	// CRichText
       
    20 
       
    21 #include <barsc.h>		//RResourceFile
       
    22 #include <barsread.h>
       
    23 
       
    24 #include <msvstore.h>	// CMsvStore
       
    25 #include <mtmdef.h>		//KUidMtmQueryxxx & TMsvPartList flags
       
    26 #include <imcm.rsg>
       
    27 #include <mmsvattachmentmanager.h>
       
    28 #include <cmsvmimeheaders.h>
       
    29 #include <cemailaccounts.h>
       
    30 #include "CImAttachmentWaiter.h"
       
    31 #include "cmsvsmtpsendoperation.h"
       
    32 #include "MIUTHDR.H"	//CImHeader
       
    33 #include "SMTCMTM.H"
       
    34 #include "MIUT_ERR.H"
       
    35 #include "IMCMMAIN.H"
       
    36 #include "IMCMUTIL.H"
       
    37 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
       
    38 #include <mtmuidsdef.hrh>
       
    39 #include "timrfc822datefield.h" 
       
    40 #include "miut_errconsts.h"
       
    41 #include "msvconsts.h"
       
    42 #include "cimmessagepart.h"
       
    43 #endif
       
    44 
       
    45 #include <msvenhancesearchsortutil.h>
       
    46 
       
    47 #if defined (_UNICODE)
       
    48 	#define KUidMsgInternetMailEditorDLL	0x10003C53  // (268450899)
       
    49 #else
       
    50 	#define KUidMsgInternetMailEditorDLL	0x100011AC  // (268439980)
       
    51 #endif
       
    52 
       
    53 /**
       
    54 @internalTechnology
       
    55 */
       
    56 
       
    57 EXPORT_C CSmtpClientMtm* CSmtpClientMtm::NewL(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aMsvSession)
       
    58 	{
       
    59 	CSmtpClientMtm* self = new(ELeave) CSmtpClientMtm(aRegisteredMtmDll, aMsvSession);
       
    60 	CleanupStack::PushL(self);
       
    61 	self->ConstructL();
       
    62 	CleanupStack::Pop();
       
    63 	return self;
       
    64 	}
       
    65 
       
    66 CSmtpClientMtm::CSmtpClientMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aMsvSession)
       
    67 	: CBaseMtm(aRegisteredMtmDll, aMsvSession)
       
    68 	{
       
    69 	__DECLARE_NAME(_S("CSmtpClientMtm"));
       
    70 	}
       
    71 
       
    72 void CSmtpClientMtm::ConstructL()
       
    73 	{
       
    74 	iWait=CMsvOperationActiveSchedulerWait::NewLC();
       
    75 	CleanupStack::Pop();	// iWait
       
    76 
       
    77 	iImSmtpSettings = new (ELeave) CImSmtpSettings;
       
    78 	iHeader = CImHeader::NewLC();
       
    79 	CleanupStack::Pop();	// iHeader
       
    80 
       
    81 	//open the resource file
       
    82 	RResourceFile resourceFile;
       
    83 	OpenResourceFileL(resourceFile, Session().FileSession());
       
    84 	CleanupClosePushL(resourceFile);
       
    85 
       
    86 	HBufC8* buf = resourceFile.AllocReadLC(EMAIL_ADDRESS_FORMATTING_STRING);
       
    87 	TResourceReader reader;
       
    88 	reader.SetBuffer(buf);
       
    89 	iEmailAddressFormatString = (reader.ReadTPtrC()).AllocL();
       
    90 	CleanupStack::PopAndDestroy(2); // resourceFile (Close resourceFile), buf
       
    91 	}
       
    92 
       
    93 CSmtpClientMtm::~CSmtpClientMtm()
       
    94 /** Destructor. */
       
    95 	{
       
    96 	delete iWait;
       
    97 	delete iImSmtpSettings;
       
    98 	delete iHeader;
       
    99 	delete iSubject;
       
   100 	delete iEmailAddressFormatString;
       
   101 	delete iEntrySelection;
       
   102 	delete iImEmailOperation;
       
   103 	delete iAttachmentWaiter;
       
   104 	delete iEmailMessage;
       
   105 	}
       
   106 
       
   107 void CSmtpClientMtm::ResetData()
       
   108 	{
       
   109 	// The client MTM owns a number of objects which are used to store data
       
   110 	// from service settings and messages.
       
   111 	iAddresseeList->Reset();
       
   112 	iImSmtpSettings->Reset();
       
   113 	
       
   114 	delete iSubject;
       
   115 	iSubject = NULL;
       
   116 
       
   117 	iHeader->Reset();
       
   118 	Body().Reset();	// discard old contents of CRichText object
       
   119 	}
       
   120 
       
   121 void CSmtpClientMtm::SaveMessageL()
       
   122 /** Commits cached changes to the current message context to the storage controlled 
       
   123 by the Message Server. */
       
   124 	{
       
   125 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(ESmtcMTMNoCMsvEntrySet));
       
   126 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   127 	
       
   128 	StoreEmailMessageL();
       
   129 	}
       
   130 
       
   131 void CSmtpClientMtm::StoreEmailMessageL()
       
   132 	{
       
   133 	__ASSERT_DEBUG(KUidMsvMessageEntryValue==iMsvEntry->Entry().iType.iUid, gPanic(ESmtcMTMNotAMessageEntry));
       
   134 	CMsvStore* store = iMsvEntry->EditStoreL();
       
   135 	CleanupStack::PushL(store);
       
   136 
       
   137 	// Save the Email header stream...
       
   138 	iHeader->SetSubjectL(SubjectL());
       
   139 	const TInt numberOfRecipients=iAddresseeList->Count();
       
   140 	// put all addressees in the To: field...
       
   141 	for (TInt n=0 ; n < numberOfRecipients ; ++n)
       
   142 		{
       
   143 		// validation done by ValidateMessage()
       
   144 		switch(iAddresseeList->Type(n))
       
   145 			{
       
   146 		case EMsvRecipientTo:
       
   147 			iHeader->ToRecipients().AppendL(AddresseeList()[n]);
       
   148 			break;
       
   149 		case EMsvRecipientCc:
       
   150 			iHeader->CcRecipients().AppendL(AddresseeList()[n]);
       
   151 			break;
       
   152 		case EMsvRecipientBcc:
       
   153 			iHeader->BccRecipients().AppendL(AddresseeList()[n]);
       
   154 			break;
       
   155 			}
       
   156 		}
       
   157 
       
   158 	iHeader->StoreL(*store);
       
   159 	store->CommitL();
       
   160 
       
   161 	// NB the From field will be set by server MTM when the email message is sent
       
   162 
       
   163 	CleanupStack::PopAndDestroy();
       
   164 
       
   165 	TMsvEntry messageEntry=iMsvEntry->Entry();
       
   166 	CImEmailMessage* emailMessage = CImEmailMessage::NewLC(*iMsvEntry);
       
   167 
       
   168 	// now store the body text
       
   169 	emailMessage->StoreBodyTextL(messageEntry.Id(), Body(), iWait->iStatus);
       
   170 	iWait->Start();		// wait for the asynch operation to complete
       
   171 	
       
   172 	// 
       
   173 	// I have stored away all the email data,
       
   174 	// now update the TMsventry that represents
       
   175 	// the email to ensure that it is up to date
       
   176 	//
       
   177 	TInt32 totalSizeOfAllAttachments = GetAttachmentSizeL(*emailMessage, messageEntry.Id());
       
   178 
       
   179 	messageEntry.iSize = iHeader->DataSize() + Body().DocumentLength() + totalSizeOfAllAttachments;
       
   180 	messageEntry.iDescription.Set(iHeader->Subject());
       
   181 	messageEntry.iDate.UniversalTime();
       
   182 
       
   183 	// fix for DEF051564 - SMTP client MTM CreateMessageL not creating message in correct state
       
   184 	//
       
   185 	// since CreateMessageL creates message as in preparation and non-visible, the SaveMessageL
       
   186 	// must now make it visible and not in preparation
       
   187 	messageEntry.SetVisible(ETrue);
       
   188 	messageEntry.SetInPreparation(EFalse);
       
   189 
       
   190 	if (iHeader->ToRecipients().Count()>0)
       
   191 		messageEntry.iDetails.Set(iHeader->ToRecipients()[0]);
       
   192 	else if (iHeader->CcRecipients().Count())
       
   193 		messageEntry.iDetails.Set(iHeader->CcRecipients()[0]);
       
   194 	else if (iHeader->BccRecipients().Count())
       
   195 		messageEntry.iDetails.Set(iHeader->BccRecipients()[0]);
       
   196 	//else do nothing as there are no recipients yet!
       
   197 
       
   198 	if (totalSizeOfAllAttachments>0)
       
   199 		messageEntry.SetAttachment(ETrue);
       
   200 
       
   201 	// if there are multiple recipients then set the flag
       
   202 	if ((iHeader->ToRecipients().Count() + iHeader->CcRecipients().Count() + iHeader->BccRecipients().Count()) >=2)
       
   203 		messageEntry.SetMultipleRecipients(ETrue);
       
   204 
       
   205 	// update the contents of the message entry
       
   206 	iMsvEntry->ChangeL(messageEntry);
       
   207 
       
   208 	CleanupStack::PopAndDestroy();	// emailMessage
       
   209 	}
       
   210 
       
   211 EXPORT_C void CSmtpClientMtm::StoreSettingsL()
       
   212 /** Stores the current service settings from the object's cache in to the Central 
       
   213 Repository for the current entry.
       
   214 
       
   215 The current entry must be a service. */
       
   216 	{
       
   217 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue, gPanic(ESmtcMTMNotAServiceEntry));
       
   218 
       
   219 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   220   	TSmtpAccount id;
       
   221 	account->GetSmtpAccountL(iMsvEntry->Entry().Id(), id);
       
   222 	account->SaveSmtpSettingsL(id, *iImSmtpSettings);
       
   223 	CleanupStack::PopAndDestroy(account);    
       
   224 	}
       
   225 
       
   226 EXPORT_C void CSmtpClientMtm::RestoreSettingsL()
       
   227 /** Loads into the object's cache the service settings from the Central Repository
       
   228 for the current entry. */
       
   229 	{
       
   230 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvServiceEntryValue, gPanic(ESmtcMTMNotAServiceEntry));
       
   231 
       
   232 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   233   	TSmtpAccount id;
       
   234 	account->GetSmtpAccountL(iMsvEntry->Entry().Id(), id);
       
   235 	account->LoadSmtpSettingsL(id, *iImSmtpSettings);
       
   236 	CleanupStack::PopAndDestroy(account);    
       
   237 	}
       
   238 
       
   239 void CSmtpClientMtm::LoadMessageL()
       
   240 /** Loads the cache with the message data for the current context. */
       
   241 	{
       
   242 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(ESmtcMTMNoCMsvEntrySet));
       
   243 	switch (iMsvEntry->Entry().iType.iUid)
       
   244 		{
       
   245 		case KUidMsvServiceEntryValue:
       
   246 			RestoreSettingsL();
       
   247 			break;
       
   248 		case KUidMsvMessageEntryValue:
       
   249 			RestoreEmailMessageL();
       
   250 			break;
       
   251 		};
       
   252 	}	
       
   253 
       
   254 void CSmtpClientMtm::RestoreEmailMessageL()
       
   255 	{
       
   256 
       
   257 	// Get a reference to TMsvEnhanceSearchSortUtil  instance set by CMsvSearchsortOpOnHeaderBody class
       
   258 	// If advanced search and sort is being performed than do not load the message header and body.
       
   259 	// These are loaded when the search criteria is known in DoFindL()
       
   260 	// For API's other than CMsvSearchsortOpOnHeaderBody-> FindInHeaderBodyL(), a call to LoadMessageL()
       
   261 	// loads the body and the header.
       
   262 
       
   263 	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   264 	if ( searchsortutil == NULL )
       
   265 		{
       
   266 		CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   267 		CleanupStack::PushL(msvStore);
       
   268 
       
   269 		// message must have a CImHeader stream...if it's not there leave as there's something wrong
       
   270 		iHeader->RestoreL(*msvStore);
       
   271 
       
   272 		TPtrC subject = iHeader->Subject();
       
   273 		TPtrC to;
       
   274 		if (iHeader->ToRecipients().Count())
       
   275 			to.Set(iHeader->ToRecipients()[0]);
       
   276 		else if (iHeader->CcRecipients().Count())
       
   277 			to.Set(iHeader->CcRecipients()[0]);
       
   278 		else if (iHeader->BccRecipients().Count())
       
   279 			to.Set(iHeader->BccRecipients()[0]);
       
   280 	//else do nothing as there are no recipients!
       
   281 
       
   282 		SetSubjectL(subject);
       
   283 		SetAddresseeListL();
       
   284 
       
   285 		// Get the attachments and the body text...
       
   286 		TMsvEntry messageEntry=iMsvEntry->Entry();
       
   287 
       
   288 		CleanupStack::PopAndDestroy(); // msvStore
       
   289 		CImEmailMessage* emailMessage = CImEmailMessage::NewLC(*iMsvEntry);
       
   290 
       
   291 		GetBodyTextL(*emailMessage, messageEntry.Id());
       
   292 		TInt32 totalSizeOfAllAttachments = GetAttachmentSizeL(*emailMessage, messageEntry.Id());
       
   293 
       
   294 		messageEntry.iSize = iHeader->DataSize() + Body().DocumentLength() + totalSizeOfAllAttachments;
       
   295 		messageEntry.iDescription.Set(subject);
       
   296 		messageEntry.iDetails.Set(to);
       
   297 
       
   298 	// update the contents of the message entry
       
   299 		iMsvEntry->ChangeL(messageEntry);
       
   300 	
       
   301 		CleanupStack::PopAndDestroy(); // emailMessage
       
   302 	
       
   303 		}
       
   304 	}
       
   305 
       
   306 
       
   307 void CSmtpClientMtm::GetBodyTextL(CImEmailMessage& aMessage, TMsvId aMsvId)
       
   308 	{
       
   309 	CRichText* messageText = CRichText::NewL(iParaFormatLayer, iCharFormatLayer);
       
   310 	CleanupStack::PushL(messageText);
       
   311 
       
   312 	aMessage.GetBodyTextL(aMsvId, CImEmailMessage::EThisMessageOnly, *messageText,*iParaFormatLayer,*iCharFormatLayer);
       
   313 
       
   314 	Body().Reset();
       
   315 	Body().AppendTakingSolePictureOwnershipL(*messageText);
       
   316 
       
   317 	CleanupStack::PopAndDestroy();
       
   318 	}
       
   319 
       
   320 TInt32 CSmtpClientMtm::GetAttachmentSizeL(CImEmailMessage& aMessage, TMsvId aMsvId)
       
   321 	{
       
   322 	// Calculate the total size of all attachments associated with this message
       
   323 	TInt total=0;
       
   324 	aMessage.GetAttachmentsListL(iWait->iStatus, aMsvId, CImEmailMessage::EAllAttachments,CImEmailMessage::EThisMessageOnly);
       
   325 	iWait->Start();		// wait for the asynch operation to complete
       
   326 	TInt numAttachments=aMessage.AttachmentManager().AttachmentCount();
       
   327 	for (TInt n=0 ; n<numAttachments ; ++n)
       
   328 		{
       
   329 		CMsvAttachment* attachment = aMessage.AttachmentManager().GetAttachmentInfoL(n);
       
   330 		total+=attachment->Size();
       
   331 		delete attachment;
       
   332 		}
       
   333 	return total;
       
   334 	}
       
   335 
       
   336 CMsvOperation* CSmtpClientMtm::ReplyL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   337 /** Creates a reply message to the current message context. 
       
   338 
       
   339 @return	If successful, this is an asynchronously completing reply operation. 
       
   340 If failed, this is a completed operation, with status set to the relevant error code. 
       
   341 @param aDestination The entry to which to assign the reply 
       
   342 @param aPartList Defines the parts that are to be copied from the original message into the reply 
       
   343 @param aCompletionStatus The request status to be completed when the operation has finished 
       
   344 */
       
   345 	{
       
   346 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   347 	TUid messageType = KUidMsgTypeSMTP;
       
   348 	return CImEmailOperation::CreateReplyL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   349 	}
       
   350 
       
   351 CMsvOperation* CSmtpClientMtm::ForwardL(TMsvId aDestination, TMsvPartList aPartList, TRequestStatus& aCompletionStatus)
       
   352 /** Creates a forwarded message from the current message context. 
       
   353 
       
   354 @return	If successful, this is an asynchronously completing forward message operation. 
       
   355 If failed, this is a completed operation, with status set to the relevant error code. 		
       
   356 @param aDestination The entry to which to assign the forwarded message 
       
   357 @param aPartList Defines the parts that are to be copied from the original message into the forwarded message 
       
   358 @param aCompletionStatus The request status to be completed when the operation has finished 
       
   359 */
       
   360 	{
       
   361 	TMsvEmailTypeList msvEmailTypeList = 0;
       
   362 	TUid messageType = KUidMsgTypeSMTP;
       
   363 	return CImEmailOperation::CreateForwardL(aCompletionStatus, Session(), iMsvEntry->EntryId(), aDestination, aPartList, msvEmailTypeList, messageType);
       
   364 	}
       
   365 
       
   366 EXPORT_C void CSmtpClientMtm::SetSubjectL(const TDesC& aSubject)
       
   367 /** Sets the message context's subject text.
       
   368 
       
   369 @param aSubject Subject text */
       
   370 	{
       
   371 	HBufC* newSubject= aSubject.AllocL();
       
   372 	delete iSubject;
       
   373 	iSubject = newSubject;	
       
   374 	}
       
   375 
       
   376 EXPORT_C const TPtrC CSmtpClientMtm::SubjectL() const
       
   377 /** Gets the message context's subject text.
       
   378 
       
   379 @return Subject text */
       
   380 	{
       
   381 	// NB won't ever leave
       
   382 	return (iSubject) ? TPtrC(*iSubject) : TPtrC();
       
   383 	}
       
   384 
       
   385 TMsvPartList CSmtpClientMtm::ValidateMessage(TMsvPartList aPartList)
       
   386 /** Validates the current message context.
       
   387 
       
   388 The addresses for the message are checked to be well-formed email addresses.
       
   389 
       
   390 @param aPartList Indicates the message parts for which validation is requested 
       
   391 @return If valid, KErrNone If invalid, identifies the invalid part(s). The 
       
   392 error value is the bitmask of the TMsvPartList IDs for each invalid part */
       
   393 	{
       
   394 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(ESmtcMTMNoCMsvEntrySet));
       
   395 
       
   396 	TMsvPartList failed(0);
       
   397 	if (aPartList & KMsvMessagePartRecipient)
       
   398 		{
       
   399 		if (iAddresseeList->Count() == 0)
       
   400 			failed |= KMsvMessagePartRecipient;
       
   401 		else
       
   402 			{
       
   403 			// check the recipient list for valid 'addresses'
       
   404 			for (TInt ii=0; ii < iAddresseeList->Count(); ++ii)
       
   405 				{
       
   406 				if (((*iAddresseeList)[ii].Length() == 0) || !ValidateAddress((*iAddresseeList)[ii]))
       
   407 					{
       
   408 					failed |= KMsvMessagePartRecipient;
       
   409 					break;
       
   410 					}
       
   411 				}
       
   412 			}
       
   413 		}
       
   414 	return failed;
       
   415 	}
       
   416 
       
   417 TBool CSmtpClientMtm::ValidateAddress(const TPtrC& anAddress)
       
   418 	{
       
   419 	return iTImMessageField.ValidInternetEmailAddress(anAddress);
       
   420 	}
       
   421 
       
   422 TMsvPartList CSmtpClientMtm::DoFindL(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   423 	{
       
   424 	CImClientMTMUtils* clientMTMUtils = CImClientMTMUtils::NewL();
       
   425 	CleanupStack::PushL(clientMTMUtils);
       
   426 
       
   427 	TMsvPartList retList = KMsvMessagePartNone;
       
   428 	
       
   429 	// Get a reference to TMsvEnhanceSearchSortUtil instance set by CMsvSearchsortOpOnHeaderBody class	
       
   430 	TMsvEnhanceSearchSortUtil* searchsortutil = (TMsvEnhanceSearchSortUtil*)(GetExtensionData());
       
   431 	
       
   432 	// searchsortuitl variable will not be NULL for Advanced Search and Sort called from CMsvSearchsortOpOnHeaderBody
       
   433  	// For the old implementation, it will be NULL
       
   434 	if(searchsortutil != NULL)
       
   435 		{
       
   436 		// Get the searchsort setting flags
       
   437 		TUint32 searchsortsetting=searchsortutil->GetSearchSortSetting();
       
   438 		
       
   439 		// The body was not loaded in LoadMessageL()
       
   440  		// If 2 search query options are on the body or on the header, than it sets EMessagePartBodyLoaded flag
       
   441  		// or EMessagePartHeaderLoaded of searchsortsetting
       
   442 		if(aPartList & KMsvMessagePartBody && !(searchsortsetting & EMessagePartBodyLoaded))  	
       
   443    			{
       
   444    			// Restore the body
       
   445    			
       
   446 			Body().Reset();	
       
   447 			// Get the attachments and the body text...
       
   448 			TMsvEntry messageEntry=iMsvEntry->Entry();
       
   449 			CImEmailMessage* emailMessage = CImEmailMessage::NewLC(*iMsvEntry);
       
   450 			GetBodyTextL(*emailMessage, messageEntry.Id());
       
   451 			CleanupStack::PopAndDestroy(); // emailMessage
       
   452 			searchsortutil->SetSearchSortSetting(EMessagePartBodyLoaded);
       
   453 			}
       
   454 		else if (!(searchsortsetting & EMessagePartHeaderLoaded))
       
   455 			{
       
   456 			// Restore the header
       
   457 			CMsvStore* msvStore = iMsvEntry->ReadStoreL();
       
   458 			CleanupStack::PushL(msvStore);
       
   459 
       
   460 			// message must have a CImHeader stream...if it's not there leave as there's something wrong
       
   461 			iHeader->RestoreL(*msvStore);
       
   462 
       
   463 			TPtrC subject = iHeader->Subject();
       
   464 			TPtrC to;
       
   465 			if (iHeader->ToRecipients().Count())
       
   466 				to.Set(iHeader->ToRecipients()[0]);
       
   467 			else if (iHeader->CcRecipients().Count())
       
   468 				to.Set(iHeader->CcRecipients()[0]);
       
   469 			else if (iHeader->BccRecipients().Count())
       
   470 				to.Set(iHeader->BccRecipients()[0]);
       
   471 			//else do nothing as there are no recipients!
       
   472 
       
   473 			SetSubjectL(subject);
       
   474 			SetAddresseeListL();
       
   475 
       
   476 			// Get the attachments and the body text...
       
   477 			TMsvEntry messageEntry=iMsvEntry->Entry();
       
   478 
       
   479 			CleanupStack::PopAndDestroy(); // msvStore
       
   480 			searchsortutil->SetSearchSortSetting(EMessagePartHeaderLoaded);
       
   481 			}
       
   482 			
       
   483 		// Issue a request to FindL
       
   484 		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);
       
   485 		
       
   486 		/* Copy the sort data if sorting is specified.
       
   487 		 The operations being performed could be only be sort or it could be search and sort
       
   488 		 If the operation is search and sort than copy the sort data only if the
       
   489 		 search operation succeeded	*/
       
   490 		 
       
   491 		if ((searchsortsetting & EMessagePartSort ) || (((searchsortsetting & EMessagePartSearchSort) && (searchsortsetting & EMessagePartLastQueryOption) && (retList))))
       
   492    			{
       
   493    			/* Copy the data to be sorted from the header stream.
       
   494    			   This done by setting iExtensionData to point to the field being copied */
       
   495    			   
       
   496 	   		if (iHeader)
       
   497    				{
       
   498    				if (searchsortsetting & EMessagePartToSort )
       
   499    					{
       
   500    					SetExtensionData((TAny*)&iHeader->ToRecipients());
       
   501 	   				}
       
   502    				else if(searchsortsetting & EMessagePartCcSort)
       
   503    					{
       
   504    					SetExtensionData((TAny*)&iHeader->CcRecipients());
       
   505    					}
       
   506    				else if(searchsortsetting & EMessagePartBccSort)
       
   507  	 	  			{
       
   508     				SetExtensionData((TAny*)&iHeader->BccRecipients());
       
   509     				}
       
   510     			else if(searchsortsetting & EMessagePartFromSort)
       
   511     				{
       
   512     				SetExtensionData((TAny*)(iHeader->From().Ptr()));
       
   513     				}
       
   514 				else if(searchsortsetting & EMessagePartSubjectSort)
       
   515 					{
       
   516 					SetExtensionData((TAny*)(iHeader->Subject().Ptr()));
       
   517 					}
       
   518     			}
       
   519    			}
       
   520 		}
       
   521 	else
       
   522 		{
       
   523 
       
   524 		clientMTMUtils->FindL(aTextToFind, Body(), *iHeader, aPartList, retList);	
       
   525 		}
       
   526     CleanupStack::PopAndDestroy(clientMTMUtils); 
       
   527 	return retList;
       
   528 	}
       
   529 
       
   530 TMsvPartList CSmtpClientMtm::Find(const TDesC& aTextToFind, TMsvPartList aPartList)
       
   531 /** Searches the specified message part(s) for the plain-text version of the text 
       
   532 to be found.
       
   533 
       
   534 @param aTextToFind The plain-text version of the text to be found. 
       
   535 @param aPartList Indicates the message parts which should be searched. 
       
   536 @return If the text was not found, or searching is unsupported, 0. If the text 
       
   537 was found, a bitmask of the TMsvPartList IDs for each part in which the text 
       
   538 was present. */
       
   539 	{
       
   540  	TMsvPartList retList = KMsvMessagePartNone;
       
   541  	TRAPD(ret, retList = DoFindL(aTextToFind, aPartList));
       
   542    	return retList;
       
   543 	}
       
   544 
       
   545 void CSmtpClientMtm::AddAddresseeL(const TDesC& aRealAddress)
       
   546 /** Adds an addressee for the current context.
       
   547 
       
   548 @param aRealAddress String representing an address to be added to the list 
       
   549 for the current message */
       
   550 	{
       
   551 	iAddresseeList->AppendL(EMsvRecipientTo, aRealAddress);
       
   552 	}
       
   553 
       
   554 void CSmtpClientMtm::SetAddresseeListL()
       
   555 	{
       
   556 	// fill in the addressee list from the contents of iHeader
       
   557 	// copy all of the recipient addresses into the addressee list
       
   558 
       
   559 	iAddresseeList->Reset();
       
   560 	TInt numberOfRecipients=iHeader->ToRecipients().Count();
       
   561 	TInt n;
       
   562 	for (n=0 ; n < numberOfRecipients ; ++n)
       
   563 		{
       
   564 		TPtrC addressWithoutAlias = iTImMessageField.GetValidInternetEmailAddressFromString(iHeader->ToRecipients()[n]);
       
   565 		AddAddresseeL(EMsvRecipientTo, addressWithoutAlias);
       
   566 		}
       
   567 
       
   568 	numberOfRecipients=iHeader->CcRecipients().Count();
       
   569 	for (n=0 ; n < numberOfRecipients ; ++n)
       
   570 		{
       
   571 		TPtrC addressWithoutAlias = iTImMessageField.GetValidInternetEmailAddressFromString(iHeader->CcRecipients()[n]);
       
   572 		AddAddresseeL(EMsvRecipientCc, addressWithoutAlias);
       
   573 		}
       
   574 
       
   575 	// there shouldn't be any Bcc: addresses in an incoming email
       
   576 	// but add them anyway?
       
   577 	numberOfRecipients=iHeader->BccRecipients().Count();
       
   578 	for (n=0 ; n < numberOfRecipients ; ++n)
       
   579 		{
       
   580 		TPtrC addressWithoutAlias = iTImMessageField.GetValidInternetEmailAddressFromString(iHeader->BccRecipients()[n]);
       
   581 		AddAddresseeL(EMsvRecipientBcc, addressWithoutAlias);
       
   582 		}
       
   583 	}
       
   584 
       
   585 void CSmtpClientMtm::AddAddresseeL(const TDesC& aRealAddress, const TDesC& aAlias)
       
   586 /** Adds an addressee with an alias for the current context.
       
   587 
       
   588 @param aRealAddress String representing an address to be added to the list 
       
   589 for the current message 
       
   590 @param aAlias Alias information */
       
   591 	{
       
   592 	HBufC* emailAddress = HBufC::NewLC(aRealAddress.Length()+aAlias.Length()+iEmailAddressFormatString->Length()-4);
       
   593 	emailAddress->Des().Format(*iEmailAddressFormatString,&aAlias,&aRealAddress);
       
   594 	iAddresseeList->AppendL(EMsvRecipientTo, *emailAddress);
       
   595 	CleanupStack::PopAndDestroy();	// emailAddress
       
   596 	}
       
   597 
       
   598 void CSmtpClientMtm::RemoveAddressee(TInt aIndex)
       
   599 /** Removes an address from the current address list.
       
   600 
       
   601 @param aIndex Index of address to be removed */
       
   602 	{
       
   603 	if (iAddresseeList->Count() > aIndex)
       
   604 		iAddresseeList->Delete(aIndex);
       
   605 	}
       
   606 
       
   607 void CSmtpClientMtm::AddAddresseeL(TMsvRecipientType aType, const TDesC& aRealAddress)
       
   608 	{
       
   609 	iAddresseeList->AppendL(aType, aRealAddress);
       
   610 	}
       
   611 
       
   612 void CSmtpClientMtm::AddAddresseeL(TMsvRecipientType aType, const TDesC& aRealAddress, const TDesC& aAlias)
       
   613 	{
       
   614 	HBufC* emailAddress = HBufC::NewLC(aRealAddress.Length()+aAlias.Length()+iEmailAddressFormatString->Length()-4);
       
   615 	emailAddress->Des().Format(*iEmailAddressFormatString,&aAlias,&aRealAddress);
       
   616 	iAddresseeList->AppendL(aType, *emailAddress);
       
   617 	CleanupStack::PopAndDestroy(emailAddress);
       
   618 	}
       
   619 	
       
   620 void CSmtpClientMtm::ContextEntrySwitched()
       
   621 	{
       
   622 	ResetData();
       
   623 	}
       
   624 
       
   625 TInt CSmtpClientMtm::QueryCapability(TUid aCapability, TInt& aResponse)
       
   626 /** Queries if the MTM supports a particular capability, specified by a UID.
       
   627 
       
   628 @param aCapability UID of capability to be queried 
       
   629 @param aResponse Response value. The format of the response varies according 
       
   630 to the capability. 
       
   631 @return KErrNone: aCapability is a recognised value and a response is returned 
       
   632 KErrNotSupported: aCapability is not a recognised value */
       
   633 	{
       
   634 	TInt error = KErrNone;
       
   635 	switch (aCapability.iUid)
       
   636 		{
       
   637 	// Supported:
       
   638 	case KUidMtmQueryMaxBodySizeValue:
       
   639 	case KUidMtmQueryMaxTotalMsgSizeValue:
       
   640 		aResponse = KMaxTInt;
       
   641 		break;
       
   642 	case KUidMsvMtmQueryEditorUidValue:
       
   643 		aResponse = KUidMsgInternetMailEditorDLL;
       
   644 		break;
       
   645 	case KUidMtmQuerySupportedBodyValue:
       
   646 		aResponse = KMtm7BitBody + KMtm8BitBody + KMtm16BitBody + KMtmBinaryBody;
       
   647 		break;
       
   648 	case KUidMtmQuerySupportSubjectValue:
       
   649 	case KUidMtmQuerySupportAttachmentsValue:
       
   650 	case KUidMtmQueryCanSendMsgValue:
       
   651 	case KUidMtmQuerySupportsRecipientTypeValue:
       
   652 	case KUidMtmQuerySendAsMessageSendSupportValue:
       
   653 		break;
       
   654 	// All others - Not Supported:
       
   655 	default:
       
   656 		error = KErrNotSupported;
       
   657 		}
       
   658 	return error;
       
   659 	}
       
   660 
       
   661 EXPORT_C void CSmtpClientMtm::SetSettingsL(const CImSmtpSettings& aSettings)
       
   662 /** Copies the specified service settings to the cached service settings.
       
   663 
       
   664 @param aSettings New service settings */
       
   665 	{
       
   666 	iImSmtpSettings->CopyL(aSettings);
       
   667 	}
       
   668 
       
   669 EXPORT_C const CImSmtpSettings& CSmtpClientMtm::Settings() const
       
   670 /** Gets the current cached service settings.
       
   671 
       
   672 @return The current cached service settings */
       
   673 	{
       
   674 	__ASSERT_DEBUG(iImSmtpSettings!=NULL, User::Invariant());
       
   675 	return *iImSmtpSettings;
       
   676 	}
       
   677 
       
   678 void CSmtpClientMtm::InvokeSyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection, TDes8& aParameter)
       
   679 /** Invokes a synchronous SMTP-specific operation.
       
   680 
       
   681 @param aFunctionId Specifies which operation to perform. The only valid ID is KSMTPMTMIsConnected.
       
   682 @param aSelection A selection of messages for the operation.
       
   683 @param aParameter Not used
       
   684 */
       
   685 	{
       
   686 	__ASSERT_DEBUG(iMsvEntry!=NULL,gPanic(ESmtcMTMNoCMsvEntrySet));
       
   687 
       
   688 	TInt error = KErrNone;
       
   689 	switch (aFunctionId)
       
   690 		{
       
   691 		case KSMTPMTMIsConnected:
       
   692 			{
       
   693 			TPckgBuf<TImSmtpProgress> progress;
       
   694 			Session().TransferCommandL(aSelection, KSMTPMTMIsConnected, aParameter, progress);
       
   695 			aParameter.Copy(progress);
       
   696 			return;
       
   697 			}
       
   698 		default:
       
   699 			error=KErrNotSupported;
       
   700 			__ASSERT_DEBUG(EFalse,gPanic(ESmtcUnknownSyncFunction));
       
   701 		}
       
   702 
       
   703 	User::LeaveIfError(error);
       
   704 	}
       
   705 
       
   706 CMsvOperation* CSmtpClientMtm::InvokeAsyncFunctionL(TInt aFunctionId, const CMsvEntrySelection& aSelection,
       
   707 													TDes8& aParameter, TRequestStatus& aCompletionStatus)
       
   708 /** Invokes asynchronous SMTP-specific operations.
       
   709 
       
   710 @param aFunctionId Specifies which operation to perform e.g. connect, copy 
       
   711 new mail etc. The specific operations are defined by the TSmtpCmds enumeration. 
       
   712 @param aSelection A selection of messages that need to be copied/moved to a 
       
   713 local folder. The first entry in this selection MUST be the service. 
       
   714 @param aParameter Not used
       
   715 @param aCompletionStatus The status when the operation completes. 
       
   716 @leave KErrNotFound The selection of email to be moved or copied is empty
       
   717 @leave KErrNotSupported The specified operation is not recognised
       
   718 @return If successful, this is an asynchronously completing operation. If failed, 
       
   719 this is a completed operation, with status set to the relevant error code. 
       
   720 @see TSmtpCmds */
       
   721 	{
       
   722 	switch(aFunctionId)
       
   723 		{
       
   724 	case KMTMStandardFunctionsSendMessage:
       
   725 		return CMsvSmtpProgressOperation::NewL(Session(), aSelection, KSMTPMTMSendOnNextConnection, aParameter, aCompletionStatus);
       
   726 	case KSMTPMTMSendOnNextConnection:
       
   727 		return (Session().TransferCommandL(aSelection, aFunctionId, aParameter, aCompletionStatus));
       
   728 	case KSMTPMTMCreateNewEmailMessage:
       
   729 	case KSMTPMTMCreateReplyEmailMessage:
       
   730 	case KSMTPMTMCreateForwardEmailMessage:
       
   731 	case KSMTPMTMCreateForwardAsAttachmentEmailMessage:
       
   732 	case KSMTPMTMCreateReceiptEmailMessage:
       
   733 		{
       
   734 		TImCreateMessageOptions createMessageOptions;	
       
   735 		TPckgC<TImCreateMessageOptions> paramPack(createMessageOptions);
       
   736 		paramPack.Set(aParameter);
       
   737 		switch (aFunctionId)
       
   738 			{
       
   739 		case KSMTPMTMCreateNewEmailMessage:
       
   740 			return iImEmailOperation->CreateNewL(aCompletionStatus, iMsvEntry->Session(), aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   741 		case KSMTPMTMCreateReplyEmailMessage:
       
   742 			return iImEmailOperation->CreateReplyL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   743 		case KSMTPMTMCreateForwardEmailMessage:
       
   744 			return iImEmailOperation->CreateForwardL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   745 		case KSMTPMTMCreateForwardAsAttachmentEmailMessage:
       
   746 			return iImEmailOperation->CreateForwardAsAttachmentL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   747 		case KSMTPMTMCreateReceiptEmailMessage:
       
   748 			return iImEmailOperation->CreateReceiptL(aCompletionStatus, iMsvEntry->Session(), aSelection[1], aSelection[0], paramPack().iMsvPartList, paramPack().iMsvEmailTypeList, paramPack().iMessageType);
       
   749 			}
       
   750 		}
       
   751 	break;
       
   752 	default:
       
   753 		User::Leave(KErrNotSupported);
       
   754 		};
       
   755 	return NULL;
       
   756 	}
       
   757 
       
   758 // Attachment functions to support the SendAs API
       
   759 
       
   760 EXPORT_C void CSmtpClientMtm::AddAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
       
   761 	{
       
   762 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   763 
       
   764 	if( iAttachmentWaiter == NULL )
       
   765 		{
       
   766 		iAttachmentWaiter = CImAttachmentWaiter::NewL();
       
   767 		}	
       
   768 
       
   769 	if (iEmailMessage == NULL)
       
   770 		{		
       
   771 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   772 		}
       
   773 	else if (iEmailMessage->EmailEntryId() != iMsvEntry->EntryId())
       
   774 		{
       
   775 		delete iEmailMessage;
       
   776 		iEmailMessage = NULL;
       
   777 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   778 		}
       
   779 
       
   780 	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
       
   781 	CleanupStack::PushL(attachmentInfo);
       
   782 	
       
   783 	attachmentInfo->SetMimeTypeL(aMimeType);
       
   784 	TParse fileNameParser;
       
   785 	User::LeaveIfError(fileNameParser.Set(aFilePath, NULL, NULL));
       
   786 	attachmentInfo->SetAttachmentNameL(fileNameParser.NameAndExt());
       
   787 	if( aCharset!=0 )
       
   788 		{
       
   789 		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
       
   790 		headers->SetMimeCharset(aCharset);
       
   791 		headers->StoreL(*attachmentInfo);
       
   792 		CleanupStack::PopAndDestroy(headers);
       
   793 		}
       
   794 
       
   795 	iEmailMessage->AttachmentManager().AddAttachmentL(aFilePath, attachmentInfo, iAttachmentWaiter->iStatus);
       
   796 	CleanupStack::Pop(attachmentInfo);// ownership passed to attachment manager
       
   797 	
       
   798 	iAttachmentWaiter->StartWaitingL(aStatus, iEmailMessage, EFalse);
       
   799 	}
       
   800 	
       
   801 EXPORT_C void CSmtpClientMtm::AddAttachmentL(RFile& aFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
       
   802 	{
       
   803 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   804 
       
   805 	if( iAttachmentWaiter == NULL )
       
   806 		{
       
   807 		iAttachmentWaiter = CImAttachmentWaiter::NewL();
       
   808 		}
       
   809 	
       
   810 	if (iEmailMessage == NULL)
       
   811 		{		
       
   812 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   813 		}
       
   814 	else if (iEmailMessage->EmailEntryId() != iMsvEntry->EntryId())
       
   815 		{
       
   816 		delete iEmailMessage;
       
   817 		iEmailMessage = NULL;
       
   818 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   819 		}
       
   820 
       
   821 	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
       
   822 	CleanupStack::PushL(attachmentInfo);
       
   823 	
       
   824 	attachmentInfo->SetMimeTypeL(aMimeType);
       
   825 	TFileName fileName;	
       
   826 	aFile.Name(fileName);
       
   827 	attachmentInfo->SetAttachmentNameL(fileName);
       
   828 	if( aCharset!=0 )
       
   829 		{
       
   830 		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
       
   831 		headers->SetMimeCharset(aCharset);
       
   832 		headers->StoreL(*attachmentInfo);
       
   833 		CleanupStack::PopAndDestroy(headers);
       
   834 		}
       
   835 	
       
   836 	iEmailMessage->AttachmentManager().AddAttachmentL(aFile, attachmentInfo, iAttachmentWaiter->iStatus);
       
   837 	CleanupStack::Pop(attachmentInfo);// ownership passed to attachment manager	
       
   838 
       
   839 	iAttachmentWaiter->StartWaitingL(aStatus, iEmailMessage, EFalse);
       
   840 	}
       
   841 	
       
   842 EXPORT_C void CSmtpClientMtm::AddLinkedAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
       
   843 	{
       
   844 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   845 
       
   846 	if( iAttachmentWaiter == NULL )
       
   847 		{
       
   848 		iAttachmentWaiter = CImAttachmentWaiter::NewL();
       
   849 		}
       
   850 
       
   851 	if (iEmailMessage == NULL)
       
   852 		{		
       
   853 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   854 		}
       
   855 	else if (iEmailMessage->EmailEntryId() != iMsvEntry->EntryId())
       
   856 		{
       
   857 		delete iEmailMessage;
       
   858 		iEmailMessage = NULL;
       
   859 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   860 		}
       
   861 	
       
   862 	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvLinkedFile);
       
   863 	CleanupStack::PushL(attachmentInfo);
       
   864 	
       
   865 	attachmentInfo->SetMimeTypeL(aMimeType);
       
   866 	
       
   867 	TParse fileNameParser;
       
   868 	User::LeaveIfError(fileNameParser.Set(aFilePath, NULL, NULL));
       
   869 	attachmentInfo->SetAttachmentNameL(fileNameParser.NameAndExt());
       
   870 
       
   871 	if( aCharset!=0 )
       
   872 		{
       
   873 		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
       
   874 		headers->SetMimeCharset(aCharset);
       
   875 		headers->StoreL(*attachmentInfo);
       
   876 		CleanupStack::PopAndDestroy(headers);
       
   877 		}
       
   878 	
       
   879 	iEmailMessage->AttachmentManager().AddLinkedAttachmentL(aFilePath, attachmentInfo, iAttachmentWaiter->iStatus);
       
   880 	CleanupStack::Pop(attachmentInfo);// ownership passed to attachment manager	
       
   881 
       
   882 	iAttachmentWaiter->StartWaitingL(aStatus, iEmailMessage, EFalse);
       
   883 	}
       
   884 	
       
   885 EXPORT_C void CSmtpClientMtm::AddEntryAsAttachmentL(TMsvId aAttachmentId, TRequestStatus& aStatus)
       
   886 	{
       
   887 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   888 
       
   889 	if( iAttachmentWaiter == NULL )
       
   890 		{
       
   891 		iAttachmentWaiter = CImAttachmentWaiter::NewL();
       
   892 		}
       
   893 
       
   894 	if (iEmailMessage == NULL)
       
   895 		{		
       
   896 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   897 		}
       
   898 	else if (iEmailMessage->EmailEntryId() != iMsvEntry->EntryId())
       
   899 		{
       
   900 		delete iEmailMessage;
       
   901 		iEmailMessage = NULL;
       
   902 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   903 		}
       
   904 	
       
   905 	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvMessageEntry);
       
   906 	CleanupStack::PushL(attachmentInfo);
       
   907 
       
   908 	iEmailMessage->AttachmentManager().AddEntryAsAttachmentL(aAttachmentId, attachmentInfo, iAttachmentWaiter->iStatus);
       
   909 	CleanupStack::Pop(attachmentInfo);// ownership passed to attachment manager	
       
   910 	
       
   911 	iAttachmentWaiter->StartWaitingL(aStatus, iEmailMessage, EFalse);
       
   912 	}
       
   913 
       
   914 EXPORT_C void CSmtpClientMtm::CreateAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
       
   915 	{
       
   916 	__ASSERT_DEBUG(iMsvEntry->Entry().iType.iUid==KUidMsvMessageEntryValue, gPanic(ESmtcMTMNotAMessageEntry));
       
   917 	
       
   918 	if( iAttachmentWaiter == NULL )
       
   919 		{
       
   920 		iAttachmentWaiter = CImAttachmentWaiter::NewL();
       
   921 		}
       
   922 
       
   923 	if (iEmailMessage == NULL)
       
   924 		{		
       
   925 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   926 		}
       
   927 	else if (iEmailMessage->EmailEntryId() != iMsvEntry->EntryId())
       
   928 		{
       
   929 		delete iEmailMessage;
       
   930 		iEmailMessage = NULL;
       
   931 		iEmailMessage = CImEmailMessage::NewL(*iMsvEntry);
       
   932 		}
       
   933 
       
   934 	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
       
   935 	CleanupStack::PushL(attachmentInfo);
       
   936 
       
   937 	attachmentInfo->SetAttachmentNameL(aFileName);
       
   938 	attachmentInfo->SetMimeTypeL(aMimeType);
       
   939 	
       
   940 	if( aCharset!=0 )
       
   941 		{
       
   942 		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
       
   943 		headers->SetMimeCharset(aCharset);
       
   944 		headers->StoreL(*attachmentInfo);
       
   945 		CleanupStack::PopAndDestroy(headers);
       
   946 		}
       
   947 
       
   948 	iEmailMessage->AttachmentManager().CreateAttachmentL(aFileName, aAttachmentFile, attachmentInfo, iAttachmentWaiter->iStatus);
       
   949 	CleanupStack::Pop(attachmentInfo);// ownership passed to attachment manager	
       
   950 	
       
   951 	iAttachmentWaiter->StartWaitingL(aStatus, iEmailMessage, EFalse);
       
   952 	}
       
   953 
       
   954 
       
   955 EXPORT_C void CSmtpClientMtm::CreateMessageL(TMsvId aServiceId)
       
   956 /** Creates a new message entry as a child of the current context.
       
   957 
       
   958 @param aServiceId ID of the service to own the entry. */
       
   959 	{
       
   960 	// fix for DEF051564 - SMTP client MTM CreateMessageL not creating message in correct state
       
   961 	TMsvEmailTypeList emailTypeList = KMsvEmailTypeListInvisibleMessage | KMsvEmailTypeListMessageInPreparation;
       
   962 
       
   963 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
   964 	
       
   965 	CImSmtpSettings* smtpSettings = new (ELeave) CImSmtpSettings;
       
   966 	CleanupStack::PushL(smtpSettings);
       
   967   	TSmtpAccount id;
       
   968 	account->GetSmtpAccountL(aServiceId, id);
       
   969 	account->LoadSmtpSettingsL(id, *smtpSettings);
       
   970 	
       
   971 	switch (smtpSettings->BodyEncoding())
       
   972 		{
       
   973 		case EMsgOutboxMHTMLAsMIME:
       
   974 		case EMsgOutboxMHTMLAlternativeAsMIME:
       
   975 			emailTypeList |= KMsvEmailTypeListMHTMLMessage;
       
   976 			break;
       
   977 		case EMsgOutboxDefault:
       
   978 		case EMsgOutboxNoAlgorithm:
       
   979 		case EMsgOutboxMIME:
       
   980 			break;
       
   981 		}
       
   982 	CleanupStack::PopAndDestroy(2, account); // smtpSettings, account
       
   983 	
       
   984 	// Now invoke the create new mail operation.
       
   985 	// Note that it is wrapped up to make the asynchronous call synchronous.
       
   986 	CMsvOperationActiveSchedulerWait* waiter=CMsvOperationActiveSchedulerWait::NewLC();
       
   987 	CImEmailOperation* createNewMailOp = CImEmailOperation::CreateNewL(waiter->iStatus, iMsvEntry->Session(), iMsvEntry->Entry().Id(), aServiceId, KMsvMessagePartBody|KMsvMessagePartAttachments, emailTypeList, KUidMsgTypeSMTP);
       
   988 	CleanupStack::PushL(createNewMailOp);
       
   989 	waiter->Start();
       
   990 
       
   991 	// The the entry is expected to be set to the new message.
       
   992 	TMsvId temp;	
       
   993 	TPckgC<TMsvId> paramPack(temp);
       
   994 	const TDesC8& progBuf = createNewMailOp->ProgressL();	
       
   995 	paramPack.Set(progBuf);
       
   996 	TMsvId messageId = paramPack();
       
   997 	iMsvEntry->SetEntryL(messageId);
       
   998 	
       
   999 	CMsvStore* store = iMsvEntry->ReadStoreL();
       
  1000 	CleanupStack::PushL(store);
       
  1001 	iHeader->RestoreL(*store);
       
  1002 
       
  1003 	CleanupStack::PopAndDestroy(3, waiter); // waiter, createNewMailOp, store	
       
  1004 	}
       
  1005 	
       
  1006 /**
       
  1007 Gets the default SMTP service.
       
  1008 
       
  1009 @return
       
  1010 The default service
       
  1011 
       
  1012 @leave 
       
  1013 KErrNotFound If default service setting does not exist.
       
  1014 */
       
  1015 EXPORT_C TMsvId CSmtpClientMtm::DefaultServiceL() const
       
  1016 	{
       
  1017 	// Get default service Id from CenRep
       
  1018 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
  1019 	TSmtpAccount id;
       
  1020 	TInt error = account->DefaultSmtpAccountL(id);
       
  1021 	if (error == KErrNotFound)
       
  1022 		{
       
  1023 		User::Leave(error);
       
  1024 		}
       
  1025 	
       
  1026 	CleanupStack::PopAndDestroy(account); 	   
       
  1027 	return id.iSmtpService;		
       
  1028 	}
       
  1029 
       
  1030 /**
       
  1031 Removes the default SMTP service.
       
  1032 */		
       
  1033 EXPORT_C void CSmtpClientMtm::RemoveDefaultServiceL()
       
  1034 	{
       
  1035 	User::Leave(KErrNotSupported);
       
  1036 	}
       
  1037 
       
  1038 /**
       
  1039 Sets the default SMTP service.
       
  1040 
       
  1041 @param	aService
       
  1042 The default service
       
  1043 */		
       
  1044 EXPORT_C void CSmtpClientMtm::ChangeDefaultServiceL(const TMsvId& aService)
       
  1045 	{
       
  1046 	CEmailAccounts* account = CEmailAccounts::NewLC();
       
  1047 	TSmtpAccount id;
       
  1048 	account->GetSmtpAccountL(aService, id);
       
  1049 	account->SetDefaultSmtpAccountL(id);
       
  1050 	CleanupStack::PopAndDestroy(account); 	   		
       
  1051 	}
       
  1052 	
       
  1053 /**
       
  1054 Cancels the current attachment operation.
       
  1055 */	
       
  1056 EXPORT_C void CSmtpClientMtm::CancelAttachmentOperation()
       
  1057 	{
       
  1058  	if ( iAttachmentWaiter)
       
  1059 		 {
       
  1060 		 iAttachmentWaiter->Cancel();
       
  1061 		 }
       
  1062 
       
  1063 	if ( iWait )
       
  1064 		 {
       
  1065 		 iWait->Cancel();
       
  1066 		 }
       
  1067 	}
       
  1068