mobilemessaging/unieditor/application/src/UniEditorSendUiOperation.cpp
changeset 0 72b543305e3a
child 53 696bfeff199e
--- /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