imageeditor/EditorProvider/src/ImageRotaterProvider.cpp
changeset 1 edfc90759b9f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imageeditor/EditorProvider/src/ImageRotaterProvider.cpp	Fri Jan 29 13:53:17 2010 +0200
@@ -0,0 +1,610 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "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:
+* Ixonos Plc
+*
+* Description:  
+*
+*/
+
+
+
+// INCLUDES
+#include <eikmenup.h>
+#include <eikenv.h>
+#include <eikproc.h>
+#include <bautils.h>
+#include <e32property.h>
+
+#include <ImageEditorProviderInternal.rsg>
+#include <aiwmenu.h>
+#include <ImplementationProxy.h>
+#include <aknutils.h>
+#include <ImageConversion.h>
+#include <AknOpenFileService.h>
+
+#include "ImageEditorProvider.hrh"
+#include "JpegRotatorHelper.h"
+#include "ImageRotaterProvider.h"
+#include "ImageEditorUids.hrh"
+#include "ImageEditorUtils.h"
+#include "commondefs.h"
+
+#include <AiwCommon.hrh>
+#include <AiwCommon.h>
+#include <eikstart.h>
+#include <PathInfo.h>
+#include <apgcli.h>
+
+
+#include <ErrorUI.h>
+
+// LOCAL CONSTANTS AND MACROS
+#ifdef DRM_SUPPORT
+#include <DRMCommon.h>
+#define DRM_FILE_ARG(x) x
+#else
+#define DRM_FILE_ARG(x)
+#endif
+
+#ifdef JPEG_ROTATOR_AIW_PROVIDER_SUPPORT
+#define JPEG_ROTATOR_AIW_PROVIDER_SUPPORT_ARG(x) x
+#else
+#define JPEG_ROTATOR_AIW_PROVIDER_SUPPORT_ARG(x)
+#endif
+
+#ifdef AIW_MULTIPLE_FILE_SUPPORT
+const TBool KMultipleFileSupport = ETrue;
+#else
+const TBool KMultipleFileSupport = EFalse;
+#endif
+
+// debug log
+#include "imageeditordebugutils.h"
+_LIT(KEditorServiceProviderLogFile,"EditorServiceProvider.log");
+
+// resource file
+_LIT (KResourceFile, "\\resource\\imageeditorproviderinternal.rsc");
+
+// application
+
+
+//=============================================================================
+CRotateProvider * CRotateProvider::NewL()
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::NewL");
+
+	return new (ELeave) CRotateProvider;
+}
+
+//=============================================================================
+CRotateProvider::CRotateProvider()
+: iResLoader(*CEikonEnv::Static()),
+  iResLoaderOpen(EFalse),
+  iFileServerConnected(EFalse)
+{
+
+}
+
+//=============================================================================
+CRotateProvider::~CRotateProvider()
+{
+	LOG(KEditorServiceProviderLogFile, "CRotateProvider::~CRotateProvider");
+
+	iCallback = NULL;
+
+	if (iInParamList)
+		{
+		iInParamList->Reset();
+		delete iInParamList;
+		}
+	if (iOutParamList)
+		{
+		iOutParamList->Reset();
+		delete iOutParamList;
+		}
+
+	iFileHandle.Close();
+
+#ifdef VERBOSE  	
+    TInt count = iSharableFS.ResourceCount();   
+    LOGFMT(KEditorServiceProviderLogFile, "Resource count: %d", count);
+	iSharableFS.ResourceCountMarkEnd();
+#endif
+
+	delete iInputFileList;
+	delete iTargetFileList;
+
+	delete iJpegRotatorHelper;	
+
+    iSharableFS.Close();
+    iResLoader.Close();
+}
+
+//=============================================================================
+void CRotateProvider::InitialiseL (
+	MAiwNotifyCallback &			/*aFrameworkCallback*/,
+	const RCriteriaArray &			/*aInterest*/
+    )
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::InitialiseL");
+
+    if (!iInParamList)
+    {
+        iInParamList = CAiwGenericParamList::NewL();    
+    }
+
+    if (!iOutParamList)
+    {
+        iOutParamList = CAiwGenericParamList::NewL();    
+    }
+    
+    if (!iResLoaderOpen)
+        {
+        //	Load AIW edit provider internal resource file
+        TFileName fileName;
+        TParse p;    
+
+        Dll::FileName(fileName);
+        p.Set(KResourceFile, &fileName, NULL);
+        iResourceFile = p.FullName();
+        BaflUtils::NearestLanguageFile( CEikonEnv::Static()->FsSession(), iResourceFile );
+
+        LOGFMT(KEditorServiceProviderLogFile, "\tLoading resource file: %S", &iResourceFile);
+
+		iResLoader.OpenL ( iResourceFile );
+        iResLoaderOpen = ETrue;
+
+        LOG(KEditorServiceProviderLogFile, "\tResources loaded succesfully");
+        }
+
+    // Connect to file server     
+    if (!iFileServerConnected)
+    {
+        User::LeaveIfError(iSharableFS.Connect());    
+        iFileServerConnected = ETrue;
+
+#ifdef VERBOSE        
+        iSharableFS.ResourceCountMarkStart();
+#endif
+
+        // Share file server sessions with other processes. Needed for Open File service.
+        User::LeaveIfError(iSharableFS.ShareProtected());
+    }   
+    
+    LOG(KEditorServiceProviderLogFile, "\tInitialized.");
+}
+
+//=============================================================================
+void CRotateProvider::InitializeMenuPaneL (
+    CAiwMenuPane &                  aMenuPane,
+    TInt                            aIndex,
+    TInt                            /*aCascadeId*/,
+    const CAiwGenericParamList &    aInParamList
+    )
+    {
+	LOG(KEditorServiceProviderLogFile, "CRotateProvider::InitializeMenuPaneL: In");
+
+	if (BaflUtils::FileExists(iSharableFS, iResourceFile))
+		{
+		// Check how many input files & examine the MIME types
+		CDesCArray* fileList = CheckInputFilesLC( aInParamList );
+		RArray<TDataType> mimeTypeList;
+		CleanupClosePushL(mimeTypeList);
+
+		if( fileList && fileList->Count())
+			{
+			// If we support multiple selection, all the files are opened here.
+			// This migh be very slow.
+			TInt inputFileCount = fileList->MdcaCount();
+
+			LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::InitializeMenuPaneL: inputFileCount: %d", inputFileCount);
+
+			// Get the MIME type(s) of the file(s)
+			RApaLsSession lsSession;
+			TInt err = lsSession.Connect();
+			CleanupClosePushL (lsSession);
+			for( TInt i = 0; i < inputFileCount; i++ )
+				{
+				TDataRecognitionResult dataType;
+				RFile file;
+				err = file.Open (iSharableFS, fileList->MdcaPoint(i), EFileShareReadersOnly);
+				if (KErrNone != err)
+					{
+					// second try...
+					err = file.Open (iSharableFS, fileList->MdcaPoint(i), EFileShareAny);
+					}
+				if (KErrNone == err)
+					{
+					CleanupClosePushL( file );
+					User::LeaveIfError( lsSession.RecognizeData(file, dataType) );
+					mimeTypeList.AppendL( dataType.iDataType );
+					CleanupStack::PopAndDestroy(); // file
+					}
+				else
+					{
+					mimeTypeList.AppendL( TDataType() );
+					}
+				}
+			CleanupStack::PopAndDestroy(); // lsSession
+
+			LOG(KEditorServiceProviderLogFile, "CRotateProvider::InitializeMenuPaneL: AIW parameter list content analyzed");
+			TBool displayJpegRotatorMenu = EFalse;
+			TInt count = fileList->MdcaCount();
+			if( (KMultipleFileSupport && count > 0) || count == 1 )
+				{
+				LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::InitializeMenuPaneL: count %d ", count);
+				for (TInt index = 0; index < count; ++index)
+					{
+					// Check if file is DRM protected
+					displayJpegRotatorMenu = !CheckDRMProtectionL( fileList->MdcaPoint(index) );
+					if (displayJpegRotatorMenu)
+						{
+						// Check that it is JPEG
+						displayJpegRotatorMenu = IsJpeg( mimeTypeList[0] );
+						}
+					if (!displayJpegRotatorMenu)
+						{
+						break;
+						}
+					}
+				}
+			// Show the menu if all selected files were of supported type
+			if (displayJpegRotatorMenu)
+				{
+			    	aMenuPane.AddMenuItemsL (iResourceFile,	R_JPEG_ROTATOR_MENU,KAiwCmdRotate,aIndex);
+				}
+			}
+		CleanupStack::PopAndDestroy(2); // fileList, mimeTypeList
+		}
+
+	LOG(KEditorServiceProviderLogFile, "CRotateProvider::InitializeMenuPaneL: Out");
+	}
+
+//=============================================================================
+void CRotateProvider::HandleServiceCmdL (
+    const TInt &                    aCmdId,
+    const CAiwGenericParamList &    aInParamList,
+    CAiwGenericParamList &          aOutParamList,
+    TUint                           aCmdOptions,
+    const MAiwNotifyCallback *		aCallback
+    )
+{
+    LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::HandleServiceCmdL (%d)", aCmdId);
+    HandleCmdsL(aCmdId, aInParamList, aOutParamList, aCmdOptions, aCallback);
+}
+
+//=============================================================================
+void CRotateProvider::HandleMenuCmdL (
+    TInt                            aMenuCmdId,
+    const CAiwGenericParamList &	aInParamList,
+    CAiwGenericParamList &          aOutParamList,
+    TUint                           aCmdOptions,
+    const MAiwNotifyCallback *      aCallback
+    )
+{
+    LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::HandleMenuCmdL (%d)", aMenuCmdId);
+
+    HandleCmdsL(aMenuCmdId, aInParamList, aOutParamList, aCmdOptions, aCallback);
+}
+
+//=============================================================================
+void CRotateProvider::HandleCmdsL (
+    TInt                            aCmdId,
+    const CAiwGenericParamList &	aInParamList,
+    CAiwGenericParamList &          aOutParamList,
+    TUint                           /*aCmdOptions*/,
+    const MAiwNotifyCallback *      aCallback
+    )
+{
+	switch (aCmdId)
+			{
+	 	  case EEditorProviderCmdIdRotateLeft:
+			case EEditorProviderCmdIdRotateRight:
+				{
+				delete iInputFileList;
+				iInputFileList = NULL;
+				iInputFileList = CheckInputFilesLC( aInParamList );
+				CleanupStack::Pop(iInputFileList);
+				CheckAiwCallBackL( aOutParamList, aCallback );
+
+				// Check that there is enough disk space and launch the rotator
+				if( iInputFileList )
+					{
+             if( CheckDiskSpaceL(iSharableFS, iInputFileList) )
+                {
+                   LaunchJpegRotatorL( iInputFileList, aCmdId );
+                }
+                else
+                {
+                  LOG(KEditorServiceProviderLogFile, "CRotateProvider::HandleCmdsL: not enough disk space to start editing");
+                  delete iInputFileList;
+                  iInputFileList = NULL;
+                  User::Leave (KErrDiskFull);
+                }
+					}
+
+				break; 
+				}
+			case EEditorProviderCmdIdScale:
+				{
+				User::Leave(KErrNotSupported);
+				break;
+				}
+			case EEditorProviderCmdIdNoiseReduction:
+				{
+				User::Leave(KErrNotSupported);
+				break;
+				}
+			case EEditorProviderCmdIdAutoFix:
+				{
+				User::Leave(KErrNotSupported);
+				break;
+				}
+				default:
+				{
+					break;
+				}
+		}
+}
+
+//=============================================================================
+void CRotateProvider::CheckAiwCallBackL ( 
+    CAiwGenericParamList &          aOutParamList,
+    const MAiwNotifyCallback *      aCallback
+	)
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckAiwCallBackL: In");
+
+    if (aCallback)
+    {
+        LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckAiwCallBackL: Callback used");
+        iCallback = aCallback;
+		iOutParamList->Reset();
+		iOutParamList->AppendL(aOutParamList);
+		LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckAiwCallBackL: Using AIW call back");
+		iUseCallBack = ETrue;
+	}
+	else
+	{
+		iCallback = NULL;
+		iUseCallBack = EFalse;
+	}
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckAiwCallBackL: Out");
+}
+
+//=============================================================================
+CDesCArray* CRotateProvider::CheckInputFilesLC ( 
+    const CAiwGenericParamList &    aInParamList
+	)
+{
+	LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckInputFilesLC: in");
+
+	iInParamList->Reset();
+	iInParamList->AppendL(aInParamList);
+
+	// Create array for input files.
+	CDesCArray* inputFileList = new (ELeave) CDesCArraySeg(4);
+	CleanupStack::PushL( inputFileList );
+
+	// Count number of files in param list and store the file names.
+	// Assuming that the files were already checked in
+	// InitializeMenuPaneL; no need to check them here.
+	TInt count = aInParamList.Count();
+	TInt index = 0;
+	TInt fileCount = 0;
+	for (index = 0; index < count; ++index)
+	{
+		const TAiwGenericParam& param = aInParamList[index];
+		if (param.SemanticId() == EGenericParamFile)
+		{
+#ifndef AIW_MULTIPLE_FILE_SUPPORT		
+			if (fileCount)
+			{
+				inputFileList->Reset();
+				break;	
+			}
+#endif				
+		
+			// Get file name
+			TPtrC fileName = param.Value().AsDes();
+			inputFileList->AppendL( fileName );
+			fileCount++;
+			LOGFMT(KEditorServiceProviderLogFile, "\tfile: %S", &fileName);
+		}
+	}
+
+	// Check that the files exist
+	TBool filesExist = ETrue;
+	for( TInt i = 0; i < inputFileList->MdcaCount(); i++ )
+		{
+		filesExist = BaflUtils::FileExists( iSharableFS, inputFileList->MdcaPoint(i) );
+		if( !filesExist )
+		{
+			inputFileList->Reset();
+			LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckInputFilesLC: file list deleted");
+			break;
+		}
+	}
+
+	LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckInputFilesLC: out");
+	return inputFileList;
+}
+
+
+//=============================================================================
+void CRotateProvider::LaunchJpegRotatorL ( 
+	const CDesCArray*   aInputFileList,
+    TInt                aCmdId
+	)
+{
+    LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::LaunchJpegRotatorL: number of files: %d", aInputFileList->MdcaCount());
+    
+    ASSERT( EEditorProviderCmdIdRotateLeft == aCmdId || EEditorProviderCmdIdRotateRight == aCmdId);
+
+    // Notify that the rotating has been started
+	if (iCallback)
+	{
+	    LOG(KEditorServiceProviderLogFile, "CRotateProvider: Calling HandleNotifyL");
+	    ((MAiwNotifyCallback*)iCallback)->HandleNotifyL(KAiwCmdEdit, KAiwEventStarted, *iOutParamList, *iInParamList);
+	}
+
+	// Set the rotation mode
+	CJpegRotator::TRotationMode mode = CJpegRotator::ERotModeCounterClockwise;
+	if (EEditorProviderCmdIdRotateRight == aCmdId)
+	{
+		mode = CJpegRotator::ERotModeClockwise;
+	}
+
+	// Start the asyncronous rotate operation
+    delete iTargetFileList;
+    iTargetFileList = NULL;
+    iTargetFileList = new (ELeave) CDesCArraySeg(4);
+	delete iJpegRotatorHelper;
+	iJpegRotatorHelper = NULL;
+	iJpegRotatorHelper = new (ELeave) CJpegRotatorHelper( iSharableFS, *this );
+
+	// Start rotate, replacing original file(s)	
+	TRAPD( err, iJpegRotatorHelper->StartRotateL( aInputFileList, iTargetFileList, mode, EFalse ) ); // replace original files
+	if (KErrNone != err)
+	{
+		iJpegRotatorHelper->Cancel();
+	}
+
+#ifdef VERBOSE        
+    count = iSharableFS.ResourceCount();   
+    LOGFMT(KEditorServiceProviderLogFile, "Resource count: %d", count);
+#endif
+
+}
+
+//=============================================================================
+TBool CRotateProvider::CheckDRMProtectionL(const TDesC& DRM_FILE_ARG(aFileName)) const
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckDRMProtectionL: In");
+
+    TBool isDRMProtected = EFalse;
+
+#ifdef DRM_SUPPORT
+
+	DRMCommon* drm = DRMCommon::NewL();
+	CleanupStack::PushL (drm);
+	drm->IsProtectedFile( aFileName, isDRMProtected );
+	CleanupStack::PopAndDestroy (drm);
+
+#endif
+
+	LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::CheckDRMProtectionL: Out (result: %d)", isDRMProtected);
+
+    return isDRMProtected;
+}
+
+
+//=============================================================================
+TBool CRotateProvider::IsJpeg (const TDataType& aDataType) const
+{
+	_LIT(KMimeJpeg, "image/jpeg");
+
+	// CompareC return 0 if equal
+	return 0 == ( aDataType.Des().Left(10).CompareF( KMimeJpeg ) );
+}
+
+//=============================================================================
+TBool CRotateProvider::CheckDiskSpaceL(RFs& aFsSession, const TDesC& aFileName) const
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckDiskSpaceL");
+
+    TBool enoughFreeSpace = ETrue;
+
+    TFileName targetDrive = PathInfo::MemoryCardRootPath();
+
+    if (!ImageEditorUtils::ImageFitsToDriveL (aFsSession, aFileName, targetDrive))
+    {
+        targetDrive = PathInfo::PhoneMemoryRootPath();
+
+        if (!ImageEditorUtils::ImageFitsToDriveL (aFsSession, aFileName, targetDrive))
+        {
+            enoughFreeSpace = EFalse;
+        }
+    }
+
+    return enoughFreeSpace;
+}
+
+//=============================================================================
+TBool CRotateProvider::CheckDiskSpaceL(RFs& aFsSession, const CDesCArray* aFileList) const
+{
+    LOG(KEditorServiceProviderLogFile, "CRotateProvider::CheckDiskSpaceL");
+
+    // Check if the files fit onto the drive. Do this initial check assuming
+    // that each rotated file is saved to the same drive than the original file
+	return ImageEditorUtils::ImagesFitToDriveL (aFsSession, *aFileList, *aFileList);
+}
+
+//=============================================================================
+void CRotateProvider::RotateOperationReadyL( TInt JPEG_ROTATOR_AIW_PROVIDER_SUPPORT_ARG(aError) )
+{
+  LOGFMT(KEditorServiceProviderLogFile, "CRotateProvider::OperationReadyL: %d", aError);
+
+	if (iCallback)
+	{
+	    LOG(KEditorServiceProviderLogFile, "CRotateProvider: Calling MAiwNotifyCallback::HandleNotifyL");
+
+		iOutParamList->Reset();
+		if( KErrNone == aError )
+		{
+			// Pass the new file names to the AIW consumer.
+			// In error cases pass empty list.
+			for( TInt i = 0; i < iTargetFileList->MdcaCount(); i++ )
+			{
+				TAiwVariant variant( iTargetFileList->MdcaPoint(i) );
+				TAiwGenericParam param( EGenericParamFile, variant );
+				iOutParamList->AppendL( param );
+			}
+		    // Non-leaving function shall use TRAP
+    	    TRAP_IGNORE ( 
+    	        ((MAiwNotifyCallback*)iCallback)->HandleNotifyL(KAiwCmdRotate, KAiwEventCompleted, *iOutParamList, *iInParamList);    	    	    
+    	    );
+
+		}
+        else
+        {
+        
+            // Show error            
+            CErrorUI* errorUi = CErrorUI::NewLC(*CEikonEnv::Static());
+            TBool errorShown = errorUi->ShowGlobalErrorNoteL(aError);
+            if (errorShown == EFalse)
+            {
+                User::Leave(aError);
+            }
+        
+            CleanupStack::PopAndDestroy();
+        
+            TRAP_IGNORE (    
+                ((MAiwNotifyCallback*)iCallback)->HandleNotifyL(KAiwCmdRotate, KAiwEventError, *iOutParamList, *iInParamList);    
+            );
+        }
+        	
+        TRAP_IGNORE ( 	   
+	        ((MAiwNotifyCallback*)iCallback)->HandleNotifyL(KAiwCmdRotate, KAiwEventStopped, *iOutParamList, *iInParamList);    
+	    );
+	}
+	
+	delete iJpegRotatorHelper;
+	iJpegRotatorHelper = NULL;
+
+
+}
+
+
+
+// End of File