--- /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