--- /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 <mmsconst.h>
+
+#include <unidatautils.h>
+#include <MsgMimeTypes.h>
+#include <unismilmodel.h>
+#include <MsgMediaInfo.h>
+#include <MsgTextInfo.h>
+#include <MsgImageInfo.h>
+#include <MsgVideoInfo.h>
+
+#include <MmsConformance.h>
+
+#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<CMsgImageInfo*>( 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<CMsgVideoInfo*>( 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<TInt>* 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<TInt>* 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<TInt>* 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