diff -r 000000000000 -r 72b543305e3a mobilemessaging/unieditor/application/src/UniEditorSendUiOperation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobilemessaging/unieditor/application/src/UniEditorSendUiOperation.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,664 @@ +/* +* Copyright (c) 2006,2007 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: CUniEditorSendUiOperation, operation for opening messages created by SendUI +* +*/ + + + +// ========== INCLUDE FILES ================================ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "UniEditorSendUiOperation.h" +#include "UniEditorProcessTextOperation.h" + +// ========== EXTERNAL DATA STRUCTURES ===================== + +// ========== EXTERNAL FUNCTION PROTOTYPES ================= + +// ========== CONSTANTS ==================================== + +const TUint KSendAsDeleteAllPercentage = 80; + +// ========== MACROS ======================================= + +// ========== LOCAL CONSTANTS AND MACROS =================== + +// ========== MODULE DATA STRUCTURES ======================= + +// ========== LOCAL FUNCTION PROTOTYPES ==================== + +// ========== LOCAL FUNCTIONS ============================== + +// ========== MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::NewL +// +// Factory method. +// --------------------------------------------------------- +// +CUniEditorSendUiOperation* CUniEditorSendUiOperation::NewL( + MUniEditorOperationObserver& aObserver, + CUniEditorDocument& aDocument, + RFs& aFs ) + { + CUniEditorSendUiOperation* self = + new ( ELeave ) CUniEditorSendUiOperation( aObserver, aDocument, aFs ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::CUniEditorSendUiOperation +// +// Constructor. +// --------------------------------------------------------- +// +CUniEditorSendUiOperation::CUniEditorSendUiOperation( + MUniEditorOperationObserver& aObserver, + CUniEditorDocument& aDocument, + RFs& aFs ) : + CUniEditorOperation( aObserver, aDocument, aFs, EUniEditorOperationSendUi ) + { + } + + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::CUniEditorSendUiOperation +// +// Destructor. +// --------------------------------------------------------- +// +CUniEditorSendUiOperation::~CUniEditorSendUiOperation() + { + Cancel(); + delete iImageOperation; + delete iVideoOperation; +#ifdef RD_MSG_XHTML_SUPPORT + delete iTextOperation; +#endif + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::Start +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::Start() + { + ResetErrors(); + + iOperationState = EUniEditorSendUiCheck; + iObjectsSize = 0; + iObjectNum = 0; + iSlideNum = 0; + iDeleteAll = EFalse; + + CompleteSelf( KErrNone ); + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::ConstructL +// +// 2nd phase constructor. +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::ConstructL() + { + BaseConstructL(); + + iDeleteAllLimit = ( iDocument.MaxMessageSize() * KSendAsDeleteAllPercentage ) / 100; + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoCancelCleanup +// +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoCancelCleanup() + { + if ( iImageOperation ) + { + iImageOperation->Cancel(); + } + + if ( iVideoOperation ) + { + iVideoOperation->Cancel(); + } +#ifdef RD_MSG_XHTML_SUPPORT + if ( iTextOperation ) + { + iTextOperation->Cancel(); + } +#endif + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::RunL +// +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::RunL() + { + PrintOperationAndState(); + + if ( !SetErrorAndReport( iStatus.Int() ) ) + { + DoSendUiStepL(); + } + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoSendUiStepL +// +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoSendUiStepL() + { + switch ( iOperationState ) + { + case EUniEditorSendUiCheck: + { + DoSendUiCheckL(); + break; + } + case EUniEditorSendUiPrepareObject: + { + DoSendUiPrepareObjectL(); + break; + } + case EUniEditorSendUiPrepareAttachments: + { + DoSendUiPrepareAttachmentsL(); + break; + } + case EUniEditorSendUiEnd: + { + iObserver.EditorOperationEvent( EUniEditorOperationSendUi, + EUniEditorOperationComplete ); + break; + } + default: + { + iObserver.EditorOperationEvent( EUniEditorOperationSendUi, + EUniEditorOperationError ); + break; + } + } + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoSendUiCheckL +// +// Check message content when message created by SendAs +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoSendUiCheckL() + { + if ( iDocument.DataModel()->ObjectList().Count() || + iDocument.DataModel()->AttachmentList().Count() ) + { + DoCheckFilesL(); + } + + if ( iDocument.DataModel()->ObjectList().Count() ) + { + iDocument.DataModel()->SmilModel().SortSlidesL(); + } + + iOperationState = EUniEditorSendUiPrepareObject; + CompleteSelf( KErrNone ); + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoCheckFilesL +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoCheckFilesL() + { + TInt slideCount = iDocument.DataModel()->SmilModel().SlideCount(); + + //It's important to go from end to beginning + //because slides may be removed + for ( TInt i = slideCount; --i >= 0 ; ) + { + //It's important to go from end to beginning + //because objects may be removed + for ( TInt ii = iDocument.DataModel()->SmilModel().SlideObjectCount(i); --ii >= 0 ;) + { + CUniObject* obj = iDocument.DataModel()->SmilModel().GetObjectByIndex( i, ii ); + + TMmsConformance conformance = + iDocument.DataModel()->MmsConformance().MediaConformance( *obj->MediaInfo() ); + + TUint32 confStatus = conformance.iConfStatus; + + TBool remove = EFalse; + if ( confStatus & EMmsConfNokDRM ) + { + remove = ETrue; + SetError( EUniSendUiForbidden ); + } + else if ( confStatus & EMmsConfNokCorrupt ) + { + SetError( EUniSendUiCorrupted ); + } + else if ( confStatus & ( EMmsConfNokNotEnoughInfo | EMmsConfNokNotSupported ) || + ( iDocument.CreationMode() == EMmsCreationModeRestricted && + confStatus & EMmsConfNokFreeModeOnly ) ) + { + remove = ETrue; + SetError( EUniSendUiUnsupported ); + } + else if ( !conformance.iCanAdapt && + confStatus & EMmsConfNokTooBig ) + { + remove = ETrue; + SetError( EUniSendUiTooBig ); + } + + if ( remove ) + { + iDocument.DataModel()->SmilModel().RemoveObjectByIndexL( i, ii ); + remove = EFalse; + } + } + + if ( !iDocument.DataModel()->SmilModel().SlideObjectCount( i ) ) + { + iDocument.DataModel()->SmilModel().RemoveSlide( i ); + } + } + + CUniObjectList& attachments = iDocument.DataModel()->AttachmentList(); + //It's important to go from end to beginning + //because attachments may be removed + for ( TInt j = attachments.Count(); --j >= 0 ; ) + { + CUniObject* obj = attachments.GetByIndex( j ); + + TMmsConformance conformance = + iDocument.DataModel()->MmsConformance().MediaConformance( *obj->MediaInfo() ); + + TUint32 confStatus = conformance.iConfStatus; + + if ( iDocument.CreationMode() != EMmsCreationModeRestricted ) + { + // Mask "FreeModeOnly" away in free mode + confStatus &= ~EMmsConfNokFreeModeOnly; + // Mask "Scaling needed" away in free mode + confStatus &= ~EMmsConfNokScalingNeeded; + } + + if ( confStatus & EMmsConfNokDRM ) + { + attachments.RemoveObjectL( obj ); + SetError( EUniSendUiForbidden ); + delete obj; + } + else if ( confStatus & EMmsConfNokCorrupt ) + { + SetError( EUniSendUiCorrupted ); + } + else if ( confStatus != EMmsConfOk ) + { + attachments.RemoveObjectL( obj ); + SetError( EUniSendUiUnsupported ); + delete obj; + } + } + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoSendUiPrepareObjectL +// +// Processes images and checks whether message size is below +// max size. If not removes as many objects as needed. +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoSendUiPrepareObjectL() + { + VerifyPreparedObjectL(); + + CUniObject* obj = iDocument.DataModel()->SmilModel().GetObjectByIndex( iSlideNum, iObjectNum ); + + if ( obj ) + { + DoPrepareObjectL( obj ); + } + else + { + iOperationState = EUniEditorSendUiPrepareAttachments; + CompleteSelf( KErrNone ); + } + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::VerifyPreparedObjectL +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::VerifyPreparedObjectL() + { + if ( iPreparedObject ) + { + TBool remove = EFalse; + + // Conformance status check! + TMmsConformance conformance = + iDocument.DataModel()->MmsConformance().MediaConformance( *iPreparedObject->MediaInfo() ); + + TUint32 confStatus = conformance.iConfStatus; + if ( iPreparedObject->MediaType() == EMsgMediaText ) + { + // Mask "ConversionNeeded" away for text objects + // -> Will be always converted to UTF-8 anyway + confStatus &= ~EMmsConfNokConversionNeeded; + } + + if ( iDocument.CreationMode() != EMmsCreationModeRestricted ) + { + // Mask "FreeModeOnly" away in free mode + confStatus &= ~EMmsConfNokFreeModeOnly; + // Mask "Scaling needed" away in free mode + confStatus &= ~EMmsConfNokScalingNeeded; + //Mask "Corrupted" away in free mode + confStatus &= ~EMmsConfNokCorrupt; + } + + // Mask "Too big" away as there is a separate check for that + confStatus &= ~EMmsConfNokTooBig; + + if ( confStatus != EMmsConfOk ) + { + SetError( EUniSendUiUnsupported ); + remove = ETrue; + } + + TInt currentSize = iObjectsSize + + iPreparedObject->Size() + + iDocument.DataModel()->SmilModel().SmilComposeSize( iSlideNum + 1, iObjectNum + 1 ); + + if ( !remove && + TUint( currentSize ) > iDocument.MaxMessageSize() ) + { + // Remove if above max size + if ( TUint( iPreviousSize ) > iDeleteAllLimit ) + { + //Once above "delete all limit" delete all the rest. + iDeleteAll = ETrue; + } + remove = ETrue; + SetError( EUniSendUiTooBig ); + } + else + { + // Don't remove. Update previous size. + iPreviousSize = currentSize; + } + + if ( remove ) + { + iDocument.DataModel()->SmilModel().RemoveObjectByIndexL( iSlideNum, iObjectNum ); + + if ( !iDocument.DataModel()->SmilModel().SlideObjectCount( iSlideNum ) ) + { + iDocument.DataModel()->SmilModel().RemoveSlide( iSlideNum ); + } + } + else + { + iObjectsSize += iPreparedObject->Size(); + iObjectNum++; + + if ( iObjectNum >= iDocument.DataModel()->SmilModel().SlideObjectCount( iSlideNum ) ) + { + iSlideNum++; + iObjectNum = 0; + } + } + } + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoPrepareObjectL +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoPrepareObjectL( CUniObject* aObject ) + { + switch ( aObject->MediaType() ) + { + case EMsgMediaImage: + { + if ( !iImageOperation ) + { + iImageOperation = CUniEditorProcessImageOperation::NewL( *this, iDocument, iFs ); + } + + // Processes if needed: + iImageOperation->Process( static_cast( aObject->MediaInfo() ), + aObject->AttachmentId(), + iPreviousSize ); + iPreparedObject = aObject; + + SetPending(); + return; + } + case EMsgMediaVideo: + { + //We need video conversion only for mp4 videos + if ( aObject->MimeType().Compare( KMsgMimeVideoMp4 ) == 0 ) + { + if ( CUniEditorConvertVideoOperation::IsImplementedL() ) + { + if ( !iVideoOperation ) + { + iVideoOperation = CUniEditorConvertVideoOperation::NewL( *this, iDocument, iFs ); + } + + // Processes if needed: + iVideoOperation->Process( static_cast( aObject->MediaInfo() ), + aObject->AttachmentId(), + iDocument.MaxMessageSize() ); + iPreparedObject = aObject; + + SetPending(); + return; + } + } + break; + } + case EMsgMediaXhtml: + { +#ifdef RD_MSG_XHTML_SUPPORT + // Processes all XHTML objects and converts them into plain text. + iTextOperation = CUniEditorProcessTextOperation::NewL( *this, iDocument, iFs ); + iTextOperation->Start(); + + SetPending(); + return; +#else + break; +#endif + } + case EMsgMediaText: + case EMsgMediaAudio: + default: + { + // nothing + break; + } + } + + iPreparedObject = aObject; + CompleteSelf( KErrNone ); + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::DoSendUiPrepareAttachmentsL +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::DoSendUiPrepareAttachmentsL() + { + TInt smilSize = iObjectsSize + iDocument.DataModel()->SmilModel().SmilComposeSize(); + + TInt attaSize = 0; + TInt j = 0; + + CUniObjectList& attachments = iDocument.DataModel()->AttachmentList(); + + if ( attachments.Count() ) + { + while ( TUint( smilSize + attaSize ) < iDocument.MaxMessageSize() ) + { + attaSize += attachments.GetByIndex( j )->Size(); + j++; + if ( j >= attachments.Count() && + TUint( smilSize + attaSize ) < iDocument.MaxMessageSize() ) + { + j++; + break; + } + } + j--; + while ( j < attachments.Count() ) + { + CUniObject* obj = attachments.GetByIndex( j ); + attachments.RemoveObjectL( obj ); + SetError( EUniSendUiTooBig ); + delete obj; + } + } + iOperationState = EUniEditorSendUiEnd; + CompleteSelf( KErrNone ); + } + +// --------------------------------------------------------- +// CUniEditorSendUiOperation::HandleOperationEvent +// --------------------------------------------------------- +// +void CUniEditorSendUiOperation::HandleOperationEvent( TUniEditorOperationType aOperation, + TUniEditorOperationEvent /*aEvent*/ ) + { + TBool remove( EFalse ); + + TMsvAttachmentId attaId( KMsvNullIndexEntryId ); + CMsgMediaInfo* info = NULL; + + if ( aOperation == EUniEditorOperationProcessImage ) + { + // Process image error handling + CArrayFixFlat* errors = iImageOperation->GetErrors(); + for ( TInt i = 0; i < errors->Count(); i++ ) + { + if ( errors->At( i ) == EUniProcessImgUserAbort ) + { + iOperationState = EUniEditorSendUiEnd; + } + else if ( ( errors->At( i ) == EUniProcessImgCouldNotScale && + iDocument.CreationMode() == EMmsCreationModeRestricted ) || + errors->At( i ) == EUniProcessImgNotFound ) + { + remove = ETrue; + } + + SetError( errors->At( i ) ); + } + + info = iImageOperation->DetachImageInfo(); + iImageOperation->DetachAttachmentId( attaId ); + } + else if ( aOperation == EUniEditorOperationConvertVideo ) + { + // Convert video error handling + CArrayFixFlat* errors = iVideoOperation->GetErrors(); + for ( TInt i = 0; i < errors->Count(); i++ ) + { + if ( errors->At( i ) == EUniConvertVidUserAbort ) + { + iOperationState = EUniEditorSendUiEnd; + } + else if ( ( errors->At( i ) == EUniConvertVidFailed && + iDocument.CreationMode() == EMmsCreationModeRestricted ) || + errors->At( i ) == EUniConvertVidNotFound ) + { + remove = ETrue; + } + + SetError( errors->At( i ) ); + } + + info = iVideoOperation->DetachVideoInfo(); + iVideoOperation->DetachAttachmentId( attaId ); + } +#ifdef RD_MSG_XHTML_SUPPORT + else if ( aOperation == EUniEditorOperationProcessText ) + { + CArrayFixFlat* errors = iTextOperation->GetErrors(); + for ( TInt i = 0; i < errors->Count(); i++ ) + { + SetError( errors->At( i ) ); + } + } +#endif + + if ( info ) + { + TRAPD( error, + iDocument.DataModel()->SmilModel().RemoveObjectL( iSlideNum, iPreparedObject ) ); + + if ( !error ) + { + iPreparedObject = NULL; + TRAP_IGNORE( iPreparedObject = iDocument.DataModel()->SmilModel().AddStoredObjectL( iSlideNum, attaId, info ) ); + } + else // --> original object remains... + { + delete info; + } + } + + if ( remove && iPreparedObject ) + { + TRAPD( err, iDocument.DataModel()->SmilModel().RemoveObjectByIndexL( iSlideNum, iObjectNum ) ); + + if ( !err && + !iDocument.DataModel()->SmilModel().SlideObjectCount( iSlideNum ) ) + { + iDocument.DataModel()->SmilModel().RemoveSlide( iSlideNum ); + } + + iPreparedObject = NULL; + } + + //else --> original object remains... + CompleteOperation( KErrNone ); + } + +// EOF