mobilemessaging/postcard/postcardsrc/PostcardOperationInsertImage.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/postcard/postcardsrc/PostcardOperationInsertImage.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,560 @@
+/*
+* Copyright (c) 2005 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:  
+*       CPostcardOperationInsertImage
+*
+*/
+
+
+
+// ========== INCLUDE FILES ================================
+
+#include <AknsConstants.h>
+#include <data_caging_path_literals.hrh> 
+#include <apmstd.h>  // TDataType
+#include <f32file.h> // RFs, RFile
+#include <gulicon.h> // CGulIcon
+#include <apmstd.h>  // TDataType
+#include <e32des8.h>
+
+#include <IHLImageFactory.h>
+#include <IHLViewerFactory.h>
+#include <MIHLFileImage.h>
+#include <MIHLBitmap.h>
+#include <MIHLImageViewer.h>
+
+#include <mmsvattachmentmanager.h>
+#include <mmsvattachmentmanagersync.h>
+#include <cmsvattachment.h>
+#include <cmsvmimeheaders.h>
+
+#include <MsgMediaResolver.h>
+#include <MsgMediaInfo.h>
+#include <MsgImageInfo.h>
+#include <MsgMimeTypes.h>
+
+#include <mmsclient.h>
+#include <Postcard.rsg>
+
+#include "PostcardOperationInsertImage.h"
+#include "PostcardLaf.h"
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::NewL
+//
+// Factory method.
+// ---------------------------------------------------------
+//
+CPostcardOperationInsertImage* CPostcardOperationInsertImage::NewL(
+            MPostcardOperationObserver& aObserver,
+            CPostcardDocument& aDocument,
+            CPostcardAppUi& aAppUi,
+            CMsgImageInfo* aInfo,
+            RFs& aFs )
+    {
+    CPostcardOperationInsertImage* self = 
+        new ( ELeave ) CPostcardOperationInsertImage( aObserver, aDocument, aAppUi, aInfo, aFs );
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::CPostcardOperationInsertImage
+// ---------------------------------------------------------
+CPostcardOperationInsertImage::CPostcardOperationInsertImage(
+            MPostcardOperationObserver& aObserver,
+            CPostcardDocument& aDocument,
+            CPostcardAppUi& aAppUi,
+            CMsgImageInfo* aInfo,
+            RFs& aFs ) :
+    CPostcardOperation( aObserver, aDocument, aAppUi, aFs ),
+    iInfo( aInfo )
+    {
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::CPostcardOperationInsertImage
+// ---------------------------------------------------------
+CPostcardOperationInsertImage::~CPostcardOperationInsertImage( )
+    {
+    delete iImageProcessor;
+    delete iInfo;
+    if( iCompressFile )
+    	{
+    	iCompressFile->Close();
+        delete iCompressFile;
+        iCompressFile = NULL;
+    	}
+    Cancel( );
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::Start
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::Start( TInt /*aArgument*/ )
+    {
+    iLaunchState = EPostcardInsertImageInitializing;
+    CompleteSelf( KErrNone );
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::Launch
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoLaunchStepL()
+    {
+    iFlags &= ~EPostcardInsertImageRequestActive;
+    switch ( iLaunchState )
+        {
+        case EPostcardInsertImageInitializing:
+            {
+            InitL( );
+            iLaunchState = EPostcardInsertImageCheckAttas;
+            CompleteSelf( KErrNone );
+            break;
+            }
+        case EPostcardInsertImageCheckAttas:
+            {
+            if( !CheckAttasL( ) )
+            	{ // If there was error, this has been completed already
+	            iLaunchState = EPostcardInsertImageCreateAtta;
+	            CompleteSelf( KErrNone );
+            	}
+            break;
+            }
+        case EPostcardInsertImageCreateAtta:
+            {
+            DoCreateAttaL( );
+            break;
+            }
+        case EPostcardInsertImageRename:
+        	{
+        	DoRenameAttaL( );
+        	break;
+        	}
+        case EPostcardInsertProcessImage:
+        	{
+        	DoStartProcessImageL( );
+        	break;
+        	}
+        case EPostcardInsertImageFinalizeSave:
+            {
+            DoFinalizeSaveL( );
+            iLaunchState = EPostcardInsertImageCreateBitmap;
+            CompleteSelf( KErrNone );
+            break;
+            }
+      	case EPostcardInsertImageCreateBitmap:
+      		{
+      		DoCreateBitmapL( );
+      		break;	
+      		}
+        case EPostcardInsertImageFinished:
+            {
+		    UnInitL( );
+            iObserver.PostcardOperationEvent(
+                EPostcardOperationInsertImage,
+                EPostcardOperationComplete ); 
+            break;
+            }
+        default:
+		    UnInitL( );
+            iObserver.PostcardOperationEvent(
+                EPostcardOperationInsertImage,
+                EPostcardOperationError ); 
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// DoCreateAttaL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoCreateAttaL( )
+    {
+    CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
+    CleanupStack::PushL( attachment );
+    
+	if( iImage )
+		{ // Remove the old image
+	 	TInt oldImage = TMsvIdToIndexL( iImage );
+		iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( oldImage );
+		}
+
+	TSize size = iInfo->Dimensions( );
+
+	TInt width = size.iWidth;
+	TInt height = size.iHeight;
+	if( height > width )
+		{
+		width = size.iHeight;
+		height = size.iWidth;
+		}
+	
+	TBool needsScaling = EFalse;
+	TBool isJpeg = EFalse;
+	
+    if( iInfo->MimeType( ).CompareF( KMsgMimeImageJpeg ) == 0 )
+		{
+		isJpeg = ETrue;
+		}
+	else if( iInfo->MimeType( ).CompareF( KMsgMimeImagePng ) == 0 )
+        { // PNG always needs to be converted into jpeg
+        needsScaling = ETrue;
+        }
+        
+	if( needsScaling )   
+		{
+        // Needs converting first -> create just an empty RFile for now
+   	    iCompressFile = new ( ELeave ) RFile;
+	    attachment->SetMimeTypeL( KMsgMimeImageJpeg );
+	    attachment->SetAttachmentNameL( KPostcardFilenameScaled );
+        iManager->CreateAttachmentL( KPostcardFilenameScaled, *iCompressFile, attachment, iStatus );
+        iLaunchState = EPostcardInsertProcessImage;
+	    iCompressAtta = attachment;
+
+        iFlags |= EPostcardInsertImageRequestActive;
+        }
+    else
+        {
+        TBool needsCompress = NeedsCompress( ); 
+        TParsePtrC parse( iInfo->FullFilePath() );
+
+		if( isJpeg )
+			{
+		    attachment->SetMimeTypeL( KMsgMimeImageJpeg );
+			}
+		else
+			{
+		    attachment->SetMimeTypeL( KMsgMimeImageGif );
+			}
+
+        if( needsCompress )    
+        	{ // Compression needed -> create just an empty attachment for now
+    	    iCompressFile = new ( ELeave ) RFile;
+    	    attachment->SetAttachmentNameL( KPostcardFilenameCompressed );
+            iManager->CreateAttachmentL( KPostcardFilenameCompressed, *iCompressFile, attachment, iStatus );
+            iFlags |= EPostcardInsertImageRequestActive;
+	        iLaunchState = EPostcardInsertProcessImage;
+			iCompressAtta = attachment;
+        	}
+        else
+        	{
+        	if( isJpeg )
+        		{
+	    	    attachment->SetAttachmentNameL( KPostcardFilenameNoOp );
+        		}
+        	else
+        		{
+	    	    attachment->SetAttachmentNameL( KPostcardFilenameNoOpGif );
+        		}
+            iManager->AddAttachmentL( iInfo->FullFilePath( ), attachment, iStatus );
+            iFlags |= EPostcardInsertImageRequestActive;
+            iLaunchState = EPostcardInsertImageFinalizeSave;
+            iNoOpAtta = attachment;
+        	}
+        }
+
+    CleanupStack::Pop( attachment );
+    SetActive();    	    			
+    }
+
+// ---------------------------------------------------------
+// DoStartProcessImageL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoStartProcessImageL( )
+	{
+	if( !iImageProcessor )
+	    {
+        iImageProcessor = new (ELeave) CUniImageProcessor( this );	    
+	    }
+    RFile tempFile;
+	User::LeaveIfError( tempFile.Open( iFs, iInfo->FullFilePath( ), EFileRead | EFileShareAny ) );
+    CleanupClosePushL( tempFile );    
+	
+	TSize maxDimensions = iDocument.MaxImageDimensions( );
+
+	TSize origDimensions = static_cast<CMsgImageInfo*>(iInfo)->Dimensions( );
+
+	if( origDimensions.iWidth < origDimensions.iHeight )
+		{ // It's portrait so swap max dimensions
+		origDimensions = maxDimensions;
+		maxDimensions.iWidth = origDimensions.iHeight;
+		maxDimensions.iHeight = origDimensions.iWidth;
+		}
+
+    iImageProcessor->ProcessImageL( 	tempFile, 
+    									*iCompressFile, 
+    									maxDimensions,
+    									KMsgMimeImageJpeg, 
+    									ETrue,
+    									iDocument.MaxImageSize( ) );
+    CleanupStack::PopAndDestroy( &tempFile ); // tempFile
+	}
+
+// ---------------------------------------------------------
+// DoFinalizeSaveL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoFinalizeSaveL( )
+    {
+    
+    iHeaders = CMsvMimeHeaders::NewL( );
+    
+    CMsvAttachment* atta = iNoOpAtta;
+    if( iScaleAtta )
+    	{
+    	atta = iScaleAtta;
+    	}
+    
+    if( iCompressAtta )
+    	{
+		atta = iCompressAtta;
+    	}
+    
+    if( atta )
+    	{
+		iHeaders->SetContentLocationL( atta->AttachmentName( ) );
+		iHeaders->SetContentTypeL( atta->MimeType( ) );
+	    iHeaders->StoreL( *atta );
+    	}
+	
+    // Lets remove the flag just in case
+    iFlags &= ~EPostcardInsertImageConvertingImage;
+    
+	iStore->Commit( ); // Is this needed?
+    
+    CheckAttasL( );
+    
+    iCommit = ETrue;
+    }
+
+// ---------------------------------------------------------
+// DoCreateBitmapL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoCreateBitmapL( )
+	{
+	RFile imageFile = iManager->GetAttachmentFileL( iImage );
+	CleanupClosePushL( imageFile );
+	
+	// The scaling for screen bitmap is started here
+
+    iSourceImage = IHLImageFactory::OpenFileImageL( imageFile );
+    iDestinationBitmap = IHLBitmap::CreateL();
+    
+    iImageHandler = IHLViewerFactory::CreateImageViewerL( PostcardLaf::Image( ).Size( ), 
+                                                    *iSourceImage, 
+                                                    *iDestinationBitmap, 
+                                                    *this, 
+                                                    TUint32( 0 ) );
+    User::LeaveIfError( iImageHandler->SetSourceRectPosition( TPoint( 0, 0 ) ) );
+
+    CleanupStack::PopAndDestroy( &imageFile );   // imageFile
+	}
+
+// ---------------------------------------------------------
+// NeedsCompress
+// ---------------------------------------------------------
+TBool CPostcardOperationInsertImage::NeedsCompress( )
+    {
+    if ( iInfo->FileSize( ) > iDocument.MaxMessageSize( ) )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// ImageProcessingReady
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::ImageProcessingReady( TSize aBitmapSize, TInt aFileSize, TBool /*aCompressed*/ )
+	{
+    if( iCompressFile )
+	    {
+        iCompressFile->Close();
+        delete iCompressFile;
+        iCompressFile = NULL;
+	    }
+
+	TBool imageFits = EFalse;
+	TSize maxDimensions = iDocument.MaxImageDimensions( );
+	if( aBitmapSize.iWidth <= maxDimensions.iWidth && 
+		aBitmapSize.iHeight <= maxDimensions.iHeight )
+		{
+		imageFits = ETrue;
+		}
+	else if( aBitmapSize.iWidth <= maxDimensions.iHeight && 
+		aBitmapSize.iHeight <= maxDimensions.iWidth )
+		{
+		imageFits = ETrue;
+		}
+
+	if( aBitmapSize.iWidth == 0 || !imageFits ||
+	    aFileSize > iDocument.MaxImageSize( ) )
+		{ // The process was not successful
+        SetError( R_POSTCARD_PROCESS_NOT_SUCCESSFUL );
+        iLaunchState = EPostcardInsertImageError;
+        CompleteSelf( -1 );
+        return;
+		}
+
+	iLaunchState = EPostcardInsertImageFinalizeSave;
+    CompleteSelf( KErrNone );
+	}
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::DoRenameAttaL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoRenameAttaL( )
+	{
+	if( iNoOpAtta )
+		{
+	    TInt count = iManager->AttachmentCount( );
+	    CMsvAttachment* atta = NULL;
+	    for(TInt a = 0; a<count; a++)
+	        {
+	        atta = iManager->GetAttachmentInfoL( a );
+	        CleanupStack::PushL( atta );
+			if( iScaleAtta->FilePath( ).CompareF( atta->FilePath( ) ) == 0 )
+				{
+				iManager->RenameAttachmentL( a, iNoOpAtta->AttachmentName( ), iStatus );			
+				SetActive( );
+				break;
+				}
+	        }
+		}
+    iLaunchState = EPostcardInsertImageFinalizeSave;
+	}
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::ConstructL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::ConstructL( )
+    {
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::ViewerBitmapChangedL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::ViewerBitmapChangedL()
+    {
+    CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+    CFbsBitmap* mask = NULL;
+    bitmap->Duplicate( iDestinationBitmap->Bitmap().Handle( ) );
+    
+    if ( iDestinationBitmap->HasMask() )
+        {
+        mask = new (ELeave) CFbsBitmap;
+        mask->Duplicate( iDestinationBitmap->Mask().Handle( ) );
+        }
+    
+    delete iDestinationBitmap;
+    iDestinationBitmap = NULL;
+    
+    delete iSourceImage;
+    iSourceImage = NULL;
+    
+    delete iImageHandler;
+    iImageHandler = NULL;
+    
+    iLaunchState = EPostcardInsertImageFinished;
+        
+    CGulIcon* icon = NULL;
+    TRAPD( err, icon = CGulIcon::NewL( bitmap, mask ) );
+
+    if( err )
+        { // Lets nullify it if there was an error
+        icon = NULL;
+        }
+        
+	iAppUi.SetImage( icon );
+
+	CompleteSelf( KErrNone );        
+        
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::ViewerError
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::ViewerError( TInt /*aError*/ )
+    {
+    delete iDestinationBitmap;
+    iDestinationBitmap = NULL;
+    
+    delete iSourceImage;
+    iSourceImage = NULL;
+    
+    delete iImageHandler;
+    iImageHandler = NULL;
+
+	SetError( R_POSTCARD_FORMAT_NOT_SUPPORTED );
+    iLaunchState = EPostcardInsertImageError;
+	CompleteSelf( -3 );
+	return;
+    }
+    
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::DoCancel
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::DoCancel( )
+    {
+    if( iManager )
+        {
+        if( iFlags & EPostcardInsertImageRequestActive )
+            {
+            iManager->CancelRequest();                
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CPostcardOperationInsertImage::RunL
+// ---------------------------------------------------------
+void CPostcardOperationInsertImage::RunL( )
+    {
+    DoLaunchStepL( );
+    }
+
+// ---------------------------------------------------------
+// RunError
+// ---------------------------------------------------------
+TInt CPostcardOperationInsertImage::RunError( TInt aError )
+    {
+    iLaunchState = -1;
+    SetError( aError );
+    iObserver.PostcardOperationEvent(
+        EPostcardOperationInsertImage,
+        EPostcardOperationError );     
+    return KErrNone;
+    }
+
+
+// EOF