--- /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 <coemain.h>
+#include <MuiuMsvUiServiceUtilities.h>
+#include <MmsConst.h>
+#include <mmsclient.h>
+#include <MmsDirectUploadUi.rsg>
+#include <eikprogi.h>
+#include <StringLoader.h>
+#include <msvids.h>
+#include <apmstd.h>
+#include <CMsvMimeHeaders.h>
+#include <mtmuibas.h> // MTM UI base
+#include <mtuireg.h> // MTM UI registery
+
+#include <MTMExtendedCapabilities.hrh>
+#include <UniImageProcessor.h>
+#include <MsgMimeTypes.h>
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#endif
+
+#include <SendUiConsts.h>
+#include <sendnorm.rsg>
+#include <senduisingleton.h>
+
+#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<CSendUiAttachment>* 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<TBool> 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
+