--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/sendui/meetingrequestsender/src/MeetingRequestSender.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,891 @@
+/*
+* Copyright (c) 2002-2005 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: MeetingRequestSender implementation
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <e32std.h>
+#include <SendUi.h> // TSendingCapabilities
+#include <e32svr.h>
+#include <mtclreg.h> // CClientMtmRegistry
+#include <mtclbase.h> // CBaseMtm
+#include <miuthdr.h>
+#include <txtrich.h>
+#include <MuiuMsvUiServiceUtilities.h>
+#include <s32mem.h> // CBufStore
+#include <apmstd.h>
+#include <mtmextendedcapabilities.hrh> // KUidMsvMtmQuerySupportLinks
+#include <apgcli.h>
+#include <mtmuids.h>
+#include <mtmdef.h>
+
+#include <CSendingServiceInfo.h>
+#include <CMessageAddress.h>
+#include <SendUiConsts.h> // UIDs for provider and service
+#include <CMessageData.h> // CMessageData
+#include <MeetingRequestData.h> // CMeetingRequestData
+#include <senduisingleton.h>
+
+#include "SendUiDummyMtm.h"
+#include "SendUiOperationWait.h"
+#include "SenduiDataUtils.h"
+#include "SenduiFileRightsEngine.h"
+#include "CSendUiAttachment.h"
+#include <MeetingRequestIds.hrh>
+#include "MeetingRequestSender.h"
+
+namespace
+ {
+ _LIT8( KContentType, "multipart" );
+ _LIT8( KContentSubType,"/alternative; boundary=mr_part; method=");
+ _LIT( KMsgInvalidSessionEvent, "CMeetingRequestSender: Invalid session event %x" );
+ _LIT( KMsgEmptyAddreesseeArray,"CMeetingRequestSender:: Addressee array is empty! Message cannot be created." );
+ _LIT( KMailtoMatchPattern, "mailto:*" ); // this is never localized
+ const TInt KMailtoLength = 7; // "mailto:" length
+
+ // LOCAL CONSTANTS
+ // For address information separation (start)
+ const TUint KSendUiMsgAddressStartChar ('<');
+
+ // For address information separation (end)
+ const TUint KSendUiMsgAddressEndChar ('>');
+
+ const TInt KRichTextStoreGranularity = 512;
+ const TInt KContentSubTypeMaxLength( 60 );
+
+ const TUint KTransferBufAdditionalInfoMaxLen = 20;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMeetingRequestSender* CMeetingRequestSender::NewL( TSendingServiceParams* aParams )
+ {
+ CMeetingRequestSender* self = CMeetingRequestSender::NewLC( aParams );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMeetingRequestSender* CMeetingRequestSender::NewLC( TSendingServiceParams* aParams )
+ {
+ CMeetingRequestSender* self = new( ELeave ) CMeetingRequestSender( aParams->iCoeEnv, aParams->iSingleton );
+ CleanupStack::PushL( self );
+
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::~CMeetingRequestSender()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CMeetingRequestSender::~CMeetingRequestSender()
+ {
+ iServiceArray.ResetAndDestroy();
+ iServiceArray.Close();
+
+ delete iStore;
+
+ delete iClientMtm;
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::CMeetingRequestSender
+// Constructor.
+// -----------------------------------------------------------------------------
+//
+
+CMeetingRequestSender::CMeetingRequestSender( CCoeEnv& aCoeEnv, CSendUiSingleton& aSingleton ) :
+ CSendingService( aCoeEnv, aSingleton )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::ConstructL()
+ {
+ InitializeServiceL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::PopulateServicesListL
+// Populates given list with the services provided by this plugin.
+// The ownership of the pointed objects remains.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::PopulateServicesListL(
+ RPointerArray<CSendingServiceInfo>& aList )
+ {
+ for ( TInt cc = 0; cc < iServiceArray.Count(); cc++ )
+ {
+ User::LeaveIfError( aList.Append( iServiceArray[cc] ) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::CreateAndSendMessageL
+// Creates message to be sent and calls MTM to send the message.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::CreateAndSendMessageL(
+ TUid aServiceUid,
+ const CMessageData* aMessageData,
+ TBool /*aLaunchEditorEmbedded*/)
+ {
+
+ if( !aMessageData ||
+ aServiceUid != KMeetingRequestSender ||
+ aMessageData->DataType() != KSenduiMsgDataMeetingRequest )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ CMeetingRequestData* mrData = CMeetingRequestData::NewLC();
+ mrData->ReadFromBufferL( aMessageData->OpaqueData() );
+
+ InitResourcesL( mrData );
+
+ //In case of SMTP we just create message and don't check capabilities,
+ //because SMTP MTM doesn't understand capabilities at the moment.
+ if( iClientMtm->Type() == KSenduiMtmSmtpUid )
+ {
+ DoCreateAndSendMessageL( *aMessageData, mrData );
+ }
+ else
+ {
+ TUid supportMeetingRequestUid = TUid::Uid(KMtmUiSupportMeetingRequest);
+ TUid supportICalCapability = TUid::Uid(KMtmUiSupportICalCapability);
+ TInt capabilityResponse;
+
+ TInt errorCode = iClientMtm->QueryCapability(supportMeetingRequestUid, capabilityResponse);
+
+ //Check if Meeting request is supported at all. If not then leave.
+ if(errorCode == KErrNotSupported || capabilityResponse == 0)
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ errorCode = iClientMtm->QueryCapability(supportICalCapability, capabilityResponse);
+
+ //Check if MTM supports supportICalCapability.
+ if ( (errorCode != KErrNotSupported) && (capabilityResponse != 0))
+ {
+ DoCreateAndSendMessageL( *aMessageData, mrData );
+ }
+ else
+ {
+ TransferIdsToClientL( *aMessageData );
+
+ DoCreateAndSendMessageL( *aMessageData, mrData );
+ }
+ }
+ CleanupStack::PopAndDestroy( mrData );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::DoCreateAndSendMessageL
+// Creates message to be sent and calls MTM to send the message.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::DoCreateAndSendMessageL(
+ const CMessageData& aMessageData,
+ CMeetingRequestData* aMeetingRequestData )
+ {
+ CreateMessageL( aMessageData );
+
+ TInt capabilityResponse;
+ //Capability to support some kind of body checked
+ TInt errorCode = iClientMtm->QueryCapability(
+ TUid::Uid( KUidMtmQuerySupportedBodyValue ),
+ capabilityResponse );
+
+ if(capabilityResponse)
+ {
+ SetBodyL( aMessageData );
+ }
+
+ AddAttachmentsL( aMessageData );
+
+ // Create message header(s)
+ CreateHeaderL( aMessageData, aMeetingRequestData );
+
+ iClientMtm->SaveMessageL();
+
+ //QueryCapability() can't be used here because client gives false answer.
+ //So only way to do this is check MTM type.
+ if(iClientMtm->Type() == KSenduiMtmSmtpUid)
+ {
+ if( !ValidateEmail( ) )
+ {
+ User::Leave( KErrCompletion );
+ }
+ }
+
+ SendEmailL( );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::TransferIdsToClientL
+// Transfers meeting request IDs to client MTM.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::TransferIdsToClientL(
+ const CMessageData& aMessageData )
+ {
+ // Create copy of opaque data. Needed because InvokeSyncFunctionL wants
+ // non-const buffer.
+ HBufC8* tempBuf = aMessageData.OpaqueData().AllocLC();
+ TPtr8 ptr = tempBuf->Des();
+
+ // Dummy entry selection
+ CMsvEntrySelection* entrySelection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( entrySelection );
+
+ //Send data to MTM with InvokeSyncFunction()
+ iClientMtm->InvokeSyncFunctionL(
+ KMTMSendMeetingRequestFunctionId,
+ *entrySelection,
+ ptr );
+
+ CleanupStack::PopAndDestroy( 2, tempBuf ); // entrySelection, buf
+
+ }
+
+// ---------------------------------------------------------
+// CMeetingRequestSender::ServiceProviderId
+// Returns the id of the service provider.
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TUid CMeetingRequestSender::ServiceProviderId() const
+ {
+ return KMeetingRequestSender; // defined in SendUiConsts.h
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::InitializeServiceL
+// Initializes service info.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::InitializeServiceL()
+ {
+ if( iServiceArray.Count() )
+ {
+ // Already initialized so do nothing
+ return;
+ }
+
+ CSendingServiceInfo* serviceInfo = CSendingServiceInfo::NewLC();
+
+ // Set service type.
+ serviceInfo->SetServiceProviderId( KMeetingRequestSender );
+ serviceInfo->SetServiceId( KMeetingRequestSender );
+ iServiceArray.AppendL( serviceInfo );
+
+ CleanupStack::Pop( serviceInfo );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::CreateMessageL
+// Creates new message with subject. Index entry is initialized and
+// new message is created in drafs folder.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::CreateMessageL(
+ const CMessageData& aMessageData )
+ {
+ CMsvEntry* draftEntry = iSingleton.MsvSessionL().GetEntryL( KMsvDraftEntryId );
+ CleanupStack::PushL(draftEntry);
+ iClientMtm->SetCurrentEntryL( draftEntry ); // mtm takes ownership
+ CleanupStack::Pop(draftEntry);
+
+ // Create new message under drafts
+ iClientMtm->CreateMessageL( iMailServiceId );
+
+ // Load email signature, if any
+ iClientMtm->LoadMessageL();
+
+ // Set message subject
+ iClientMtm->SetSubjectL( aMessageData.Subject() );
+
+ // Set attributes on index entry
+ TMsvEntry indexEntry = iClientMtm->Entry().Entry();
+ indexEntry.SetInPreparation( ETrue );
+ indexEntry.SetVisible( EFalse );
+ indexEntry.iDate.UniversalTime();
+ indexEntry.SetAttachment( EFalse );
+
+ iClientMtm->Entry().ChangeL( indexEntry );
+
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::InitResourcesL
+// Client MTM is initialized. Used SMTP service is validated.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::InitResourcesL(
+ CMeetingRequestData* aMeetingRequestData )
+ {
+ iMailServiceId = aMeetingRequestData->Mailbox();
+
+ if ( iMailServiceId == KMsvNullIndexEntryId )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ ResolveClientMTMTypeL( iMailServiceId );
+
+ if ( iClientMtmType == KNullUid )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // Create client side MTM object.
+ delete iClientMtm;
+ iClientMtm = NULL;
+
+ iClientMtm = iSingleton.ClientMtmRegistryL().NewMtmL( iClientMtmType );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::ResolveClientMTMTypeL
+// Resolves the client MTM type by using service id. KNullUid is returned if
+// service id doesn't match to any available service.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::ResolveClientMTMTypeL( TMsvId aServiceId )
+ {
+ TInt i = 0;
+
+ CMsvEntrySelection* entrySelection =
+ MsvUiServiceUtilities::GetListOfAccountsL( iSingleton.MsvSessionL(), ETrue );
+ CleanupStack::PushL( entrySelection );
+
+ CMsvEntry* rootEntry = CMsvEntry::NewL(
+ iSingleton.MsvSessionL(),
+ KMsvRootIndexEntryId,
+ TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ) );
+ CleanupStack::PushL( rootEntry );
+
+ TMsvId msvId;
+ for ( i = 0; i < entrySelection->Count(); i++ )
+ {
+ msvId = entrySelection->At( i );
+
+ if ( msvId == aServiceId )
+ {
+ TMsvEntry tEntry = rootEntry->ChildDataL( msvId );
+ iClientMtmType = tEntry.iMtm;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2, entrySelection ); // entrySelection, rootEntry
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::SetBodyL
+// Sets email body.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::SetBodyL(
+ const CMessageData& aMessageData )
+ {
+ // If body has been not set return immediately
+ if( !aMessageData.BodyText()->DocumentLength() )
+ {
+ return;
+ }
+
+ const CRichText& bodyText = *( aMessageData.BodyText() );
+ CRichText& mtmBody = iClientMtm->Body();
+
+ delete iStore;
+ iStore = NULL;
+
+ iStore = CBufStore::NewL( KRichTextStoreGranularity );
+
+ // If signature has been set then append it at the end of email
+ if ( mtmBody.DocumentLength() )
+ {
+ CRichText* text = CRichText::NewL(
+ static_cast<CEikonEnv&>( iCoeEnv ).SystemParaFormatLayerL(),
+ static_cast<CEikonEnv&>( iCoeEnv ).SystemCharFormatLayerL() );
+ CleanupStack::PushL( text );
+
+ TInt len1 = bodyText.DocumentLength();
+ TInt len2 = mtmBody.DocumentLength();
+
+ HBufC* buf = HBufC::NewLC( len1 );
+ TPtr ptr = buf->Des();
+ bodyText.Extract( ptr, 0 );
+ text->InsertL( 0, *buf );
+ CleanupStack::PopAndDestroy( buf );
+
+ len1 = text->DocumentLength();
+ text->InsertL( len1, CEditableText::EParagraphDelimiter );
+ len1 = text->DocumentLength();
+ text->InsertL( len1, mtmBody.Read( 0, len2 ) );
+
+ // Save and restore the rich text
+ TStreamId id = text->StoreL( *iStore );
+ mtmBody.RestoreL( *iStore, id );
+
+ CleanupStack::PopAndDestroy(text);
+ }
+ else
+ {
+ // Save and restore the rich text
+ TStreamId id = bodyText.StoreL( *iStore );
+ mtmBody.RestoreL( *iStore, id );
+ }
+
+ // Get access to protected data
+ CSendUiDummyMtm* mtm = ( CSendUiDummyMtm* ) iClientMtm;
+
+ mtm->SetCharFormatL( *bodyText.GlobalCharFormatLayer() );
+ mtm->SetParaFormatL( *bodyText.GlobalParaFormatLayer() );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::CreateHeaderL
+// Create email headers. "Standard" and MIME header is initialized.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::CreateHeaderL(
+ const CMessageData& aMessageData,
+ CMeetingRequestData* aMeetingRequestData )
+ {
+ InitStdHeaderL( aMessageData );
+
+ //At the moment only way to check mime capability is to use iClientMtm->Type()
+ if(iClientMtm->Type() == KSenduiMtmSmtpUid)
+ {
+ InitMimeHeaderL( aMeetingRequestData );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::InitStdHeaderL
+// Initialize standard header. To, cc and bcc fields are set.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::InitStdHeaderL(
+ const CMessageData& aMessageData )
+ {
+ // Nothing to do if aTo array is empty
+ if ( aMessageData.ToAddressArray().Count() == 0 )
+ {
+ RDebug::Print( KMsgEmptyAddreesseeArray );
+ User::Leave( KErrArgument );
+ }
+
+ AddAddresseesL( EMsvRecipientTo, aMessageData.ToAddressArray() );
+
+ AddAddresseesL( EMsvRecipientCc, aMessageData.CcAddressArray() );
+
+ AddAddresseesL( EMsvRecipientBcc, aMessageData.BccAddressArray() );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::AddAddresseesL
+// Add To addressees.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::AddAddresseesL(
+ TMsvRecipientType aRecipientType,
+ const CMessageAddressArray& aAddressees )
+ {
+ TInt i(0);
+
+ for( i = 0; i < aAddressees.Count(); i++ )
+ {
+ if( aAddressees[i]->Address().Length() > 0 )
+ {
+ // If address has an alias, process it
+ if( aAddressees[i]->Alias().Length() > 0 )
+ {
+ TPtrC alias = aAddressees[i]->Alias();
+
+ // Check if alias contains illegal characters. If it does
+ // remove them.
+ if( ( alias.Locate( KSendUiMsgAddressStartChar ) != KErrNotFound ) ||
+ ( alias.Locate( KSendUiMsgAddressEndChar ) != KErrNotFound ) )
+ {
+ HBufC* aliasNew = alias.AllocLC();
+ RemoveIllegalChars( aliasNew );
+ iClientMtm->AddAddresseeL(
+ aRecipientType,
+ AttendeeAdressWithoutPrefix( aAddressees[i]->Address() ),
+ *aliasNew );
+
+ CleanupStack::PopAndDestroy( aliasNew );
+ }
+ else
+ {
+ iClientMtm->AddAddresseeL(
+ aRecipientType,
+ AttendeeAdressWithoutPrefix(aAddressees[i]->Address() ),
+ alias );
+ }
+ }
+ else
+ {
+ // Address entry didn't have alias
+ iClientMtm->AddAddresseeL( aRecipientType,
+ AttendeeAdressWithoutPrefix( aAddressees[i]->Address() ));
+ }
+ }
+ // Done setting one addressee
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::RemoveIllegalChars
+// Remove illegal chars from string. Illegal chars are replaced with space
+// and trimmed string is returned.
+// Should everything be removed between KSendUiMsgAddressStartChar and
+// KSendUiMsgAddressEndChar?
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::RemoveIllegalChars( HBufC* aCheckedString )
+ {
+ TInt stringLength = aCheckedString->Length();
+ TPtr string = aCheckedString->Des();
+
+ while( stringLength-- )
+ {
+ if( string[stringLength] == KSendUiMsgAddressStartChar ||
+ string[stringLength] == KSendUiMsgAddressEndChar )
+ {
+ string[stringLength] = CEditableText::ESpace;
+ }
+ }
+ string.TrimAll();
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::InitMimeHeaderL
+// Mime message header is initialized with user defined content type.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::InitMimeHeaderL(
+ CMeetingRequestData* aMeetingRequestData )
+ {
+ CMsvEntry& entry = iClientMtm->Entry();
+ CMsvStore* msvStore = entry.EditStoreL();
+ CleanupStack::PushL( msvStore );
+
+ CImMimeHeader* header = CImMimeHeader::NewLC();
+
+ // Set content type
+ header->SetContentTypeL( KContentType );
+
+ TBuf8<KContentSubTypeMaxLength> subtype( KContentSubType() );
+ subtype.Append( aMeetingRequestData->MailHeaderMethod() );
+ header->SetContentSubTypeL( subtype );
+
+ header->StoreL( *msvStore );
+ msvStore->CommitL();
+
+ CleanupStack::PopAndDestroy( 2, msvStore );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::AddAttachmentsL
+// Attachments are added to the email. Method will leave if there is not
+// enough space for attachments.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::AddAttachmentsL(
+ const CMessageData& aMessageData )
+ {
+ TInt i(0);
+
+
+ CArrayPtrFlat<CSendUiAttachment>* attachments;
+ attachments = CSendUiAttachment::InitAttachmentArrayLCC(
+ aMessageData.AttachmentArray(),
+ aMessageData.AttachmentHandleArray(),
+ iCoeEnv.FsSession() );
+
+
+ // If there are no attachments, return immediately.
+ if( !attachments->Count() )
+ {
+ return;
+ }
+
+ // Get total size of attachments.
+ CSendUiFileRightsEngine* fileRightsEngine =
+ CSendUiFileRightsEngine::NewLC( iCoeEnv.FsSession() );
+
+ // Check if linked attachments are supported.
+ TInt supportsLinks = 0;
+ TUid uidQuery = { KUidMsvMtmQuerySupportLinks };
+ iClientMtm->QueryCapability( uidQuery, supportsLinks );
+
+ TInt totalSize = fileRightsEngine->CalculateTotalSizeOfFiles( attachments, supportsLinks );
+
+ CleanupStack::PopAndDestroy( fileRightsEngine );
+ // following will leave if there is not enough space
+ CheckDiskSpaceL( totalSize );
+
+ const RArray<RFile>& attHandles = aMessageData.AttachmentHandleArray();
+ const CDesCArray& attFilePaths = aMessageData.AttachmentArray();
+
+
+ for( i = 0; i < attachments->Count(); i++ )
+ {
+ AddAttachmentL( attachments->At(i), supportsLinks );
+ }
+
+ CleanupStack::PopAndDestroy(2); // *attachments, attacments
+ TMsvEntry entry = iClientMtm->Entry().Entry();
+ entry.SetAttachment( ETrue );
+ iClientMtm->Entry().ChangeL(entry);
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::AddAttachmentL
+// Add attachment (file descriptor)
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::AddAttachmentL(
+ CSendUiAttachment* aAttachment,
+ TInt aLinksSupported )
+ {
+ TDataType mimeType;
+
+ CSendUiDataUtils* dataUtils = CSendUiDataUtils::NewL( iCoeEnv.FsSession() );
+ CleanupStack::PushL( dataUtils );
+ CSendUiOperationWait* waiter = CSendUiOperationWait::NewLC();
+
+ if ( aAttachment->Type() == CSendUiAttachment::EAttachmentPath )
+ {
+ dataUtils->ResolveFileMimeTypeL( *(aAttachment->Path()), mimeType );
+
+ if ( aLinksSupported )
+ {
+ iClientMtm->AddLinkedAttachmentL(
+ *(aAttachment->Path()), mimeType.Des8(), 0, waiter->iStatus );
+ }
+ else
+ {
+ iClientMtm->AddAttachmentL(
+ *(aAttachment->Path()), mimeType.Des8(), 0, waiter->iStatus );
+ }
+ }
+ else
+ {
+ dataUtils->ResolveFileMimeTypeL( *(aAttachment->Handle()), mimeType );
+ RFile attachmentFile;
+ User::LeaveIfError( attachmentFile.Duplicate( *(aAttachment->Handle()) ) );
+ CleanupClosePushL( attachmentFile );
+
+ // File handle ownership transferred.
+ iClientMtm->AddAttachmentL(
+ attachmentFile,
+ mimeType.Des8(),
+ NULL,
+ waiter->iStatus );
+ CleanupStack::Pop( &attachmentFile );
+
+ }
+
+
+ waiter->Start( iClientMtm );
+
+ CleanupStack::PopAndDestroy( 2, dataUtils ); // waiter, dataUtils
+ }
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::CheckDiskSpaceL
+// Check if there are enough space for email (includes attachments). Leaves
+// if there are not enough space.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::CheckDiskSpaceL(
+ TInt aMsgSize )
+ {
+ if( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL(
+ iSingleton.MsvSessionL(), aMsgSize ) )
+ {
+ User::Leave( KErrDiskFull );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::ValidateEmail
+// Validates email before sending it. Returns true if email is valid.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CMeetingRequestSender::ValidateEmail( )
+ {
+ TMsvPartList msgCheckParts =
+ KMsvMessagePartBody |
+ KMsvMessagePartRecipient |
+ KMsvMessagePartOriginator |
+ KMsvMessagePartDate |
+ KMsvMessagePartDescription;
+
+ TMsvPartList msgFailParts =
+ iClientMtm->ValidateMessage( msgCheckParts );
+
+ return ( msgFailParts == KMsvMessagePartNone );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::SendEmailL
+// Sends an email.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::SendEmailL( )
+ {
+ TMsvEntry entry = iClientMtm->Entry().Entry();
+
+ entry.SetInPreparation( EFalse );
+ entry.SetVisible( ETrue );
+ entry.SetSendingState( KMsvSendStateWaiting );
+
+ iClientMtm->Entry().ChangeL( entry );
+
+ iClientMtm->LoadMessageL();
+ entry = iClientMtm->Entry().Entry();
+ TMsvId id = entry.Id();
+
+ if( entry.Parent() != KMsvGlobalOutBoxIndexEntryId )
+ {
+ // move message to outbox
+ MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );
+ }
+
+ CMsvEntrySelection* entrySelection;
+ entrySelection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( entrySelection );
+
+ entrySelection->AppendL( iMailServiceId );
+ entrySelection->AppendL( id );
+
+ TBuf8<1> params;
+
+ CSendUiOperationWait* waiter = CSendUiOperationWait::NewLC();
+
+ CMsvOperation* op =
+ iClientMtm->InvokeAsyncFunctionL(
+ KMTMStandardFunctionsSendMessage,
+ *entrySelection,
+ params,
+ waiter->iStatus );
+
+ waiter->Start( op );
+
+ CleanupStack::PopAndDestroy( 2, entrySelection ); // entrySelectoin, waiter
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::MoveMessageEntryL
+// Moves email to target folder (usually outbox).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMeetingRequestSender::MoveMessageEntryL( TMsvId aTarget )
+ {
+ TMsvSelectionOrdering sort;
+ // we want to also handle the invisible entries
+ sort.SetShowInvisibleEntries( ETrue );
+
+ // Take a handle to the parent entry
+ TMsvEntry msvEntry( iClientMtm->Entry().Entry() );
+ CMsvEntry* parentEntry =
+ CMsvEntry::NewL(
+ iClientMtm->Session(),
+ msvEntry.Parent(),
+ sort );
+ CleanupStack::PushL( parentEntry );
+
+ // Move original from the parent to the new location
+ parentEntry->MoveL( msvEntry.Id(), aTarget );
+
+ CleanupStack::PopAndDestroy( parentEntry );
+ }
+
+// -----------------------------------------------------------------------------
+// CMeetingRequestSender::AttendeeAdressWithoutPrefix
+// Returns a new descriptor where "MAILTO:" prefix is removed if it existed.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC CMeetingRequestSender::AttendeeAdressWithoutPrefix( const TDesC& aAddress )
+ {
+ TPtrC attendeeAddrWithoutPrefix;
+ if ( aAddress.MatchF( KMailtoMatchPattern ) != KErrNotFound )
+ {
+ attendeeAddrWithoutPrefix.Set( aAddress.Mid( KMailtoLength ) );
+ }
+ else
+ {
+ attendeeAddrWithoutPrefix.Set( aAddress );
+ }
+ return attendeeAddrWithoutPrefix;
+ }
+
+// -----------------------------------------------------------------------------
+// TechnologyType
+// -----------------------------------------------------------------------------
+//
+TUid CMeetingRequestSender::TechnologyTypeId( ) const
+ {
+ return KNullUid;
+ }
+
+// END OF FILE