wvuing/wvuiave/AppSrc/CCAUiMessageUtils.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuiave/AppSrc/CCAUiMessageUtils.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,1254 @@
+/*
+* Copyright (c) 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:  UI utils for message handling
+*
+*/
+
+
+
+// INCLUDE FILES
+#include    "CCAUiMessageUtils.h"
+#include    "IMDialogUtils.h"
+#include    "ChatDebugPrint.h"
+#include    "ChatDefinitions.h"
+#include    "CAArrayUtils.h"
+#include    "imutils.h"
+
+#include    "MCAConversationMessage.h"
+#include    "mcablockchecker.h"
+
+
+#include    <NewFileServiceClient.h>
+#include    <AiwGenericParam.h>
+#include    <chatNG.rsg>
+#include    <MGFetch.h>
+#include    <MMGFetchVerifier.h>
+#include    <documenthandler.h>
+
+#include    <eikenv.h>
+#include    <imageconversion.h>
+
+#include    "impsbuilddefinitions.h"
+#include    "chatdebugassert.h"
+
+#include	"MCAConversationPC.h"
+#include	"IMMessageUtilsPC.h"
+#include	<aknnavi.h>
+#include	<aknappui.h>
+// The Settings have been moved to Cenrep (also retained in the Resource file),
+// so the enums for keys and central repository header is added here
+#include 	"VariantKeys.h"
+
+#ifdef  RD_IMAGEPREVIEW
+#include    <imagepreview.h>
+
+
+#endif  // RD_IMAGEPREVIEW
+
+// CONSTANTS
+
+_LIT8( KMimeTypeJpeg, "image/jpeg" );
+_LIT8( KMimeTypeGif,  "image/gif" );
+_LIT8( KMimeTypeEmpty, "" );
+// From ICL documentation:
+// "all decoder plugins also support thumbnail decodes with ratios of 1:2, 1:4 and 1:8."
+const TInt KDecodeScaleRatioMin = 2;
+const TInt KDecodeScaleRatioMax = 8;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::CCAUiMessageUtils
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCAUiMessageUtils::CCAUiMessageUtils( MCABlockChecker* aBlockChecker )
+        : CActive( CActive::EPriorityLow ), iBlockChecker( aBlockChecker )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCAUiMessageUtils::ConstructL()
+    {
+    User::LeaveIfError( iApaSession.Connect() );
+
+    // create dochandler
+    iDocHandler = CDocumentHandler::NewL();
+    iDocHandler->SetExitObserver( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCAUiMessageUtils* CCAUiMessageUtils::NewLC( MCABlockChecker* aBlockChecker /*= NULL*/ )
+    {
+    CCAUiMessageUtils* self = new( ELeave ) CCAUiMessageUtils( aBlockChecker );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+
+    return self;
+    }
+
+
+// Destructor
+CCAUiMessageUtils::~CCAUiMessageUtils()
+    {
+    Cancel();
+
+    delete iDecoder;
+    delete iSelectedNames;
+
+    delete iDocHandler;
+    iApaSession.Close();
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+    }
+
+//-----------------------------------------------------------------------------
+// CCAUiMessageUtils::RunL
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAUiMessageUtils::RunL()
+    {
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+    }
+
+//-----------------------------------------------------------------------------
+// CCAUiMessageUtils::DoCancel
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+void CCAUiMessageUtils::DoCancel()
+    {
+    iDecoder->Cancel();
+    }
+
+//-----------------------------------------------------------------------------
+// CCAUiMessageUtils::RunError
+// ( Other items commented in header )
+//-----------------------------------------------------------------------------
+TInt CCAUiMessageUtils::RunError( TInt aError )
+    {
+    if ( IsActive() )
+        {
+        iStatus = aError;
+        Cancel();
+        }
+
+    if ( aError == KErrNoMemory )
+        {
+        CActiveScheduler::Current()->Error( KErrNoMemory );
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::SendNewFileL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAUiMessageUtils::SendNewFileL( TNewServiceFileType aFileType,
+                                      MCAConversationPC& aMessageRWInterfacePC,
+                                      const TDesC& aSender /*= KNullDesC*/,
+                                      const MDesCArray* aScreenNames /*= NULL*/,
+                                      TBool aIsWhisperAllowed /*= ETrue*/ )
+    {
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) )
+        {
+        // cancelled
+        return;
+        }
+
+    // only one file will be created
+    CDesCArray* fileNames = new( ELeave )CDesCArrayFlat( 1 );
+    CleanupStack::PushL( fileNames );
+    CNewFileServiceClient* newFile = NewFileServiceFactory::NewClientL();
+    CleanupStack::PushL( newFile );
+
+    CAiwGenericParamList* params = CAiwGenericParamList::NewLC();
+
+//    CEikonEnv::Static()->SetSystem( ETrue );
+
+    CHAT_DP_TXT( "Starting new file service.." );
+    TBool okToSend = EFalse;
+    TRAPD( err, okToSend =
+               newFile->NewFileL( *fileNames, params, aFileType, EFalse ) );
+    if ( err )
+        {
+//        // restore state
+//        CEikonEnv::Static()->SetSystem( EFalse );
+        User::LeaveIfError( err );
+        }
+
+    if ( okToSend )
+        {
+        // we got new file, let's send it
+        CHAT_DP_TXT( "..got new file, sending it" );
+
+        DoSendFileL( *fileNames, aMessageRWInterfacePC, aSender );
+
+        }
+
+    CleanupStack::PopAndDestroy( 3, fileNames ); // params, newFile, fileNames
+    CHAT_DP_TXT( "Send new file done.." );
+    }
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::SendImageL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAUiMessageUtils::SendImageL(
+    MCAConversationPC& aMessageRWInterfacePC,
+    const TDesC& aSender /* = KNullDesC */,
+    const MDesCArray* aScreenNames /* = NULL */,
+    TBool aIsWhisperAllowed /*= ETrue*/ )
+    {
+    TBool ok( EFalse );
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) )
+        {
+        // cancelled
+        return;
+        }
+    while ( !ok )
+        {
+        // only one image can be selected at the moment
+        CDesCArray* files = new( ELeave )CDesCArrayFlat( 1 );
+        CleanupStack::PushL( files );
+
+        HBufC* softkey = CCoeEnv::Static()->AllocReadResourceLC(
+                             R_TEXT_SOFTKEY_SELECT );
+
+        iBeginVerifySelection = EFalse;
+
+        // This rd flag is for testing purposes only.
+#ifndef RD_SEND_NOT_SUPPORTED_CONTENT
+        // only one image can be selected (EFalse)
+        if ( MGFetch::RunL( *files, EImageFile    , EFalse, *softkey, KNullDesC, this ) )
+#else
+        if ( MGFetch::RunL( *files, EAnyMediaFile, EFalse, *softkey, KNullDesC, this ) )
+#endif //RD_SEND_NOT_SUPPORTED_CONTENT
+            {
+            // verify the selected image
+            iBeginVerifySelection = ETrue;
+            TBool verify = VerifySelectionL( files );
+
+            if ( !verify )
+                {
+                CleanupStack::PopAndDestroy( softkey ); // softkey
+                CleanupStack::PopAndDestroy( files );   // files
+                continue;
+                }
+
+#ifdef RD_IMAGEPREVIEW
+            //
+            // Open image preview
+            //
+            if ( files->MdcaCount() == 1 ) // We can only open 1 image
+                {
+                HBufC* skSelect = CCoeEnv::Static()->AllocReadResourceLC(
+                                      R_TEXT_SOFTKEY_SELECT );
+                HBufC* skBack = CCoeEnv::Static()->AllocReadResourceLC(
+                                    R_TEXT_SOFTKEY_BACK );
+
+                this->SetNavigationPaneDimmed( ETrue );
+
+                TInt res = ImagePreview::ShowImageL( files->MdcaPoint( 0 ),
+                                                     *skSelect, *skBack );
+
+                this->SetNavigationPaneDimmed( EFalse );
+                CleanupStack::PopAndDestroy( 2 ); // skSelect, skBack
+                ( res == EAknSoftkeyCancel ) ? ( ok = EFalse ) : ( ok = ETrue );
+                }
+            else
+                {
+                // Invalid number of images
+                __CHAT_ASSERT_DEBUG( EFalse );
+                }
+#endif //RD_IMAGEPREVIEW
+
+            if ( ok )
+                {
+                // send files
+                DoSendFileL( *files, aMessageRWInterfacePC, aSender );
+
+                }
+            CleanupStack::PopAndDestroy( 2 ); // files, softkey
+
+            }
+        else
+            {
+            // user canceled
+            CleanupStack::PopAndDestroy( 2 ); // files, softkey
+            ok = ETrue;
+            }
+        } //end of while
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::SendFileL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::SendFileL(
+    const MDesCArray& aFileNames,
+    MCAConversationPC& aMessageRWInterfacePC,
+    const TDesC& aSender /*= KNullDesC*/,
+    const MDesCArray* aScreenNames /*= NULL*/ )
+    {
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames ) )
+        {
+        // cancelled
+        return;
+        }
+
+    DoSendFileL( aFileNames, aMessageRWInterfacePC, aSender );
+
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::SendNewFileL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAUiMessageUtils::SendNewFileL( TNewServiceFileType aFileType,
+                                      MCAGroupPC& aMessageRWInterfacePC,
+                                      const TDesC& aSender /*= KNullDesC*/,
+                                      const MDesCArray* aScreenNames /*= NULL*/,
+                                      TBool aIsWhisperAllowed /*= ETrue*/ )
+    {
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) )
+        {
+        // cancelled
+        return;
+        }
+
+    // only one file will be created
+    CDesCArray* fileNames = new( ELeave )CDesCArrayFlat( 1 );
+    CleanupStack::PushL( fileNames );
+    CNewFileServiceClient* newFile = NewFileServiceFactory::NewClientL();
+    CleanupStack::PushL( newFile );
+
+    CAiwGenericParamList* params = CAiwGenericParamList::NewLC();
+
+    CHAT_DP_TXT( "Starting new file service.." );
+    if ( newFile->NewFileL( *fileNames, params, aFileType, EFalse ) )
+        {
+
+        // we got new file, let's send it
+        CHAT_DP_TXT( "..got new file, sending it" );
+
+        DoSendFileL( *fileNames, aMessageRWInterfacePC, aSender );
+
+        }
+
+    CleanupStack::PopAndDestroy( 3, fileNames ); // params, newFile, fileNames
+    CHAT_DP_TXT( "Send new file done.." );
+    }
+
+// -----------------------------------------------------------------------------
+// CCAUiMessageUtils::SendImageL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAUiMessageUtils::SendImageL(
+    MCAGroupPC& aMessageRWInterfacePC,
+    const TDesC& aSender /* = KNullDesC */,
+    const MDesCArray* aScreenNames /* = NULL */,
+    TBool aIsWhisperAllowed /*= ETrue*/ )
+    {
+    TBool ok( EFalse );
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) )
+        {
+        // cancelled
+        return;
+        }
+
+    while ( !ok )
+        {
+        // only one image can be selected at the moment
+        CDesCArray* files = new( ELeave )CDesCArrayFlat( 1 );
+        CleanupStack::PushL( files );
+
+        HBufC* softkey = CCoeEnv::Static()->AllocReadResourceLC(
+                             R_TEXT_SOFTKEY_SELECT );
+
+        iBeginVerifySelection = EFalse;
+
+        // This rd flag is for testing purposes only.
+#ifndef RD_SEND_NOT_SUPPORTED_CONTENT
+        // only one image can be selected (EFalse)
+        if ( MGFetch::RunL( *files, EImageFile, EFalse, *softkey, KNullDesC, this ) )
+#else
+        if ( MGFetch::RunL( *files, EAnyMediaFile, EFalse, *softkey, KNullDesC, this ) )
+#endif //RD_SEND_NOT_SUPPORTED_CONTENT
+            {
+            // verify the selected image
+            iBeginVerifySelection = ETrue;
+            TBool verify = VerifySelectionL( files );
+
+            if ( !verify )
+                {
+                CleanupStack::PopAndDestroy( softkey ); // softkey
+                CleanupStack::PopAndDestroy( files );   // files
+                continue;
+                }
+
+#ifdef RD_IMAGEPREVIEW
+            //
+            // Open image preview
+            //
+            if ( files->MdcaCount() == 1 ) // We can only open 1 image
+                {
+                HBufC* skSelect = CCoeEnv::Static()->AllocReadResourceLC(
+                                      R_TEXT_SOFTKEY_SELECT );
+                HBufC* skBack = CCoeEnv::Static()->AllocReadResourceLC(
+                                    R_TEXT_SOFTKEY_BACK );
+
+                this->SetNavigationPaneDimmed( ETrue );
+
+                TInt res = ImagePreview::ShowImageL( files->MdcaPoint( 0 ),
+                                                     *skSelect, *skBack );
+
+                this->SetNavigationPaneDimmed( EFalse );
+
+                CleanupStack::PopAndDestroy( 2 ); // skSelect, skBack
+                ( res == EAknSoftkeyCancel ) ? ( ok = EFalse ) : ( ok = ETrue );
+                }
+            else
+                {
+                // Invalid number of images
+                __CHAT_ASSERT_DEBUG( EFalse );
+                }
+#endif //RD_IMAGEPREVIEW
+
+            if ( ok )
+                {
+                // send files
+                DoSendFileL( *files, aMessageRWInterfacePC, aSender );
+
+                }
+            CleanupStack::PopAndDestroy( 2 ); // files, softkey
+
+            }
+        else
+            {
+            // user canceled
+            CleanupStack::PopAndDestroy( 2 ); // files, softkey
+            ok = ETrue;
+            }
+        } //end of while
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::SendFileL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::SendFileL(
+    const MDesCArray& aFileNames,
+    MCAGroupPC& aMessageRWInterfacePC,
+    const TDesC& aSender /*= KNullDesC*/,
+    const MDesCArray* aScreenNames /*= NULL*/ )
+    {
+    // show the list of recipients first
+    if ( ! SelectRecipientsL( aScreenNames ) )
+        {
+        // cancelled
+        return;
+        }
+
+    DoSendFileL( aFileNames, aMessageRWInterfacePC, aSender );
+
+    }
+
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::SelectRecipientsL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAUiMessageUtils::SelectRecipientsL( const MDesCArray* aScreenNames,
+                                            TBool aIsWhisperAllowed /*= ETrue*/ )
+    {
+    delete iSelectedNames;
+    iSelectedNames = NULL;
+
+    // check if we're sending a group message and whispering is allowed.
+    // in that case, group members are in aScreenNames array
+
+    const MDesCArray* screenNames = aScreenNames;
+
+    if ( screenNames && aIsWhisperAllowed )
+        {
+        TInt count( screenNames->MdcaCount() );
+        if ( count > 0 )
+            {
+            // insert "All" to top of the list
+            HBufC* all = CCoeEnv::Static()->AllocReadResourceLC(
+                             R_QTN_CHAT_SEND_FILE_TO_ALL );
+            HBufC* title = CCoeEnv::Static()->AllocReadResourceLC(
+                               R_QTN_CHAT_SEND_FILE_TO );
+
+            // we have some screennames..
+            CDesCArray* lst = CAArrayUtils::CloneArrayLC( *screenNames );
+            lst->Sort();
+            lst->InsertL( 0, *all );
+
+            // show query
+            iSelectedNames =
+                IMDialogUtils::MultiselectionListQueryDialogL( *lst, *title );
+
+            CleanupStack::PopAndDestroy( 2, title ); // lst, title
+            if ( ! iSelectedNames )
+                {
+                // cancel
+                CleanupStack::PopAndDestroy( all );
+                return EFalse; // not accepted
+                }
+
+            if ( iSelectedNames->Count() > 0 )
+                {
+                TInt pos;
+                if ( iSelectedNames->Find( *all, pos ) == 0 )
+                    {
+                    // "All" selected, send message with
+                    // empty array of screennames
+                    iSelectedNames->Reset();
+                    }
+                }
+            CleanupStack::PopAndDestroy( all );
+            }
+        else
+            {
+            // possibly the user is in group by himself
+            // => send to all.
+            delete iSelectedNames;
+            iSelectedNames = NULL;
+            iSelectedNames = new( ELeave ) CDesCArrayFlat( 1 );
+            iSelectedNames->Reset();
+            }
+        }
+    else if ( !aIsWhisperAllowed )
+        {
+        // Whispering not allowed
+        // Send message with empty array of screennames
+        if ( !iSelectedNames )
+            {
+            iSelectedNames = new( ELeave ) CDesCArrayFlat( 1 );
+            }
+        iSelectedNames->Reset();
+        }
+
+    return ETrue; // was accepted
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::OpenObjectL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::OpenObjectL( MCAConversationMessage& aMsg )
+    {
+    CHAT_DP( D_CHAT_LIT( "*OpenObject: opening.." ) );
+    TEnumsPC::TContentProcessState state = aMsg.ContentProcessState();
+
+    switch ( state )
+        {
+        case TEnumsPC::EThumbnailReady:
+            {
+            if ( aMsg.MessagerType() != TEnumsPC::EMessageSent )
+                {
+
+                if ( aMsg.ContentData().Length() == 0 )
+                    {
+                    //In case there is only a thumbnail available in the buffer, because the real
+                    //image file is deleted because of lack of memory
+                    IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN );
+                    return;
+                    }
+                else
+                    {
+                    if ( aMsg.IsImageSaved() )
+                        {
+                        //In case there is only a thumbnail available in the buffer, because user
+                        //has saved the image
+                        IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN_SAVED );
+                        return;
+                        }
+                    }
+                }
+            else
+                {
+                //In case there is only a thumbnail available in the buffer, because user
+                //sent it by himself
+                IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN_SAVED );
+                return;
+                }
+
+            break;
+            }
+
+        case TEnumsPC::EContentCorrupted:
+            {
+            // => corrupted
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED );
+            return;
+            }
+
+        case TEnumsPC::EContentNotSupported:
+        case TEnumsPC::EContentNotSupportedDrm:
+            {
+            // => unsupported
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED );
+            return;
+            }
+
+        default:
+            {
+            break;
+            }
+        }
+
+
+    // save to a temporary file
+    HBufC* tempFileName = HBufC::NewMaxLC( KMaxPath );
+    TPtr tempFileNamePtr( tempFileName->Des() );
+
+    HBufC* fileName = NULL;
+
+    // Check if there is filename defined in message
+    const TDesC& origName = aMsg.Text();
+    if ( origName.Length() > 0 )
+        {
+        TParse parser;
+        User::LeaveIfError( parser.Set( origName, NULL, NULL ) );
+        TPtrC ptr = parser.Name();
+        fileName = ptr.AllocLC();
+        tempFileNamePtr.SetLength( 0 );
+        tempFileNamePtr.Insert( 0, *fileName );
+        }
+    else
+        {
+        fileName = CCoeEnv::Static()->AllocReadResourceLC(
+                       R_QTN_CHAT_UNNAMED_FILE );
+        }
+
+    TPtr fileNamePtr( fileName->Des() );
+
+    TDataType type( aMsg.MimeType() );
+    RFile tempFile;
+    CleanupClosePushL( tempFile );
+
+    CHAT_DP( D_CHAT_LIT( "*OpenObject: creating temporary file %S" ),
+             &fileNamePtr );
+    iDocHandler->SaveTempFileL( aMsg.ContentData(), type, fileNamePtr,
+                                tempFile );
+    iDocHandler->GetPath( tempFileNamePtr );
+    CHAT_DP( D_CHAT_LIT( "*OpenObject: created temporary file to %S" ),
+             &tempFileNamePtr );
+
+    // check rights
+    if ( !IMUtils::FileProtectedL( tempFileNamePtr ) )
+        {
+        // Create parameters to allow IV do saving
+        CAiwGenericParamList* params = CAiwGenericParamList::NewL();
+        CleanupStack::PushL( params );
+        TAiwGenericParam saveParam( EGenericParamAllowSave );
+        params->AppendL( saveParam );
+        // start the document
+        TRAPD( err, iDocHandler->OpenFileEmbeddedL( tempFile, type, *params ) );
+        if ( err == KErrNone )
+            {
+            // and wait for exit
+            CHAT_DP( D_CHAT_LIT( "*OpenObject: launched OpenFileEmbeddedL,\
+                        waiting for complete.. " ) );
+
+            if ( ! iWait.IsStarted() )
+                {
+                iWait.Start();  // CSI: 10 # iWait is not an active object
+                }
+            }
+        else
+            {
+            CHAT_DP( D_CHAT_LIT( "*OpenObject: OpenFileEmbeddedL left with %d " ),
+                     err );
+            CActiveScheduler::Current()->Error( err );
+            }
+        CleanupStack::PopAndDestroy( params );
+        }
+    else
+        {
+        // content is protected
+        IMDialogUtils::DisplayInformationNoteL(
+            R_QTN_DRM_NOT_ALLOWED );
+        }
+
+    // delete temporary file
+    CleanupStack::PopAndDestroy( 2, fileName ); // tempFile.Close(), fileName
+    CHAT_DP( D_CHAT_LIT( "*OpenObject: deleting %S" ), &tempFileNamePtr );
+    RFs& fs = CCoeEnv::Static()->FsSession();
+    fs.Delete( *tempFileName );
+
+    CleanupStack::PopAndDestroy( tempFileName );
+    CHAT_DP( D_CHAT_LIT( "*OpenObject: done" ) );
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::SaveObjectL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TInt CCAUiMessageUtils::SaveObjectL( MCAConversationMessage& aMsg )
+    {
+    CHAT_DP( D_CHAT_LIT( "*SaveObject: saving.." ) );
+    if ( aMsg.ContentData().Length() == 0 )
+        {
+        // No content
+        return KErrGeneral;
+        }
+
+    // Check if there is filename defined in message
+    HBufC* fileName = NULL;
+    const TDesC& origName = aMsg.Text();
+
+    if ( origName.Length() > 0 )
+        {
+        TParse parser;
+        User::LeaveIfError( parser.Set( origName, NULL, NULL ) );
+        TPtrC ptr = parser.Name();
+        fileName = parser.Name().AllocLC();
+        }
+    else
+        {
+        fileName = HBufC::NewLC( 0 );
+        }
+
+    TDataType type( aMsg.MimeType() );
+    RFile tempFile;
+    CleanupClosePushL( tempFile );
+
+    // First save to temp file
+    iDocHandler->SaveTempFileL( aMsg.ContentData(), type, *fileName, tempFile );
+    TFileName tempFileName;
+    TInt err = KErrNone;
+    tempFile.Name( tempFileName );
+    iDocHandler->GetPath( tempFileName );
+
+    // Copy temp file, asks user drive for copying and leaves if free space
+    // on requested drive is below or will fall below critical level
+    if ( origName.Length() > 0 )
+        {
+        err = iDocHandler->CopyL( tempFile, *fileName, type, KEntryAttNormal );
+        }
+    else
+        {
+        err = iDocHandler->CopyL( tempFile, KNullDesC, type, KEntryAttNormal );
+        }
+
+    //fix - refer Ui Spec Approved Version 1.0
+    //(Instant Messaging NG 001 151006.pdf)
+    //Section 10.2.10 Pg 131 -
+    //"In case user has saved the image already or sent it
+    //by himself, this option(save) is not available."
+    if ( err == KErrNone )
+        {
+        aMsg.SetImageAsSaved( ETrue );
+        }
+    CleanupStack::PopAndDestroy( 2, fileName );  // tempFile.Close(), fileName
+
+    // Delete temp file
+    RFs& fs = CCoeEnv::Static()->FsSession();
+    fs.Delete( tempFileName );
+
+    return err;
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::HandleServerAppExit
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::HandleServerAppExit( TInt aReason )
+    {
+    iServerAppExitReason = aReason;
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop();
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::VerifySelectionL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAUiMessageUtils::VerifySelectionL( const MDesCArray* aSelectedFiles )
+    {
+    if ( !iBeginVerifySelection )
+        {
+        return ETrue;
+        }
+
+    TBool ok( EFalse );
+    TBool protectedCount( 0 );
+    TBool corruptedImage( EFalse );
+
+#ifndef RD_SEND_NOT_SUPPORTED_CONTENT
+    if ( aSelectedFiles )
+        {
+        TInt count( aSelectedFiles->MdcaCount() );
+        for ( TInt i( 0 ); i < count; ++i )
+            {
+            TUid dummyUid( KNullUid );
+            TDataType dataType;
+            TPtrC filename( aSelectedFiles->MdcaPoint( i ) );
+            User::LeaveIfError( iApaSession.AppForDocument(
+                                    filename,
+                                    dummyUid, dataType ) );
+
+            //Mime type is empty for non image files (e.g book marks)
+            // so retrun false
+            if ( dataType.Des8().CompareF( KMimeTypeEmpty ) == 0 )
+                {
+                return EFalse;
+                }
+
+            if ( dataType.Des8().CompareF( KMimeTypeJpeg ) == 0 ||
+                 dataType.Des8().CompareF( KMimeTypeGif ) == 0 )
+                {
+                // selected object is gif or jpeg
+                if ( !IMUtils::FileProtectedL( filename ) )
+                    {
+                    // if not protected => image is ok
+                    ok = ETrue;
+                    }
+                else
+                    {
+                    ++protectedCount;
+                    }
+                }
+
+            // try to open and decode picture to make sure it's
+            // not corrupted.
+
+            delete iDecoder;
+            iDecoder = NULL;
+
+            TInt params( CImageDecoder::EOptionNone
+#ifndef RD_30_COMPATIBILITY_MODE
+                         | CImageDecoder::EPreferFastDecode
+#endif
+                       );
+
+            TRAPD( err, iDecoder = CImageDecoder::FileNewL(
+                                       CEikonEnv::Static()->FsSession(), filename,
+                                       static_cast<CImageDecoder::TOptions>( params ) ) );
+
+            if ( err == KErrNone )
+                {
+                // file seems ok, try to decode image
+                CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap();
+                CleanupStack::PushL( bitmap );
+
+                TFrameInfo frame =  iDecoder->FrameInfo();
+                TSize decodeSize( DecodeSize( frame.iOverallSizeInPixels ) );
+
+                TInt bitmaperr =
+                    bitmap->Create( decodeSize, frame.iFrameDisplayMode );
+
+                if ( bitmaperr )
+                    {
+                    CHAT_DP( D_CHAT_LIT( "CCAUiMessageUtils::VerifySelectionL:\
+                            Unable to create bitmap (%d)" ), bitmaperr );
+                    CActiveScheduler::Current()->Error( bitmaperr );
+                    CleanupStack::PopAndDestroy( bitmap );
+                    return EFalse;
+                    }
+                // start converting
+                iDecoder->Convert( &iStatus, *bitmap );
+                if ( !IsActive() )
+                    {
+                    SetActive();
+                    }
+
+                // and wait until it's finished
+                if ( !iWait.IsStarted() )
+                    {
+                    iWait.Start();  // CSI: 10 # iWait is not an active object
+                    }
+
+                TInt statuscode = iStatus.Int();
+                CleanupStack::PopAndDestroy( bitmap );
+
+                if ( statuscode == KErrCorrupt )
+                    {
+                    CHAT_DP_TXT( "CCAUiMessageUtils::VerifySelectionL\
+                            corrupted: decode failed" );
+                    corruptedImage = ETrue;
+                    }
+
+                delete iDecoder;
+                iDecoder = NULL;
+                }
+            else
+                {
+                // something wrong with opening file
+                // -> assume corrupt
+                corruptedImage = ETrue;
+                }
+            }
+        }
+    else
+        {
+        return ok;
+        }
+#else
+    ok = ETrue;
+#endif //RD_SEND_NOT_SUPPORTED_CONTENT
+
+    if ( protectedCount > 0 )
+        {
+        // some of the files were protected
+        IMDialogUtils::DisplayQueryDialogL(
+            protectedCount == 1 ?
+            R_QTN_DRM_INFO_SEND_FORBID_ONE :
+            R_QTN_DRM_INFO_SEND_FORBID_SOME );
+        }
+    else if ( corruptedImage )
+        {
+        IMDialogUtils::DisplayQueryDialogL( R_QTN_MMS_UPLOAD_INFO_CORRUPTED );
+        ok = EFalse; // don't allow selection of this image
+        }
+    else if ( !ok && aSelectedFiles->MdcaCount() != 0 )
+        {
+        // not ok, show note
+        IMDialogUtils::DisplayQueryDialogL( R_QTN_MMS_INFO_OBJ_NOT_SUPP_SEND );
+        }
+    return ok;
+    }
+
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::DecodeSize
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TSize CCAUiMessageUtils::DecodeSize( const TSize& aSize )
+    {
+    // 1:1 is always valid ratio for decode scaling
+    TInt lastValidRatio( 1 );
+    for ( TInt ratio( KDecodeScaleRatioMin ); ratio <= KDecodeScaleRatioMax; ratio <<= 1 )
+        {
+        if ( aSize.iWidth % ratio + aSize.iHeight % ratio == 0 )
+            {
+            // this ratio is valid
+            lastValidRatio = ratio;
+            }
+        }
+
+    // return the size scaled with correct ratio
+    return TSize( aSize.iWidth / lastValidRatio,
+                  aSize.iHeight / lastValidRatio );
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::ForwardContentMessageL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAUiMessageUtils::ForwardContentMessageL(
+    const MCAConversationMessage& aMessage,
+    const TDesC& aRecipient,
+    const MDesCArray* aScreenNames,
+    MCAConversationPC& aMessageRWInterfacePC,
+    TBool aIsWhisperingAllowed,
+    const TDesC& aSender /*= KNullDesC*/ )
+    {
+    // picture was forwarded
+    if ( aMessage.ContentType() == TEnumsPC::EContentPicture )
+        {
+        // Check image state and DRM.
+        // We should not get corrupted or DRM files at this point,
+        // but it's better to make sure of it.
+        TBool isProtected( IMUtils::ContentProtectedL( aMessage.ContentData() ) );
+
+        TEnumsPC::TContentProcessState state =
+            aMessage.ContentProcessState();
+        if ( state == TEnumsPC::EContentCorrupted )
+            {
+            // => corrupted
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED );
+            // Message was handled as best as we could
+            return ETrue;
+            }
+        else if ( state == TEnumsPC::EContentNotSupported ||
+                  state == TEnumsPC::EContentNotSupportedDrm ||
+                  isProtected )
+            {
+            // => unsupported
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED );
+            // Message was handled as best as we could
+            return ETrue;
+            }
+
+        // Image seems to be ok, so let's continue forwarding.
+
+        // show the list of recipients first
+        if ( aScreenNames )
+            {
+            if ( !SelectRecipientsL( aScreenNames, aIsWhisperingAllowed ) )
+                {
+                // cancelled. Return true because it needs to seem that
+                // we handled the message.
+                return ETrue;
+                }
+            }
+        else
+            {
+            // this has to be Null when sending a PtoP message.
+            delete iSelectedNames;
+            iSelectedNames = NULL;
+            }
+
+        IMMessageUtilsPC::SendMessageL(
+            aMessage,
+            aRecipient,
+            aMessageRWInterfacePC,
+            iSelectedNames,
+            aSender ) ;
+
+        // message handled succesfully
+        return ETrue;
+        }
+
+    // We handle only pictures here, so message was not handled.
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::ForwardContentMessageL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAUiMessageUtils::ForwardContentMessageL(
+    const MCAConversationMessage& aMessage,
+    const TDesC& aRecipient,
+    const MDesCArray* aScreenNames,
+    MCAGroupPC& aMessageRWInterfacePC,
+    TBool aIsWhisperingAllowed,
+    const TDesC& aSender /*= KNullDesC*/ )
+    {
+    // picture was forwarded
+    if ( aMessage.ContentType() == TEnumsPC::EContentPicture )
+        {
+        // Check image state and DRM.
+        // We should not get corrupted or DRM files at this point,
+        // but it's better to make sure of it.
+        TBool isProtected( IMUtils::ContentProtectedL( aMessage.ContentData() ) );
+
+        TEnumsPC::TContentProcessState state =
+            aMessage.ContentProcessState();
+        if ( state == TEnumsPC::EContentCorrupted )
+            {
+            // => corrupted
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED );
+            // Message was handled as best as we could
+            return ETrue;
+            }
+        else if ( state == TEnumsPC::EContentNotSupported ||
+                  state == TEnumsPC::EContentNotSupportedDrm ||
+                  isProtected )
+            {
+            // => unsupported
+            IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED );
+            // Message was handled as best as we could
+            return ETrue;
+            }
+
+        // Image seems to be ok, so let's continue forwarding.
+
+        // show the list of recipients first
+        if ( aScreenNames )
+            {
+            if ( !SelectRecipientsL( aScreenNames, aIsWhisperingAllowed ) )
+                {
+                // cancelled. Return true because it needs to seem that
+                // we handled the message.
+                return ETrue;
+                }
+            }
+        else
+            {
+            // this has to be Null when sending a PtoP message.
+            delete iSelectedNames;
+            iSelectedNames = NULL;
+            }
+
+        IMMessageUtilsPC::SendMessageL(
+            aMessage,
+            aRecipient,
+            aMessageRWInterfacePC,
+            iSelectedNames,
+            aSender ) ;
+
+        // message handled succesfully
+        return ETrue;
+        }
+
+    // We handle only pictures here, so message was not handled.
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::DoSendFileL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::DoSendFileL(
+    const MDesCArray& aFileNames,
+    MCAConversationPC& aMsgRWInterface,
+    const TDesC& aSender /*= KNullDesC*/ )
+    {
+
+    TDataType dataType;
+    TPtrC8 mimeType;
+    TBool sendOption;
+
+    // check file before it will be sent.
+    if ( CheckFileL( aFileNames, dataType, mimeType, sendOption ) )
+        {
+        TPtrC fileName( aFileNames.MdcaPoint( 0 ) );
+        IMMessageUtilsPC::SendFileL( aMsgRWInterface,
+                                     iSelectedNames,
+                                     sendOption,
+                                     fileName,
+                                     mimeType,
+                                     KNullDesC8,
+                                     aSender );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::DoSendFileL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::DoSendFileL(
+    const MDesCArray& aFileNames,
+    MCAGroupPC& aMsgRWInterface,
+    const TDesC& aSender /*= KNullDesC*/ )
+    {
+    TDataType dataType;
+    TPtrC8 mimeType;
+    TBool sendOption;
+
+    // check file before it will be sent.
+    if ( CheckFileL( aFileNames, dataType, mimeType, sendOption ) )
+        {
+        TPtrC fileName( aFileNames.MdcaPoint( 0 ) );
+        IMMessageUtilsPC::SendFileL( aMsgRWInterface,
+                                     iSelectedNames,
+                                     sendOption,
+                                     fileName,
+                                     mimeType,
+                                     KNullDesC8,
+                                     aSender );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::CheckFileL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAUiMessageUtils::CheckFileL( const MDesCArray& aFileNames, TDataType& aDataType, TPtrC8& aMimeType, TBool& aSendOption )
+    {
+    if ( aFileNames.MdcaCount() == 0 )
+        return EFalse;
+
+    // Check if recipient is blocked
+    if ( iBlockChecker )
+        {
+        iBlockChecker->CheckBlockedL();
+        }
+
+    TPtrC fileName( aFileNames.MdcaPoint( 0 ) );
+    TUid dummyUid( KNullUid );
+
+#ifndef RD_SEND_NOT_SUPPORTED_CONTENT
+
+    if ( IMUtils::FileProtectedL( fileName ) )
+        return EFalse;
+
+    // not drm-protected
+    User::LeaveIfError( iApaSession.AppForDocument( fileName,
+                                                    dummyUid,
+                                                    aDataType ) );
+    aMimeType.Set( aDataType.Des8() );
+    aSendOption = EFalse;
+
+    return ETrue;
+#else
+
+    TInt err( iApaSession.AppForDocument( fileName, dummyUid, aDataType ) );
+    if ( err == KErrNone )
+        aMimeType.Set( aDataType.Des8() );
+    else
+        aMimeType.Set( KMimeTypeJpeg );
+
+    if ( !IMUtils::FileProtectedL( fileName ) )
+        aSendOption = EFalse;
+    else
+        aSendOption = ETrue;
+
+    return ETrue;
+#endif //RD_SEND_NOT_SUPPORTED_CONTENT
+    }
+
+// ---------------------------------------------------------
+// CCAUiMessageUtils::SetNaviPaneDimmed
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAUiMessageUtils::SetNavigationPaneDimmed( TBool aDimmed )
+    {
+    CEikStatusPane* statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane();
+    CCoeControl* control = statusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
+    CAknNavigationControlContainer* navipane = static_cast<CAknNavigationControlContainer*>( control );
+    statusPane->SetDimmed( aDimmed );
+    }
+
+//  End of File