diff -r 000000000000 -r 72b543305e3a messagingappbase/sendui/mmsdirectupload/src/MDUCreateAndSend.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/sendui/mmsdirectupload/src/MDUCreateAndSend.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,725 @@ +/* +* Copyright (c) 2002-2006 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: Creates and sends as many MMS messages as there are files +* to be send. Oversize JPEG images are compressed to fit into +* message. +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // MTM UI base +#include // MTM UI registery + +#include +#include +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include +#include +#include + +#include "SendUiFileRightsEngine.h" +#include "MDUCreateAndSend.h" +#include "CSendUiAttachment.h" + +// CONSTANTS +const TInt KProgressIncrement = 1; +const TInt KTenKiloBytes = 10240; +const TInt KImageTargetWidth = 1600; +const TInt KImageTargetHeight = 1200; + +// Ram drive, path structure is created if it does not exist +_LIT( KTempFilePath, ":\\system\\temp\\mmsupload\\"); + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::CMDUCreateAndSend +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMDUCreateAndSend::CMDUCreateAndSend( + CCoeEnv& aCoeEnv, + CSendUiSingleton& aSingleton, + MMDUCreateAndSendCallback* aCallback ) + : CActive( EPriorityStandard ), + iCoeEnv( aCoeEnv ), + iSingleton( aSingleton ), + iFs( iCoeEnv.FsSession() ), + iCallback( aCallback ), + iMessageCreated( EFalse ) + { + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::ConstructL() + { + iError = iSendAsSession.Connect(); + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMDUCreateAndSend* CMDUCreateAndSend::NewL( + CCoeEnv& aCoeEnv, + CSendUiSingleton& aSingleton, + MMDUCreateAndSendCallback* aCallback ) + { + CMDUCreateAndSend* self = CMDUCreateAndSend::NewLC( aCoeEnv, aSingleton, aCallback ); + + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::NewLC +// Two-phased constructor. +// --------------------------------------------------------- +// +CMDUCreateAndSend* CMDUCreateAndSend::NewLC( + CCoeEnv& aCoeEnv, + CSendUiSingleton& aSingleton, + MMDUCreateAndSendCallback* aCallback) + { + CMDUCreateAndSend* self = new (ELeave) CMDUCreateAndSend( aCoeEnv, aSingleton, aCallback ); + + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// Destructor +CMDUCreateAndSend::~CMDUCreateAndSend() + { + iSendAsSession.Close(); + Cancel(); + Reset(); + } + + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::CMDUCreateAndSend +// Creates and sends as many MMS messages as there are files +// to be send. Oversize JPEG images are compressed to fit into +// message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::CreateAndSendL( + CArrayPtrFlat* aAttachments, + const TDesC& aToAddress, + const TDesC& aToAlias, + TInt aMaxMsgSize ) + { + iError = KErrNone; + iCompressionOk = 0; + iCompressionFail = 0; + iMaxMsgSize = aMaxMsgSize; + + if ( aAttachments->Count() ) + { + iAttachments = aAttachments; + } + else + { + User::Leave( KErrArgument ); + } + + if( aToAlias.Length() ) + { + iToAlias = aToAlias.AllocL(); + } + else + { + User::Leave( KErrArgument ); + } + + if( aToAddress.Length() ) + { + iToAddress = aToAddress.AllocL(); + } + else + { + User::Leave( KErrArgument ); + } + + if ( !CheckMmsServiceAvailabilityL() ) + { + CSendUiFileRightsEngine* fileRightsEngine = + CSendUiFileRightsEngine::NewLC( iCoeEnv.FsSession() ); + + TUint i; + if ( iAttachments->Count() > 1 ) + { + i = R_SENDUI_SETTINGS_NOT_OK_MANY; + } + else + { + i = R_SENDUI_SETTINGS_NOT_OK; + } + + fileRightsEngine->ShowInformationNoteL( i ); + CleanupStack::PopAndDestroy( fileRightsEngine ); + User::Leave( KErrCompletion ); + } + + CreateProgressNoteL( aAttachments->Count() ); + + iState = EStateCreateMessage; + + CreateMessageAndSetDataL(); + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::RunL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::RunL() + { + if ( iStatus < 0 ) + { + iError = iStatus.Int(); + } + + if ( iError != KErrNone ) + { + Reset(); + iCallback->MessagesReady(); + } + else + { + switch ( iState ) + { + case EStateCreateMessage: + { + if ( iMessageCount < iAttachments->Count() ) + { + CreateMessageAndSetDataL(); + } + else + { + iState = EStateReady; + CompleteSelf(); + } + } + break; + case EStateImageCompression: + { + if ( IsCompressionNeededL() ) + { + CompressImageL(); + } + else + { + iState = EStateAddAttachment; + CompleteSelf(); + } + } + break; + case EStateAddAttachment: + { + AddAttachmentL(); + } + break; + case EStateSendMessage: + { + SendMessage(); + } + break; + case EStateFinalize: + { + TSendAsProgress progress; + iSendAsMessage.ProgressL( progress ); + + if ( progress.iError == KErrNone ) + { + FinalizeL(); + } + else + { + iState = EStateReady; + CompleteSelf(); + } + } + break; + case EStateReady: + { + iCallback->MessagesReady(); + Reset(); + iState = EStateIdle; + } + break; + default: + { + // Should never end up here. + } + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::DoCancel +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::DoCancel() + { + if ( iCompressor ) + { + iCompressor->Cancel(); + } + iSendAsMessage.Cancel(); + iMessageCreated = EFalse; + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::RunError +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMDUCreateAndSend::RunError( TInt aError ) + { + iError = aError; + Reset(); + iCallback->MessagesReady(); + return KErrNone; + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::CompleteSelf +// +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::CompleteSelf() + { + iStatus = KRequestPending; + TRequestStatus* pStatus = &iStatus; + SetActive(); + User::RequestComplete( pStatus, KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::Reset +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::Reset() + { + iMessageCount = 0; + + delete iCompressor; + iCompressor = NULL; + + delete iToAddress; + iToAddress = NULL; + + delete iToAlias; + iToAlias = NULL; + + if ( iMessageCreated ) + { + iSendAsMessage.Close(); + iMessageCreated = EFalse; + } + + if( iProgressDialog ) + { + // Progress note showing, try to dismiss it + TRAP_IGNORE( iProgressDialog->ProcessFinishedL() ); + + // If the ProcessFinishedL() leaves, force the dialog away with delete + delete iProgressDialog; + iProgressDialog = NULL; + } + + if ( iImageCompressed ) + { + iCompressedImage.Close(); + // Delete the temporary file from RAM + iFs.Delete( iCompressedImagePath ); + iImageCompressed = EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::CreateMessageAndSetDataL +// Starts message entry creation. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMDUCreateAndSend::CreateMessageAndSetDataL() + { + iStatus = KRequestPending; + + iSendAsMessage.CreateL( iSendAsSession, KSenduiMtmMmsUid ); + iMessageCreated = ETrue; + + iSendAsMessage.SetBioTypeL( KUidMsgSubTypeMmsUpload ); + + iSendAsMessage.AddRecipientL( + *iToAddress, + *iToAlias, + RSendAsMessage::ESendAsRecipientTo ); + + // Set file name as subject. + TFileName fileName; + CSendUiAttachment& attachment = *(iAttachments->At(iMessageCount)); + attachment.Handle()->Name( fileName ); + + iSendAsMessage.SetSubjectL( fileName ); + + iState = EStateImageCompression; + CompleteSelf(); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::IsCompressionNeededL +// Checks if file is oversized JPEG image. +// Returns ETrue if image should be compressed. +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CMDUCreateAndSend::IsCompressionNeededL() + { + iImageCompressed = EFalse; + iAttachmentSize = 0; + + CSendUiAttachment& attachment = (*iAttachments->At(iMessageCount)); + + // Get file size and type. + iAttachmentSize = attachment.Size(); + if ( iAttachmentSize > iMaxMsgSize && + attachment.MimeType().CompareF( KMsgMimeImageJpeg ) == 0 ) + { + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::CompressImageL +// Compress oversized JPEG image. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::CompressImageL() + { + TInt targetSize = iMaxMsgSize - KTenKiloBytes; + RFile sourceFile = *(*iAttachments->At(iMessageCount)).Handle(); + CreateTempFileL( sourceFile, iCompressedImage ); + + TSize targetDimensions( KImageTargetWidth, KImageTargetHeight ); + if ( !iCompressor ) + { + iCompressor = new ( ELeave ) CUniImageProcessor( this ); + } + iCompressor->ProcessImageL( + sourceFile, + iCompressedImage, + targetDimensions, + KMsgMimeImageJpeg, + ETrue, + targetSize ); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::AddAttachment +// Add attachment to message. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::AddAttachmentL() + { + CSendUiAttachment& attachmentPacket = *(iAttachments->At(iMessageCount)); + if ( iAttachmentSize > 0 && iAttachmentSize < iMaxMsgSize ) + { + if ( iImageCompressed ) + { + iSendAsMessage.AddAttachment( + iCompressedImage, + iStatus ); + } + else + { + RFile attachment; + attachment.Duplicate( *attachmentPacket.Handle()); + iSendAsMessage.AddAttachment( + attachment, + iStatus ); + } + iState = EStateSendMessage; + SetActive(); + } + else + { + // file could not be fit into the message + FinalizeL(); + } + + + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::SendMessage +// Sends message. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::SendMessage() + { + iSendAsMessage.SendMessage( iStatus ); + iState = EStateFinalize; + SetActive(); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::FinalizeL +// Updates progress bar. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::FinalizeL() + { + iMessageCount++; + + iSendAsMessage.Close(); + iMessageCreated = EFalse; + + // Update progress note text + if ( iMessageCount < iAttachments->Count() ) + { + // Delete the temporary file from RAM + if ( iImageCompressed ) + { + iCompressedImage.Close(); + iFs.Delete( iCompressedImagePath ); + iImageCompressed = EFalse; + } + UpdateProgressTextL( iAttachments->Count() ); + iState = EStateCreateMessage; + } + else + { + iProgressDialog->ProcessFinishedL(); + iState = EStateReady; + } + + CompleteSelf(); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::CreateTempFileL +// Creates temp file to EDefaultRam:\system\temp\mmsupload. Original filename is used. +// Note: handle to created file is left open. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::CreateTempFileL( + RFile& aSourceFile, + RFile& aTargetFile ) + { + // Construct target path + TInt drive; +#ifdef RD_MULTIPLE_DRIVE + User::LeaveIfError( DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRam, drive ) ); +#else + drive = EDriveD; +#endif + + iCompressedImagePath.Zero(); + TChar driveLetter = TChar('A'); + driveLetter += drive ; + iCompressedImagePath.Append( driveLetter ); + iCompressedImagePath.Append( KTempFilePath ); + + // Create temp directory if needed + TInt err = iFs.MkDirAll( iCompressedImagePath ); + + if ( err != KErrNone && err != KErrAlreadyExists ) + { + User::Leave( err ); + } + + TFileName sourceName; + aSourceFile.Name( sourceName ); + + iCompressedImagePath.Append( sourceName ); + + // Create and open new file + User::LeaveIfError( aTargetFile.Replace( + iFs, + iCompressedImagePath, + EFileWrite | EFileShareAny ) ); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::CreateProgressNoteL +// Creates progress bar. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::CreateProgressNoteL( TInt aFinalValue ) + { + iProgressDialog = new (ELeave) CAknProgressDialog( + reinterpret_cast< CEikDialog** > (&iProgressDialog) ); + + iProgressDialog->PrepareLC( R_MMS_DIRECT_UPLOAD_PROGRESS_NOTE ); + iProgressDialog->SetTone( CAknNoteDialog::ENoTone ); + iProgressInfo = iProgressDialog->GetProgressInfoL(); + iProgressInfo->SetFinalValue( aFinalValue ); + + iProgressCount = 1; + UpdateProgressTextL( aFinalValue ); + + // Register for cancel event and execute the note + iProgressDialog->SetCallback( this ); + iProgressDialog->RunLD(); + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::UpdateProgressTextL +// Updates progress bar text. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::UpdateProgressTextL( TInt aFinalValue ) + { + CArrayFixFlat< TInt >* numbers = new( ELeave ) CArrayFixFlat< TInt > (2); + CleanupStack::PushL( numbers ); + + numbers->AppendL( iProgressCount ); + numbers->AppendL( aFinalValue ); + + HBufC* progressText = StringLoader::LoadLC( + R_MMS_DIRECT_UPLOAD_PROGRESS, *numbers, &iCoeEnv ); + + if ( iProgressDialog ) + { + iProgressDialog->SetTextL( *progressText ); + iProgressInfo->IncrementAndDraw( KProgressIncrement ); + iProgressCount++; + } + + CleanupStack::PopAndDestroy( 2, numbers ); // progressText, numbers + } + +// --------------------------------------------------------- +// CMDUCreateAndSend::DialogDismissedL +// Callback method for progress dialog to inform us when dialog is dismissed. +// This function is called when cancel button of the progress bar was pressed. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::DialogDismissedL( TInt aButtonId ) + { + // Check if cancel button was pressed. + if ( aButtonId == EAknSoftkeyCancel ) + { + DoCancel(); + + iState = EStateReady; + } + } + +// ----------------------------------------------------------------------------- +// CMDUCreateAndSend::CheckMmsServiceAvailabilityL +// Checks that MMS service is available. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CMDUCreateAndSend::CheckMmsServiceAvailabilityL() + { + CBaseMtm* mtm = iSingleton.ClientMtmRegistryL().NewMtmL( KSenduiMtmMmsUid ); + CleanupStack::PushL( mtm ); + + CBaseMtmUi* mtmUi = iSingleton.MtmUiRegistryL().NewMtmUiL( *mtm ); + CleanupStack::PushL( mtmUi ); + + TPckgBuf paramPack( ETrue ); + + // This is not actually used. + CMsvEntrySelection* dummySelection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( dummySelection ); + + mtmUi->InvokeSyncFunctionL( KMtmUiFunctionValidateService, + *dummySelection, + paramPack ); + + CleanupStack::PopAndDestroy( 3, mtm ); + return ( KErrNone == paramPack() ); + } + + +// --------------------------------------------------------- +// CMDUCreateAndSend::ImageProcessingReady +// Callback function called when compression is ready. +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CMDUCreateAndSend::ImageProcessingReady( TSize /*aBitmapSize*/, TInt aFileSize, TBool /*aCompressed*/ ) + { + iAttachmentSize = aFileSize; + + TInt error = iCompressor->Error(); + + if ( error == KErrNone ) + { + iCompressionOk++; + iState = EStateAddAttachment; + } + else + { + iCompressionFail++; + iState = EStateFinalize; + } + + iImageCompressed = ETrue; + + CompleteSelf(); + } + +// End of File +