messagingfw/msgsrvnstore/server/src/MTCLBASE.CPP
changeset 0 8e480a14352b
child 34 b66b8f3a7fd8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgsrvnstore/server/src/MTCLBASE.CPP	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,861 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// MTCLBASE.CPP
+//
+#include <e32std.h>
+#include <txtrich.h>
+#include <txtfmlyr.h>
+#include <mtmuids.h>
+
+#include "MSVIDS.H"
+#include "MSVAPI.H"
+#include "MTCLBASE.H"
+#include "MTCLREG.H"
+#include "MSVPANIC.H"
+#include "MSVUIDS.H"
+
+#include <mmsvattachmentmanager.h>
+#include "CMsvAttachmentWaiter.h"
+#include <cmsvmimeheaders.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
+#include "msvconsts.h"
+#endif
+
+#if defined(_DEBUG)
+_LIT(KMtclPanicString, "MSGS");
+#endif
+
+
+EXPORT_C CBaseMtm::CBaseMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvSession& aSession)
+: iRegisteredMtmDll(aRegisteredMtmDll), iSession(aSession)
+//
+//
+//
+/** Creates a CBaseMtm with member variables initialised from the passed arguments. 
+
+
+Client applications do not use this function. It is relevant only to implementers 
+of derived classes.
+
+The value of aSession can be accessed through Session().
+
+Derived classes can implement a constructor to perform any additional MTM-specific 
+setup that can be safely carried out in a constructor. Such constructors must 
+call the base class constructor function.
+
+Derived classes also implement two-phase construction functions (NewL(), ConstructL()) 
+to create a new instance of the object, in which any dynamic allocation should 
+be performed. Client-side MTMs also implement a factory function by which 
+a MTM registry can request an instance of the class.
+
+@param aRegisteredMtmDll Registration data for the MTM DLL. 
+@param aSession The CMsvSession of the client requesting the object */
+	{}
+
+
+EXPORT_C CBaseMtm::~CBaseMtm()
+//
+//
+//
+/** Cleans up the base class. 
+
+CBaseMtm -derived objects must be deleted by client applications when they 
+are no longer required. 
+
+Derived classes can implement a destructor to do any additional clean up tasks 
+that they require. */
+	{
+	DeleteEntry();
+	delete iAddresseeList;
+	delete iRichTextBody;
+	delete iCharFormatLayer;
+	delete iParaFormatLayer;
+	iRegisteredMtmDll.ReleaseLibrary();
+	delete iAttachmentWaiter;
+	delete iExtensionData;
+	}
+
+
+EXPORT_C TUid CBaseMtm::Type() const
+/** Gets the Type UID of the message type associated with the Client-side MTM.
+
+@return UID of the message type associated with the MTM */
+	{
+	return iRegisteredMtmDll.MtmTypeUid();
+	}
+
+
+EXPORT_C TInt CBaseMtm::QueryCapability(TUid /*aCapability*/, TInt& /*aResponse*/)
+//
+//
+//
+	/** Queries if the MTM supports a particular capability, specified by a UID. 
+	
+	For MTM-specific UIDs, see the documentation for the relevant MTM.
+	
+	Requirements:
+	
+	Implementations should check aCapability for the standard capability values, 
+	plus any MTM-specific capabilities, and if recognised, return a suitable response 
+	in aResponse. If aCapability is unknown, return KErrNotSupported.
+	
+	The default implementation returns KErrNotSupported. 
+	
+	@param aCapability UID of capability to be queried 
+	@param aResponse Response value. The format of the response varies according 
+	to the capability. 
+	@return KErrNone: aCapability is a recognised value and a response is returned 
+	KErrNotSupported: aCapability is not a recognised value */
+	{
+	return KErrNotSupported;
+	}
+
+
+
+EXPORT_C void CBaseMtm::SwitchCurrentEntryL(TMsvId aId)
+//
+//
+//
+/** Changes the entry on which later actions are performed to the entry with the 
+specified TMsvId. 
+
+@param aId The ID of the entry upon which all following actions will be performed 
+
+@leave KErrNoMemory Insufficient memory 
+@leave KErrNotFound The requested entry does not exist */
+	{
+	// create the new CMsvEntry
+	CMsvEntry* newEntry = Session().GetEntryL(aId);
+	SetCurrentEntryL(newEntry);
+	}
+
+
+
+EXPORT_C void CBaseMtm::SetCurrentEntryL(CMsvEntry* aEntry)
+//
+//
+//
+/** Sets the entry on which later actions are performed to the specified CMsvEntry. 
+
+
+@param aEntry The entry on which all following actions will be performed 
+@leave KErrNoMemory Insufficient memory */
+	{
+	CleanupStack::PushL(aEntry);
+
+	if (iAddresseeList==NULL)
+		iAddresseeList = CMsvRecipientList::NewL();
+	if (iParaFormatLayer==NULL)
+		iParaFormatLayer = CParaFormatLayer::NewL();
+	if (iCharFormatLayer==NULL)
+		iCharFormatLayer = CCharFormatLayer::NewL();
+	if (iRichTextBody==NULL)
+		iRichTextBody = CRichText::NewL(iParaFormatLayer, iCharFormatLayer);
+	else
+		iRichTextBody->Reset();
+
+	aEntry->AddObserverL(*this);
+
+	CleanupStack::Pop(); // aEntry
+
+	// swap the old and new context
+	DeleteEntry();
+	iMsvEntry = aEntry;
+	iEntryId = iMsvEntry->EntryId();
+
+	// If waiting for attachment additons to be commited, delete without commiting
+	// the changed
+	delete iAttachmentWaiter;
+	iAttachmentWaiter = NULL;
+
+	// inform concrete implementation that the context has switched (or set in the first case)
+	ContextEntrySwitched();
+	}
+
+
+EXPORT_C CMsvEntry& CBaseMtm::Entry() const
+/** Gets a CMsvEntry for the current context. The message client application can 
+then use this to manipulate the entry.
+
+Implementers should note that this function returns the value of the protected 
+data member iMsvEntry.
+
+@return CMsvEntry for the current context */
+	{
+	__ASSERT_DEBUG(iMsvEntry!=NULL, User::Panic(KMtclPanicString, 275));
+	return *iMsvEntry;
+	};
+
+
+EXPORT_C TBool CBaseMtm::HasContext() const
+/** Tests if an MTM context has been set.
+
+A Client-side MTM has no context until one is set through SwitchCurrentEntryL() 
+or SetCurrentEntryL() . 
+
+@return ETrue: context has been set EFalse: context has not been set */
+	{
+	return (iMsvEntry!=NULL);
+	}
+
+
+void CBaseMtm::DeleteEntry()
+//
+//
+//
+	{
+	if (iMsvEntry!=NULL)
+		{
+		iMsvEntry->RemoveObserver(*this);
+		delete iMsvEntry;
+		iMsvEntry=NULL;
+		}
+	}
+
+EXPORT_C void CBaseMtm::StoreBodyL(CMsvStore& aStore)
+//
+//
+//
+/** Stores and commits the current cached CRichText body text to the appropriate 
+stream in the specified message store. Client applications do not use this 
+function. It is relevant only to implementers of derived classes.
+
+The function overwrites any existing data in that stream. The implementation 
+must have write access to aStore. 
+
+A typical use of this function is from SaveMessageL().
+
+@param aStore Message store in which to store the body text 
+@leave KErrAccessDenied The store was opened for read only 
+@leave Other Standard stream-related leave codes */
+	{
+	__ASSERT_ALWAYS(iMsvEntry!=NULL, PanicServer(EMtclMsvEntryNotSet));
+	__ASSERT_ALWAYS(iMsvEntry->EntryId()==iEntryId, PanicServer(EMtclContextChangedByOwner));
+	
+	aStore.StoreBodyTextL(*iRichTextBody);	
+	}
+
+EXPORT_C void CBaseMtm::RestoreBodyL(CMsvStore& aStore)
+//
+//
+//
+/** Gets the current cached CRichText from the appropriate stream in the specified 
+message store. Client applications do not use this function. It is relevant 
+only to implementers of derived classes.
+
+A typical use of this function is from LoadMessageL().
+
+@param aStore Message store from which to read the body text */
+	{
+	__ASSERT_ALWAYS(iMsvEntry!=NULL, PanicServer(EMtclMsvEntryNotSet));
+	__ASSERT_ALWAYS(iMsvEntry->EntryId()==iEntryId, PanicServer(EMtclContextChangedByOwner));
+
+	aStore.RestoreBodyTextL(*iRichTextBody);
+	}
+
+
+EXPORT_C CRichText& CBaseMtm::Body()
+/** Gets the body text of the context, that must be a message. For non-message 
+contexts, an empty CRichText is returned. 
+
+@return Body text of the context 
+@see StoreBodyL()
+@see RestoreBodyL() */
+	{
+	__ASSERT_DEBUG(iMsvEntry!=NULL, User::Panic(KMtclPanicString, 275)); 
+	return *iRichTextBody;
+	}
+
+
+EXPORT_C const CRichText& CBaseMtm::Body() const
+/** Gets the read-only body text of the context, that must be a message. For non-message 
+contexts, an empty CRichText is returned. 
+
+@return Read-only body text of the context 
+@see StoreBodyL()
+@see RestoreBodyL() */
+	{
+	__ASSERT_DEBUG(iMsvEntry!=NULL, User::Panic(KMtclPanicString, 275));
+	return *iRichTextBody;
+	}
+
+
+EXPORT_C void CBaseMtm::SetSubjectL(const TDesC& /*aSubject*/)
+//
+//
+//
+	/** Sets the subject text of the context, which must be a message. 
+	
+	Some Client-side MTMs may not support subject text, in which case the function 
+	leaves with KErrNotSupported.
+	
+	Requirements:
+	
+	If the message protocol supports subject text, implementations should maintain 
+	a private buffer to store this information, settable through this function.
+	
+	Implementations should save the subject text to the appropriate place in the 
+	message store when the message is stored.
+	
+	The default implementation leaves with KErrNotSupported.
+	
+	@param aSubject Message subject text 
+	@leave KErrNotSupported The Client-side MTMs does not support subject text 
+	@see StoreBodyL()
+	@see RestoreBodyL() */
+	{
+	User::Leave(KErrNotSupported);
+	}
+
+
+/** Gets the list of intended recipients for the current context, which must be 
+a message. 
+
+In the case of protocols that allow different classes of recipient (such as 
+To, Cc and Bcc), the list returned is whatever the protocol defines as the 
+default recipient list. 
+
+Requirements:
+
+The default implementation simply returns the value of the protected data 
+member iAddresseeList. As a consequence, Client-side MTM implementations should 
+update this member whenever the address list is modified.
+
+@return Array of recipients
+*/
+EXPORT_C const CMsvRecipientList& CBaseMtm::AddresseeList() const
+	{
+	__ASSERT_DEBUG(iMsvEntry!=NULL, User::Panic(KMtclPanicString, 275));
+	return *iAddresseeList;
+	}
+
+
+/** Adds addressee to list.
+
+The default implementation treats To: and Cc: type addressees as if the addressee
+had no type.
+
+The default implementation does not support Bcc type addressees.
+
+@param	aType
+The addressee type.
+
+@param	aRealAddress
+The addressee address.
+
+@leave	KErrNotSupprted
+The addressee type was Bcc which is not supported in the default implementation.
+*/
+EXPORT_C void CBaseMtm::AddAddresseeL(TMsvRecipientType aType, const TDesC& aRealAddress)
+	{
+	if (aType == EMsvRecipientBcc)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	AddAddresseeL(aRealAddress);
+	}
+
+	
+/** Adds addressee to list.
+
+The default implementation treats To: and Cc: type addressees as if the addressee
+had no type.
+
+The default implementation does not support Bcc type addressees.
+
+@param	aType
+The addressee type.
+
+@param	aRealAddress
+The addressee address.
+
+@param	aAlias
+The alias for the addressee.
+
+@leave	KErrNotSupprted
+The addressee type was Bcc which is not supported in the default implementation.
+*/
+EXPORT_C void CBaseMtm::AddAddresseeL(TMsvRecipientType aType, const TDesC& aRealAddress, const TDesC& aAlias)
+	{
+	if (aType == EMsvRecipientBcc)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	AddAddresseeL(aRealAddress, aAlias);
+	}
+
+
+EXPORT_C const TPtrC CBaseMtm::SubjectL() const
+//
+//
+//
+/** Gets the subject text of the context, which must be a message. 
+
+Some Client-side MTMs may not support subject text, in which case the function 
+leaves with KErrNotSupported.
+
+Requirements:
+
+If the message protocol supports subject text, implementations should maintain 
+a private buffer to store this information, gettable through this function.
+
+The default implementation leaves with KErrNotSupported.
+
+@leave KErrNotSupported The Client-side MTMs does not support subject text 
+@return Message subject text */
+	{
+	User::Leave(KErrNotSupported);
+	return TPtrC();
+	}
+
+
+EXPORT_C void CBaseMtm::HandleEntryEventL(TMsvEntryEvent /*aEvent*/, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
+/** Indicates that an event has occurred. 
+
+Client applications do not use this function. It is relevant only to implementers of derived classes.
+
+The Client-side MTM object is automatically set as an observer, through CMsvEntry::AddObserverL(), 
+for the context whenever the context changes (by SetCurrentEntryL() or SwitchCurrentEntryL()).
+
+The default implementation is defined to do nothing.
+
+Requirements:
+
+Implementations can override this function to handle events concerning the current context. 
+
+@param aEvent Indicates the event type 
+@param aArg1 Event specific argument value 
+@param aArg2 Event specific argument value
+@param aArg3 Event specific argument value
+*/
+	{
+	}
+
+
+EXPORT_C CMsvSession& CBaseMtm::Session()
+/** Gets a reference to the session object passed by the creator of the Client-side 
+MTM.
+
+@return Session object used by the Client-side MTM */
+	{
+	return iSession;
+	}
+
+
+/**
+Adds a file attachment to the current message entry.
+
+The attachment is referenced by its file path and is copied into the message store.
+Only one asynchronous operation can be run at any one time.
+
+@param aFilePath The full path specification of the attachment file.
+@param aMimeType The mime type of the attachment file.
+@param aCharset The mime charset. The value is a standard IANA value. The value 0 indicates
+	   that no charset is provided.
+@param aStatus The request status to complete when request has completed.
+@leave System-wide error codes.
+*/
+EXPORT_C void CBaseMtm::AddAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
+	{
+	AddFilePathAttachmentL(aFilePath, aMimeType, aCharset, CMsvAttachment::EMsvFile, aStatus);
+	}
+	
+/**
+Adds a file attachment to the current message entry.
+
+The attachment is referenced by an open file handle and is copied into the message store. 
+Only one asynchronous operation can be run at any one time.
+
+@param aFile An open file handle for the file attachment.
+@param aMimeType The mime type of the attachment file.
+@param aCharset The mime charset. The value is a standard IANA value. The value 0 indicates
+	   that no charset is provided.
+@param aStatus The request status to complete when request has completed.
+@leave System-wide error codes.
+*/
+EXPORT_C void CBaseMtm::AddAttachmentL(RFile& aFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
+	{
+	if( iAttachmentWaiter == NULL )
+		iAttachmentWaiter = CMsvAttachmentWaiter::NewL();
+
+	CMsvStore* store = iMsvEntry->EditStoreL();
+	CleanupStack::PushL(store);
+	
+	CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
+	CleanupStack::PushL(attachment);
+	
+	// set the size
+	TInt size = 0;
+	User::LeaveIfError(aFile.Size(size));
+	attachment->SetSize(size);
+	
+	// set the mime-type if provided
+	if( aMimeType.Length() > 0 )
+		{
+		attachment->SetMimeTypeL(aMimeType);
+		}
+		
+	TFileName fileName;
+	User::LeaveIfError(aFile.Name(fileName));
+	attachment->SetAttachmentNameL(fileName);
+	
+	if( aCharset!=0 )
+		{
+		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
+		headers->SetMimeCharset(aCharset);
+		headers->StoreL(*attachment);
+		CleanupStack::PopAndDestroy(headers);
+		}	
+	
+	// attachment is initialised, pass to the attachment manager
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	manager.AddAttachmentL(aFile, attachment, iAttachmentWaiter->iStatus); 
+	CleanupStack::Pop(attachment); // ownership passed to manager
+	iAttachmentWaiter->StartWaitingL(aStatus, store, &manager);
+	CleanupStack::Pop(store);      // ownership passed
+	}
+
+/**
+Adds a file attachment to the current message entry as a linked file.
+
+The attachment is referenced by its file path and is not copied into the message store. The attachment file is always used from
+its original location on disk indicated by the aFilePath parameter. Only one asynchronous operation can be run at any one time.
+
+@param aFilePath The full path specification of the attachment file.
+@param aMimeType The mime type of the attachment file.
+@param aCharset The mime charset. The value is a standard IANA value. The value 0 indicates
+	   that no charset is provided.
+@param aStatus The request status to complete when request has completed.
+@leave System-wide error codes.
+*/	
+EXPORT_C void CBaseMtm::AddLinkedAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
+	{
+	AddFilePathAttachmentL(aFilePath, aMimeType, aCharset, CMsvAttachment::EMsvLinkedFile, aStatus);
+	}
+
+/**
+Creates a new empty file attachment to the current message entry.
+
+An empty file attachment is created with the suggested given name and if
+completed successfully, the aAttachmentFile will be open on the new file.
+Only one asynchronous operation can be run at any one time.
+
+@param aFileName The suggested file name for the new attachment file.
+@param aAttachmentFile If successful, this will be set to the open new file.
+@param aMimeType The mime type of the attachment file.
+@param aCharset The mime charset. The value is a standard IANA value. The value 0 indicates
+	   that no charset is provided.
+@param aStatus The request status to complete when request has completed.
+@leave System-wide error codes.
+*/
+EXPORT_C void CBaseMtm::CreateAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus)
+	{
+	if( iAttachmentWaiter == NULL )
+		iAttachmentWaiter = CMsvAttachmentWaiter::NewL();
+
+	CMsvStore* store = iMsvEntry->EditStoreL();
+	CleanupStack::PushL(store);
+	
+	CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
+	CleanupStack::PushL(attachmentInfo);
+	attachmentInfo->SetAttachmentNameL(aFileName);
+	attachmentInfo->SetMimeTypeL(aMimeType);
+
+	if( aCharset!=0 )
+		{
+		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
+		headers->SetMimeCharset(aCharset);
+		headers->StoreL(*attachmentInfo);
+		CleanupStack::PopAndDestroy(headers);
+		}
+
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	manager.CreateAttachmentL(aFileName, aAttachmentFile, attachmentInfo, iAttachmentWaiter->iStatus);
+	CleanupStack::Pop(attachmentInfo); // ownership passed to manager
+	iAttachmentWaiter->StartWaitingL(aStatus, store, &manager);
+	CleanupStack::Pop(store); // ownership passed
+	}
+
+/**
+Adds a message entry as an attachment to the current message entry.
+
+This method simply registers an existing message entry as an attachment to the current entry. Only one asynchronous
+operation can be run at any one time.
+
+@param aAttachmentId The message Id of the message entry to add as an attachment.
+@param aStatus The request status to complete when request has completed.
+@leave System-wide error codes.
+*/	
+EXPORT_C void CBaseMtm::AddEntryAsAttachmentL(TMsvId aAttachmentId, TRequestStatus& aStatus)
+	{
+	// Get the size of the message entry
+	CMsvEntry* attachEntry = iSession.GetEntryL(aAttachmentId);
+	TInt attachSize = attachEntry->Entry().iSize;
+	delete attachEntry;
+	attachEntry = NULL;
+	
+	if( iAttachmentWaiter == NULL )
+		iAttachmentWaiter = CMsvAttachmentWaiter::NewL();
+
+	CMsvStore* store = iMsvEntry->EditStoreL();
+	CleanupStack::PushL(store);
+	
+	CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvMessageEntry);
+	CleanupStack::PushL(attachment);
+	attachment->SetSize(attachSize);
+	
+	// Register entry as attachment
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	manager.AddEntryAsAttachmentL(aAttachmentId, attachment, iAttachmentWaiter->iStatus);
+	CleanupStack::Pop(attachment); // ownership passed to manager
+	iAttachmentWaiter->StartWaitingL(aStatus, store, &manager);
+	CleanupStack::Pop(store); // ownership passed
+	}
+
+void CBaseMtm::AddFilePathAttachmentL(const TDesC& aFilePath, const TDesC8& aMimeType, TUint aCharset, CMsvAttachment::TMsvAttachmentType aType, TRequestStatus& aStatus)
+	{
+	__ASSERT_DEBUG(aType != CMsvAttachment::EMsvMessageEntry, User::Invariant());
+	
+	if( iAttachmentWaiter == NULL )
+		iAttachmentWaiter = CMsvAttachmentWaiter::NewL();
+	
+	CMsvStore* store = iMsvEntry->EditStoreL();
+	CleanupStack::PushL(store);
+
+	CMsvAttachment* attachment = CMsvAttachment::NewL(aType);
+	CleanupStack::PushL(attachment);
+	
+	// set the size
+	TEntry fileEntry;
+	RFs& fs = iSession.FileSession();
+	User::LeaveIfError(fs.Entry(aFilePath, fileEntry));
+	attachment->SetSize(fileEntry.iSize);
+	
+	// set the mime-type, if provided
+	if( aMimeType.Length() > 0 )
+		{
+		attachment->SetMimeTypeL(aMimeType);
+		}
+		
+	// set attachment name
+	TParse fileNameParser;
+	User::LeaveIfError(fileNameParser.Set(aFilePath, NULL, NULL));
+	attachment->SetAttachmentNameL(fileNameParser.NameAndExt());
+	
+	if( aCharset!=0 )
+		{
+		CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
+		headers->SetMimeCharset(aCharset);
+		headers->StoreL(*attachment);
+		CleanupStack::PopAndDestroy(headers);
+		}
+	
+	// attachment is initialised, pass to the attachment manager
+	MMsvAttachmentManager& manager = store->AttachmentManagerL();
+	switch(aType)
+		{
+		case CMsvAttachment::EMsvFile:
+			manager.AddAttachmentL(aFilePath, attachment, iAttachmentWaiter->iStatus);
+			break;
+		case CMsvAttachment::EMsvLinkedFile:
+			manager.AddLinkedAttachmentL(aFilePath, attachment, iAttachmentWaiter->iStatus);
+			break;
+		default:
+			break;
+		}
+
+	CleanupStack::Pop(attachment); // ownership passed to manager
+
+	iAttachmentWaiter->StartWaitingL(aStatus, store, &manager);
+	CleanupStack::Pop(store); // ownership passed
+	}
+
+/**
+Cancels the current attachment operation.
+*/	
+EXPORT_C void CBaseMtm::CancelAttachmentOperation()
+	{
+	__ASSERT_ALWAYS(iAttachmentWaiter != NULL, PanicServer(EMsvOperationNotFound));
+	iAttachmentWaiter->Cancel();
+	delete iAttachmentWaiter;
+	iAttachmentWaiter = NULL;
+	}
+
+
+// virtual
+EXPORT_C void CBaseMtm::CreateMessageL(TMsvId aServiceId)
+/** Creates a new message entry as a child of the current context.
+
+The default implementation creates an empty entry with its visible flag set 
+to false and its in-preparation flag set to true.
+
+@param aServiceId ID of the service to own the entry. */
+	{
+	// create an invisible blank entry 
+	TMsvEntry entry;
+	entry.iType = KUidMsvMessageEntry;
+	entry.iServiceId = aServiceId;
+	entry.iMtm = Type();
+	entry.SetVisible(EFalse);
+	entry.SetInPreparation(ETrue);
+
+	// store entry in folder
+	iMsvEntry->CreateL(entry);
+	iMsvEntry->SetEntryL(entry.Id());
+	iEntryId = entry.Id();
+	}
+
+EXPORT_C void CBaseMtm::BioTypeChangedL(TUid /*aBioTypeUid*/)
+	/** Informs client-side MTM that the context's BIO field is being changed as a 
+	result of a call to CSendAs::SetBioTypeL().
+	
+	CSendAs::SetBioTypeL() calls this function before setting the BIO field in 
+	the context's index entry. This allows a client-side MTM to perform MTM specific 
+	actions when the BIO type changes. 
+	
+	CSendAs will not change the BIO type if this function leaves.
+	
+	The default implementation is to do nothing. 
+	
+	@param aBioTypeUid New value for the BIO field
+	@see CSendAs::SetBioTypeL() */
+	{
+	//The default implementation is to do nothing.
+	}
+ 	
+/**
+Gets the default MTM service.
+ 	
+The default implementation is to assume the MTM only supports one service so finds the
+first service associated with this MTM and returns that.
+ 
+@return
+The default service
+ 
+@leave 
+KErrNotFound If no service has been created.
+*/
+EXPORT_C TMsvId CBaseMtm::DefaultServiceL() const
+ 	{
+    // Create a new entry, showing invisible entries (because the service entry may be invisible)
+    TMsvSelectionOrdering ordering(KMsvNoGrouping, EMsvSortByNone, ETrue);
+    CMsvEntry* entry = CMsvEntry::NewL(iSession, KMsvRootIndexEntryId, ordering);
+    CleanupStack::PushL(entry);
+	
+ 	CMsvEntrySelection *sel=entry->ChildrenWithMtmL(iRegisteredMtmDll.MtmTypeUid());
+	CleanupStack::PushL(sel);
+	if(sel->Count() == 0)
+	    {
+	    User::Leave(KErrNotFound);
+	    } 
+	TMsvId service=sel->At(0);
+ 	CleanupStack::PopAndDestroy(2,entry);
+	return service;
+ 	}
+ 
+/**
+Removes the default service setting. The default implementation of this function assumes
+that the MTM only supports one service and therefore this does nothing.
+*/
+EXPORT_C void CBaseMtm::RemoveDefaultServiceL()
+ 	{
+ 	}
+ 
+/**
+Sets the default MTM service. The default implementation of this function assumes that
+the MTM only supports one service and therefore this does nothing.
+ 
+@param	aService
+The default service
+*/
+EXPORT_C void CBaseMtm::ChangeDefaultServiceL(const TMsvId& /*aService*/)
+ 	{
+ 	}
+
+
+/**
+Returns a pointer to the interface with the specified Uid.
+
+This method is the first part of an extension pattern to allow for 
+more functionality to be supported without adding virtual methods 
+to this base class.
+
+The default implementation returns a NULL pointer.
+ 
+@param	aUid  
+Uid of the extension interface
+@return
+Pointer to the extension interface
+*/
+EXPORT_C TAny* CBaseMtm::GetInterface(TUid /*aUid*/)
+ 	{
+	return NULL;
+ 	}
+
+/** 
+Sets the character encoding value. The character encoding value options are 7-bit,
+8-bit and 16-Bit Unicode. By default the character set encoding is 7 bit encoding.
+@param	aCharSet	Character encoding value may be 7-bit/8-bit/16-bit Unicode.
+@return KErrNone	If charset is changed successfully in SMS settings.
+*/
+   
+EXPORT_C TInt CBaseMtm::SetMessageCharacterSet(TUint aCharSet)
+	{
+	TAny* ptrNull=NULL;
+	return Extension_(KUIDCharacterSet,ptrNull,&aCharSet);		
+	}
+	
+/**
+The default Extension service. The default implementation of this function assumes that
+the new service for setting the charset encoding value for a SMS message is not 
+supported. TAny* is equivalent to void*.
+@param	a0				 			The collective parameters of TAny*
+@param	a1				 			The collective parameters of TAny*,Charset encoding value is actually extracted from a1.
+@param aExtensionId 	 			Uid of the extension interface
+@return KErrExtensionNotSupported 	If the message is other than SMS.
+@return Other 			 			Standard system-wide error codes.
+*/
+
+EXPORT_C TInt CBaseMtm::Extension_(TUint aExtensionId, TAny *&a0, TAny *a1)	
+	{
+	TInt ret = KErrNone;
+	switch(aExtensionId)
+		{
+		case KUIDCharacterSet:
+			{
+			ret = KErrExtensionNotSupported;
+			}
+			break;
+		default:
+			{
+			// Chain to base class
+			ret = CBase::Extension_(aExtensionId,a0,a1);
+			}
+			break;
+		}
+	return ret;
+	}
+
+//if passed value is NULL, its as good as reset extention data
+EXPORT_C void CBaseMtm::SetExtensionData(TAny* aSortData)
+	{
+	iExtensionData=aSortData;	
+	}
+	
+EXPORT_C TAny* CBaseMtm::GetExtensionData()
+	{
+	return iExtensionData;
+	}
+