--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videditor/SimpleVideoEditor/src/SimpleVideoEditorImpl.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1866 @@
+/*
+* 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 "SimpleVideoEditorImpl.h"
+#include <SimpleVideoEditor.rsg>
+#include <e32std.h>
+#include <aknutils.h>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+#include <mgfetch.h>
+#include <sysutil.h>
+#include <stringloader.h>
+#include <aknnotewrappers.h>
+#include <eikenv.h>
+#include <errorui.h>
+#include <PathInfo.h>
+#include <eikprogi.h>
+#include <stringloader.h>
+#include <VedAudioClipInfo.h>
+#include <CAknMemorySelectionDialog.h>
+#include <CAknFileNamePromptDialog.h>
+#include <AknCommonDialogsDynMem.h>
+#include <CAknMemorySelectionDialogMultiDrive.h>
+#include <apgcli.h>
+
+#include "VideoEditorUtils.h"
+#include "VeiAddQueue.h"
+#include "VideoEditorCommon.h"
+#include "VideoEditorDebugUtils.h"
+#include "VeiTempMaker.h"
+#include "ExtProgressDialog.h"
+#include "VeiMGFetchVerifier.h"
+#include "VeiImageClipGenerator.h"
+#include "DummyControl.h"
+#include "CMultiLineQueryDialog.h"
+
+// CONSTANTS
+_LIT(KResourceFile, "SimpleVideoEditor.rsc");
+const TProcessPriority KLowPriority = EPriorityLow;
+const TInt KAudioLevelMin = -127;
+const TUint KFadeInTimeMicroSeconds = 50000;
+
+#define KMediaGalleryUID3 0x101F8599
+
+//=======================================================================================================
+CSimpleVideoEditorImpl* CSimpleVideoEditorImpl::NewL(MSimpleVideoEditorExitObserver& aExitObserver)
+ {
+ CSimpleVideoEditorImpl* self = new (ELeave) CSimpleVideoEditorImpl(aExitObserver);
+ CleanupStack::PushL (self);
+ self->ConstructL();
+ CleanupStack::Pop (self);
+ return self;
+ }
+
+//=======================================================================================================
+CSimpleVideoEditorImpl::~CSimpleVideoEditorImpl()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::~CSimpleVideoEditorImpl, In");
+
+ // Remove foreground event observer
+ iEnv.RemoveForegroundObserver( *this );
+
+ Cancel();
+ iResLoader.Close();
+
+ if ( iMovie )
+ {
+ iMovie->Reset();
+ iMovie->UnregisterMovieObserver( this );
+ delete iMovie;
+ iMovie = NULL;
+ }
+
+ if ( iTempFile )
+ {
+ (void) iEnv.FsSession().Delete( *iTempFile );
+ delete iTempFile;
+ iTempFile = NULL;
+ }
+
+ if ( iProgressDialog )
+ {
+ iProgressDialog->SetCallback( NULL );
+ delete iProgressDialog;
+ iProgressDialog = NULL;
+ }
+
+ if ( iWaitDialog )
+ {
+ iWaitDialog->SetCallback(NULL);
+ delete iWaitDialog;
+ iWaitDialog = NULL;
+ }
+ if ( iAnimatedProgressDialog )
+ {
+ delete iAnimatedProgressDialog;
+ }
+
+ if (iImageClipGenerator)
+ {
+ delete iImageClipGenerator;
+ }
+
+ if (iTextGenerator)
+ {
+ delete iTextGenerator;
+ }
+
+ if (iAddText)
+ {
+ delete iAddText;
+ }
+
+ if ( iErrorUI )
+ {
+ delete iErrorUI;
+ }
+
+ if ( iAudioClipInfo )
+ {
+ delete iAudioClipInfo;
+ }
+
+ if ( iAcceptedAudioTypes )
+ {
+ delete iAcceptedAudioTypes;
+ iAcceptedAudioTypes = 0;
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::~CSimpleVideoEditorImpl, Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::RestoreOrientation()
+ {
+ CAknAppUiBase* appUi = static_cast<CAknAppUiBase *>( iEnv.EikAppUi() );
+ CAknAppUiBase::TAppUiOrientation orientation = appUi->Orientation();
+
+ if (orientation != iOriginalOrientation)
+ {
+ TRAP_IGNORE( appUi->SetOrientationL(iOriginalOrientation) );
+
+ // Send screen device change event to validate screen
+ TWsEvent event;
+
+ RWsSession& rws = iEnv.WsSession();
+ event.SetType( EEventScreenDeviceChanged );
+ event.SetTimeNow();
+ event.SetHandle( rws.WsHandle() );
+
+ (void)rws.SendEventToAllWindowGroups( event );
+ }
+ }
+
+//=======================================================================================================
+CSimpleVideoEditorImpl::CSimpleVideoEditorImpl(MSimpleVideoEditorExitObserver& aExitObserver)
+: CActive (EPriorityStandard),
+ iEnv( *CEikonEnv::Static() ),
+ iExitObserver (aExitObserver),
+ iResLoader( iEnv ),
+ iGeneratorComplete( ETrue ),
+ iDialogDismissed( EFalse )
+ {
+ CActiveScheduler::Add(this);
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::ConstructL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ConstructL: In");
+
+ // Locate and open the resource file
+ TFileName fileName;
+ TParse p;
+
+ Dll::FileName(fileName);
+ p.Set(KResourceFile, &KDC_RESOURCE_FILES_DIR, &fileName);
+ fileName = p.FullName();
+
+ LOGFMT(KVideoEditorLogFile, "\tLoading resource file: %S", &fileName);
+ iResLoader.OpenL( fileName ); // RConeResourceLoader selects the correct language file
+
+ // Always use automatic save quality for the result movie
+ iMovie = CVedMovie::NewL( NULL );
+ iMovie->RegisterMovieObserverL( this );
+ iMovie->SetQuality( CVedMovie::EQualityAutomatic );
+
+ CVeiTempMaker* maker = CVeiTempMaker::NewLC();
+ // this call can leave even though it does not end with 'L'
+ maker->EmptyTempFolder();
+ CleanupStack::PopAndDestroy(maker);
+ //delete maker;
+
+ iEnv.AddForegroundObserverL( *this );
+
+
+ iErrorUI = CErrorUI::NewL( iEnv );
+
+ iAcceptedAudioTypes = new ( ELeave ) CDesCArrayFlat( 4 );
+
+ iAcceptedAudioTypes->Reset();
+
+ iAcceptedAudioTypes->AppendL( _L( "audio/mpeg" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/aac" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/amr" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/mp3" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/x-mp3" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/3gpp" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/3gpp2" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/m4a" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/mp4" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/mpeg4" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/wav" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/x-wav" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/x-realaudio" ) );
+ iAcceptedAudioTypes->AppendL( _L( "audio/wma" ) );
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ConstructL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartMerge( const TDesC& aSourceFileName )
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMerge: In");
+
+ iSourceFileName = aSourceFileName;
+ iOperationMode = EOperationModeMerge;
+ iState = EStateInitializing;
+
+ CompleteRequest();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMerge: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartChangeAudio( const TDesC& aSourceFileName )
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartChangeAudio: In");
+
+ iSourceFileName = aSourceFileName;
+ iOperationMode = EOperationModeChangeAudio;
+ iState = EStateInitializing;
+
+ CompleteRequest();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartChangeAudio: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartAddText( const TDesC& aSourceFileName )
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartAddText: In");
+
+ iSourceFileName = aSourceFileName;
+ iOperationMode = EOperationModeAddText;
+ iState = EStateInitializing;
+
+ CompleteRequest();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartAddText: Out");
+ }
+
+
+//=============================================================================
+void CSimpleVideoEditorImpl::RunL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: In");
+
+ // Resetting these indicators. This is not necessary right now,
+ // but might be in the future if the code is changed so it's reasonable to
+ // to do it anyway, just in case.
+ iGeneratorComplete = ETrue;
+ iDialogDismissed = EFalse;
+
+ // if RunL() leaves, RunError() is called and iState is changed to EStateFinalizing
+ // (or to EStateReady if already in EStateFinalizing
+
+ switch (iState)
+ {
+ case EStateInitializing:
+ {
+ InitializeOperationL();
+
+ iState = EStateInsertInputFirst;
+ CompleteRequest();
+ break;
+ }
+ case EStateInsertInputFirst:
+ {
+ // Common to all operation modes: Insert the original video clip to the movie
+ // (Operation continues from the NotifyVideoClipAdded() callback method).
+ iMovie->InsertVideoClipL( iSourceFileName, 0 );
+ StartWaitDialogL();
+
+ break;
+ }
+ case EStateInsertInputSecond:
+ {
+ // Get the input - text, image, video or sound clip
+ switch (iOperationMode)
+ {
+ case EOperationModeMerge:
+ {
+ GetMergeInputFileL();
+ CompleteRequest();
+ break;
+ }
+
+ case EOperationModeChangeAudio:
+ {
+ GetAudioFileL();
+ CompleteRequest();
+ break;
+ }
+
+ case EOperationModeAddText:
+ {
+ GetTextL();
+ CompleteRequest();
+ break;
+ }
+
+ default:
+ User::Invariant();
+ break;
+ }
+ break;
+ }
+ case EStateCheckAudioLength:
+ {
+ // NotifyAudioClipInfoReady is called instead of RunL
+ break;
+ }
+ case EStateInsertVideo:
+ {
+ iMovie->InsertVideoClipL(iMergeFileName, iVideoOrImageIndex);
+ StartWaitDialogL();
+ break;
+ }
+ case EStateCreateImageGenerator:
+ {
+ TTimeIntervalMicroSeconds duration( 3000000 );
+ TRgb background = KRgbBlack;
+ // Setting to false to indicate that the
+ // NewL() called below hasn't yet completed.
+ iGeneratorComplete = EFalse;
+
+ // Create the image clip generator
+ iImageClipGenerator = CVeiImageClipGenerator::NewL(
+ iMergeFileName,
+ iMovie->Resolution(),
+ duration,
+ background,
+ KVideoClipGenetatorDisplayMode,
+ iEnv.FsSession(),
+ *this );
+ StartWaitDialogL();
+ break;
+ }
+ case EStateInsertImage:
+ {
+ TRAPD(err, iMovie->InsertVideoClipL( *iImageClipGenerator, ETrue, iVideoOrImageIndex )); // generator owned by movie
+ if (KErrNone == err)
+ {
+ // Generator is no longer our concern, ownership transferred to iMovie
+ iImageClipGenerator = 0;
+ StartWaitDialogL();
+ }
+ else
+ {
+ iError = err;
+ iError = FilterError();
+ iState = EStateFinalizing;
+ CompleteRequest();
+ }
+ break;
+ }
+
+ case EStateInsertAudio:
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: Inserting audio clip %S", &iAudioFileName);
+
+ iMovie->AddAudioClipL( iAudioFileName, TTimeIntervalMicroSeconds( 0 ));
+ StartWaitDialogL();
+ break;
+ }
+
+ case EStateInsertTextToBegin:
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 1");
+
+
+ iTextGenerator = CVeiTitleClipGenerator::NewL( iMovie->Resolution(),
+ EVeiTitleClipTransitionNone,
+ EVeiTitleClipHorizontalAlignmentCenter,
+ EVeiTitleClipVerticalAlignmentCenter);
+
+ HBufC* descriptiveName = StringLoader::LoadLC(R_VESM_EDIT_VIEW_TITLE_NAME, &iEnv );
+ iTextGenerator->SetDescriptiveNameL(*descriptiveName);
+ CleanupStack::PopAndDestroy(descriptiveName);
+ iTextGenerator->SetTextL(*iAddText);
+
+ iTextGenerator->SetTransitionAndAlignmentsL(EVeiTitleClipTransitionNone,
+ EVeiTitleClipHorizontalAlignmentCenter,
+ EVeiTitleClipVerticalAlignmentCenter);
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 2");
+ TRAPD(err, iMovie->InsertVideoClipL( *iTextGenerator, ETrue, 0));
+
+ if (KErrNone == err)
+ {
+ // Generator is no longer our concern, ownership transferred to iMovie
+ iTextGenerator = 0;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 3");
+ StartWaitDialogL();
+ }
+ else
+ {
+ iError = err;
+ iError = FilterError();
+ iState = EStateFinalizing;
+ CompleteRequest();
+ }
+ break;
+ }
+
+ case EStateInsertTextToEnd:
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 4");
+
+ iTextGenerator = CVeiTitleClipGenerator::NewL( iMovie->Resolution(),
+ EVeiTitleClipTransitionScrollBottomToTop,
+ EVeiTitleClipHorizontalAlignmentCenter,
+ EVeiTitleClipVerticalAlignmentCenter);
+
+ HBufC* descriptiveName = StringLoader::LoadLC(R_VESM_EDIT_VIEW_TITLE_NAME, &iEnv );
+ iTextGenerator->SetDescriptiveNameL(*descriptiveName);
+ CleanupStack::PopAndDestroy(descriptiveName);
+ iTextGenerator->SetTextL(*iAddText);
+
+ iTextGenerator->SetTransitionAndAlignmentsL(EVeiTitleClipTransitionScrollBottomToTop,
+ EVeiTitleClipHorizontalAlignmentCenter,
+ EVeiTitleClipVerticalAlignmentCenter);
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 5");
+
+ TRAPD(err, iMovie->InsertVideoClipL( *iTextGenerator, ETrue, 1));
+
+ if (KErrNone == err)
+ {
+ // Generator is no longer our concern, ownership transferred to iMovie
+ iTextGenerator = 0;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: 6");
+ StartWaitDialogL();
+ }
+ else
+ {
+ iError = err;
+ iError = FilterError();
+ iState = EStateFinalizing;
+ CompleteRequest();
+ }
+ break;
+ }
+
+ case EStateProcessing:
+ {
+ StartMovieProcessingL(iSourceFileName);
+ break;
+ }
+
+ case EStateProcessingOk:
+ {
+ ProcessingOkL();
+ CompleteRequest();
+ break;
+ }
+
+ case EStateProcessingFailed:
+ {
+ ProcessingFailed();
+ CompleteRequest();
+ break;
+ }
+
+ case EStateFinalizing:
+ {
+ // Show possible error dialog etc.
+ // in TRAP because endless call loop may otherwise be resulted in case of leave in HandleErrorL
+ // @ : should FilterError() be called only from here?
+ HandleError();
+ iState = EStateReady;
+ CompleteRequest();
+ break;
+ }
+
+ case EStateReady:
+ {
+ // Notify completion to observer
+ iExitObserver.HandleSimpleVideoEditorExit( iError, iOutputFileName );
+ break;
+ }
+
+ default:
+ {
+ User::Invariant();
+ break;
+ }
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunL: Out");
+ }
+
+//=============================================================================
+void CSimpleVideoEditorImpl::DoCancel()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DoCancel: In");
+ CancelMovieProcessing();
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DoCancel: Out");
+ }
+//=============================================================================
+
+void CSimpleVideoEditorImpl::CancelMovieProcessing()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::CancelMovieProcessing: In");
+
+ if (iMovie)
+ {
+ iMovie->CancelProcessing();
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::CancelMovieProcessing: Out");
+ }
+//=============================================================================
+
+TInt CSimpleVideoEditorImpl::RunError( TInt aError )
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::RunError: %d", aError);
+ //@ : think how to solve this
+
+ // Show possible error dialog etc.
+ iError = aError;
+ // @: if leave and error happens so that Notify callbacks are not called
+ iError = FilterError();
+
+ // if leave happens in HandleError, iState must be changed to prevent same leave happening eternally
+ if (EStateReady == iState)
+ {
+ iExitObserver.HandleSimpleVideoEditorExit( iError, iOutputFileName );
+ }
+ else
+ {
+ iState = EStateReady;
+ HandleError();
+ iExitObserver.HandleSimpleVideoEditorExit( iError, iOutputFileName );
+ // If CompleteRequest() is called here, system crashes because ~CSimpleVideoEditorImpl() gets
+ // called from iExitObserver.HandleSimpleVideoEditorExitL(), stray signal resulted
+ //CompleteRequest();
+ }
+
+ return KErrNone;
+ }
+//=======================================================================================================
+
+void CSimpleVideoEditorImpl::InitializeOperationL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::InitializeOperationL: In");
+
+ iOutputFileName.Zero();
+
+ if( !AknLayoutUtils::PenEnabled() && EOperationModeAddText == iOperationMode )
+ {
+ // Text input is always inserted in portrait mode.
+ // Store the original screen orientation.
+ CAknAppUiBase* appUi = static_cast<CAknAppUiBase *>( iEnv.EikAppUi() );
+ iOriginalOrientation = appUi->Orientation();
+ appUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationPortrait);
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::InitializeOperationL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::GetMergeInputFileL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: In");
+
+ iVideoOrImageIndex = 0;
+
+ CDesCArrayFlat* selectedFiles = new ( ELeave ) CDesCArrayFlat( 1 );
+ CleanupStack::PushL(selectedFiles);
+
+ CDesCArrayFlat* mimetypesVideo = new ( ELeave ) CDesCArrayFlat( 1 );
+ CleanupStack::PushL(mimetypesVideo);
+ mimetypesVideo->AppendL(_L("video/*"));
+
+ CDesCArrayFlat* mimetypesImage = new ( ELeave ) CDesCArrayFlat( 1 );
+ CleanupStack::PushL(mimetypesImage);
+ mimetypesImage->AppendL(_L("image/*"));
+
+ TInt videoOrImage = -1;
+ TBool chosen = EFalse;
+
+ // Select the input type: video clip or image
+ if ( ShowListQueryL(videoOrImage, R_VEI_QUERY_HEADING_MERGE_WITH, R_VED_VIDEO_OR_IMAGE_QUERY) )
+ {
+ CVeiMGFetchVerifier* mgFetchVerifier = CVeiMGFetchVerifier::NewLC();
+ if (0 == videoOrImage) // video chosen
+ {
+ if ( MGFetch::RunL( *selectedFiles, EVideoFile, EFalse, KNullDesC(), KNullDesC(), mimetypesVideo, mgFetchVerifier))
+ {
+ chosen = ETrue;
+ }
+ }
+ else if (1 == videoOrImage) // image chosen
+ {
+ if ( MGFetch::RunL( *selectedFiles, EImageFile, EFalse, KNullDesC(), KNullDesC(), mimetypesImage, mgFetchVerifier))
+ {
+ chosen = ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy( mgFetchVerifier );
+
+ if (chosen)
+ {
+ iMergeFileName = selectedFiles->MdcaPoint(0);
+ TInt headingResourceId = R_VIE_QUERY_HEADING_ADD_VIDEO_TO;
+ if (0 == videoOrImage) // video chosen
+ {
+ iOperationMode = EOperationModeMergeWithVideo;
+ iState = EStateInsertVideo;
+ headingResourceId = R_VIE_QUERY_HEADING_ADD_VIDEO_TO;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: 4");
+ }
+ else if (1 == videoOrImage) // image chosen
+ {
+ iOperationMode = EOperationModeMergeWithImage;
+ iState = EStateCreateImageGenerator;
+ headingResourceId = R_VIE_QUERY_HEADING_ADD_IMAGE_TO;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: 5");
+ }
+
+ TInt begOrEnd = -1;
+ if ( ShowListQueryL(begOrEnd, headingResourceId, R_VED_INSERT_POSITION_QUERY) )
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: 6");
+
+ if (0 == begOrEnd) // video or image to the beginning
+ {
+ iVideoOrImageIndex = 0;
+ }
+ else // video or image to end
+ {
+ iVideoOrImageIndex = 1;
+ }
+ }
+ else
+ {
+ iState = EStateFinalizing;
+ }
+ } // if (chosen)
+ else
+ {
+ iState = EStateFinalizing;
+ }
+ } // if ( ShowListQueryL for image or video
+ else
+ {
+ iState = EStateFinalizing;
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: 7");
+ CleanupStack::PopAndDestroy(mimetypesImage);
+ CleanupStack::PopAndDestroy(mimetypesVideo);
+ CleanupStack::PopAndDestroy(selectedFiles);
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetMergeInputFileL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::GetAudioFileL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetAudioFileL: In");
+
+ TFileName outputFile;
+
+ CDesCArrayFlat* selectedFiles = new ( ELeave ) CDesCArrayFlat( 1 );
+ CleanupStack::PushL(selectedFiles);
+ CVeiMGFetchVerifier* mgFetchVerifier = CVeiMGFetchVerifier::NewLC();
+
+ if ( MGFetch::RunL( *selectedFiles, EAudioFile, EFalse, KNullDesC, KNullDesC , iAcceptedAudioTypes, mgFetchVerifier ) )
+ {
+ iAudioFileName = selectedFiles->MdcaPoint(0);
+ iAudioClipInfo = CVedAudioClipInfo::NewL( iAudioFileName, *this );
+ iState = EStateCheckAudioLength;
+ }
+ else
+ {
+ iState = EStateFinalizing;
+ }
+
+ CleanupStack::PopAndDestroy( mgFetchVerifier );
+ CleanupStack::PopAndDestroy(selectedFiles);
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetAudioFileL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::GetTextL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetTextL: In");
+
+ // Ask for text.
+ iAddText = HBufC::NewL(AKNTEXT_QUERY_WIDTH * AKNTEXT_QUERY_LINES); // think what these limit values should be?
+ TPtr textPtr = iAddText->Des();
+ CMultiLineQueryDialog* textQuery = CMultiLineQueryDialog::NewL(textPtr);
+ textQuery->SetMaxLength(AKNTEXT_QUERY_WIDTH * AKNTEXT_QUERY_LINES);
+ //textQuery->SetPredictiveTextInputPermitted(ETrue);
+
+ if (textQuery->ExecuteLD(R_VESM_EDITVIDEO_TITLESCREEN_TEXT_QUERY))
+ {
+ // Restore the original screen orientation immediately after the text input ends
+ RestoreOrientation();
+
+ TInt begOrEnd = -1;
+
+ if ( ShowListQueryL(begOrEnd, R_VEI_QUERY_HEADING_ADD_TEXT_TO, R_VED_INSERT_POSITION_QUERY) )
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetTextL: 1");
+
+ if (0 == begOrEnd) // text to begin
+ {
+ iState = EStateInsertTextToBegin;
+ }
+ else // text to end in credits style (rolling down the screen)
+ {
+ iState = EStateInsertTextToEnd;
+ }
+ }
+ else
+ {
+ iState = EStateFinalizing;
+ }
+ }
+ else
+ {
+ // Restore the original screen orientation immediately after the text input ends
+ RestoreOrientation();
+ iState = EStateFinalizing;
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::GetTextL: Out");
+ }
+
+//=======================================================================================================
+TInt CSimpleVideoEditorImpl::ShowListQueryL (TInt& aPosition,
+ TInt aHeadingResourceId,
+ TInt aQueryResourceId) const
+ {
+ CAknListQueryDialog* dlg = new( ELeave ) CAknListQueryDialog( &aPosition );
+ dlg->PrepareLC( aQueryResourceId );
+
+ CAknPopupHeadingPane* heading = dlg->QueryHeading();
+ HBufC* noteText = StringLoader::LoadLC( aHeadingResourceId, &iEnv );
+ heading->SetTextL( noteText->Des() );
+ CleanupStack::PopAndDestroy( noteText );
+
+ return dlg->RunLD();
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartMovieProcessingL(const TDesC& aSourceFile)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMovieProcessingL: In");
+
+ RFs& fs = iEnv.FsSession();
+
+ if (QueryAndSaveL(aSourceFile))
+ {
+ // Generate temp file.
+ // Take the drive from the target file name.
+ CAknMemorySelectionDialog::TMemory memory( CAknMemorySelectionDialog::EMemoryCard );
+ if( 0 != iOutputFileName.Left(1).CompareF( PathInfo::MemoryCardRootPath().Left(1) ) )
+ {
+ memory = CAknMemorySelectionDialog::EPhoneMemory;
+ }
+
+ iTempFile = HBufC::NewL(KMaxFileName);
+ CVeiTempMaker* maker = CVeiTempMaker::NewL();
+ maker->GenerateTempFileName( *iTempFile, memory, iMovie->Format() );
+ delete maker;
+
+ // Start rendering video to the temporary file.
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMovieProcessingL: 1, calling iMovie->ProcessL(%S)", iTempFile);
+ iMovie->ProcessL(*iTempFile, *this);
+ }
+ else
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMovieProcessingL: User cancelled saving");
+ iState = EStateProcessingFailed;
+ CompleteRequest();
+ }
+
+ // Next: wait for MVedMovieProcessingObserver callback
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartMovieProcessingL: Out");
+ }
+
+//=============================================================================
+TInt CSimpleVideoEditorImpl::QueryAndSaveL(const TDesC& aSourceFileName)
+{
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::QueryAndSaveL: in");
+
+ TBool ret = EFalse;
+
+ RFs fs = CCoeEnv::Static()->FsSession();
+
+ // launch query with choices "Replace original" and "Save with a new file name"
+ TInt userSelection = LaunchSaveVideoQueryL();
+
+ if(userSelection == 0)
+ // the user selects to save with a new file name
+ {
+ CAknMemorySelectionDialog::TMemory selectedMemory(CAknMemorySelectionDialog::EPhoneMemory);
+
+ // Multiple drive support
+#ifdef RD_MULTIPLE_DRIVE
+
+ TDriveNumber driveNumber;
+ TFileName driveAndPath;
+ CAknMemorySelectionDialogMultiDrive* multiDriveDlg = CAknMemorySelectionDialogMultiDrive::NewL(ECFDDialogTypeSave, EFalse );
+ CleanupStack::PushL(multiDriveDlg);
+
+ // launch "Select memory" query
+ if (multiDriveDlg->ExecuteL( driveNumber, &driveAndPath, NULL ))
+ {
+ iOutputFileName.Zero();
+
+ // Generate a default name for the new file
+ TInt err = VideoEditorUtils::GenerateFileNameL (
+ fs,
+ aSourceFileName,
+ iOutputFileName,
+ iMovie->Format(),
+ iMovie->GetSizeEstimateL(),
+ driveAndPath);
+
+ driveAndPath.Append( PathInfo::VideosPath() );
+
+ if ( KErrNone == err )
+ {
+ // launch file name prompt dialog
+ if (CAknFileNamePromptDialog::RunDlgLD(iOutputFileName, driveAndPath, KNullDesC))
+ {
+ driveAndPath.Append(iOutputFileName);
+ iOutputFileName = driveAndPath;
+ ret = ETrue;
+ }
+ }
+ else // err != KErrNone
+ {
+ iErrorUI->ShowGlobalErrorNoteL( err );
+ ret = EFalse;
+ }
+ }
+ CleanupStack::PopAndDestroy( multiDriveDlg );
+
+#else // no multiple drive support
+
+ // launch "Select memory" query
+ if (CAknMemorySelectionDialog::RunDlgLD(selectedMemory))
+ {
+ // create path for the image
+ TFileName driveAndPath;
+ VideoEditor::TMemory memorySelection = VideoEditor::EMemPhoneMemory;
+ if (selectedMemory == CAknMemorySelectionDialog::EPhoneMemory)
+ {
+ memorySelection = VideoEditor::EMemPhoneMemory;
+ driveAndPath.Copy( PathInfo::PhoneMemoryRootPath() );
+ driveAndPath.Append( PathInfo::VideosPath() );
+ }
+ else if (selectedMemory == CAknMemorySelectionDialog::EMemoryCard)
+ {
+ memorySelection = VideoEditor::EMemMemoryCard;
+ driveAndPath.Copy( PathInfo::MemoryCardRootPath() );
+ driveAndPath.Append( PathInfo::VideosPath() );
+ }
+
+
+ // GenerateNewDocumentNameL also checks disk space
+ iOutputFileName.Zero();
+ TInt err = VideoEditorUtils::GenerateNewDocumentNameL (
+ fs,
+ aSourceFileName,
+ iOutputFileName,
+ iMovie->Format(),
+ iMovie->GetSizeEstimateL(),
+ memorySelection);
+
+ if ( KErrNone == err )
+ {
+ // launch file name prompt dialog
+ if (CAknFileNamePromptDialog::RunDlgLD(iOutputFileName, driveAndPath, KNullDesC))
+ {
+ driveAndPath.Append(iOutputFileName);
+ iOutputFileName = driveAndPath;
+ ret = ETrue;
+ }
+ }
+ else // err != KErrNone
+ {
+ ret = EFalse;
+ }
+ }
+#endif
+ }
+ // user selects to overwrite
+ else if (userSelection == 1)
+
+ {
+ iOutputFileName = aSourceFileName;
+ return ETrue;
+ }
+ else // user cancelled
+ {
+ ret = EFalse;
+ }
+
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::QueryAndSaveL: out: %d", ret);
+
+ return ret;
+}
+
+
+
+//=============================================================================
+TInt CSimpleVideoEditorImpl::LaunchListQueryDialogL (
+ MDesCArray * aTextItems,
+ const TDesC & aPrompt
+ )
+{
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::LaunchListQueryDialogL: in");
+ // Selected text item index
+ TInt index (-1);
+
+ // Create a new list dialog
+ CAknListQueryDialog * dlg = new (ELeave) CAknListQueryDialog (&index);
+
+ // Prepare list query dialog
+ dlg->PrepareLC (R_VIE_LIST_QUERY);
+
+ // Set heading
+ dlg->QueryHeading()->SetTextL (aPrompt);
+
+ // Set text item array
+ dlg->SetItemTextArray (aTextItems);
+
+ // Set item ownership
+ dlg->SetOwnershipType (ELbmDoesNotOwnItemArray);
+
+ // Execute
+ if (dlg->RunLD())
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::LaunchListQueryDialogL: out: return %d", index);
+ return index;
+ }
+ else
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::LaunchListQueryDialogL: out: return -1");
+ return -1;
+ }
+}
+
+//=============================================================================
+TInt CSimpleVideoEditorImpl::LaunchSaveVideoQueryL ()
+{
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::LaunchSaveVideoQueryL: in");
+ // Create dialog heading and options
+ HBufC * heading = CEikonEnv::Static()->AllocReadResourceLC (R_VIE_QUERY_HEADING_SAVE);
+ HBufC * option1 = CEikonEnv::Static()->AllocReadResourceLC (R_VIE_QUERY_SAVE_NEW);
+ HBufC * option2 = CEikonEnv::Static()->AllocReadResourceLC (R_VIE_QUERY_SAVE_REPLACE);
+
+ // Query dialog texts
+ CDesCArray * options = new (ELeave) CDesCArraySeg (2);
+ CleanupStack::PushL (options);
+ options->AppendL( option1->Des() );
+ options->AppendL( option2->Des() );
+
+ // Execute query dialog
+ TInt ret = LaunchListQueryDialogL (options, *heading);
+
+ options->Reset();
+
+ CleanupStack::PopAndDestroy( options );
+ CleanupStack::PopAndDestroy( option2 );
+ CleanupStack::PopAndDestroy( option1 );
+ CleanupStack::PopAndDestroy( heading );
+
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::LaunchListQueryDialogL: out: return %d", ret);
+ return ret;
+}
+
+
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::HandleLosingForeground()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleLosingForeground(): In");
+
+ // Set the priority to low. This is needed to handle the situations
+ // where the engine is performing heavy processing while the application
+ // is in background.
+ RProcess myProcess;
+ iOriginalProcessPriority = myProcess.Priority();
+ LOGFMT3(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleLosingForeground: changing priority of process %Ld from %d to %d", myProcess.Id().Id(), iOriginalProcessPriority, KLowPriority);
+ myProcess.SetPriority( KLowPriority );
+ iProcessPriorityAltered = ETrue;
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleLosingForeground(): Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::HandleGainingForeground()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleGainingForeground(): In");
+
+ // Return to normal priority.
+ RProcess myProcess;
+ TProcessPriority priority = myProcess.Priority();
+ if ( priority < iOriginalProcessPriority )
+ {
+ myProcess.SetPriority( iOriginalProcessPriority );
+ }
+ iProcessPriorityAltered = EFalse;
+
+ LOGFMT2(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleGainingForeground: Out: process %Ld back to normal priority %d", myProcess.Id().Id(), priority);
+ }
+
+//=======================================================================================================
+TInt CSimpleVideoEditorImpl::FilterError(/*const TInt& aErrEngine, const TInt& aErrUi*/) const
+ {
+ // here standard leave codes are converted to our own codes having correspondent localized error messages
+ if (KErrNone != iError && KErrCancel != iError)
+ {
+ if (EStateInsertInputFirst == iState )
+ {
+ return KErrUnableToEditVideo;
+ }
+ else if (EStateInsertVideo == iState)
+ {
+ if (KErrNotSupported == iError)
+ {
+ return KErrVideoFormatNotSupported;
+ }
+ else return KErrUnableToInsertVideo;
+ }
+ else if (EStateInsertImage == iState || EStateCreateImageGenerator == iState)
+ {
+ if (KErrNotSupported == iError)
+ {
+ return KErrImageFormatNotSupported;
+ }
+ else return KErrUnableToInsertImage;
+ }
+ else if (EStateInsertAudio == iState || EStateCheckAudioLength == iState )
+ {
+ if (KErrNotSupported == iError)
+ {
+ return KErrAudioFormatNotSupported;
+ }
+ else
+ {
+ return KErrUnableToInsertSound;
+ }
+ }
+ else if (EStateInsertTextToBegin == iState || EStateInsertTextToEnd == iState)
+ {
+ return KErrUnableToInsertText;
+ }
+ else if (EOperationModeMergeWithVideo == iOperationMode)
+ {
+ return KErrUnableToMergeVideos;
+ }
+ else if (EOperationModeMergeWithImage == iOperationMode)
+ {
+ return KErrUnableToMergeVideoAndImage;
+ }
+ else if (EOperationModeChangeAudio == iOperationMode)
+ {
+ return KErrUnableToChangeSound;
+ }
+ else if (EOperationModeAddText == iOperationMode)
+ {
+ if (iError == KErrNoMemory) return KErrNoMemory;
+ return KErrUnableToInsertText;
+ }
+ }
+
+ return iError;
+ }
+
+
+//=============================================================================
+void CSimpleVideoEditorImpl::CompleteRequest()
+ {
+ if ( IsActive() )
+ {
+ Cancel();
+ }
+ TRequestStatus * p = &iStatus;
+ SetActive();
+ User::RequestComplete (p, KErrNone);
+ }
+
+//=============================================================================
+void CSimpleVideoEditorImpl::HandleError()
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleErrorL: In, iError:%d", iError);
+
+ if (KErrNone != iError && KErrCancel != iError)
+ {
+
+ if (iTempFile)
+ {
+ TInt delErr = iEnv.FsSession().Delete( *iTempFile );
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleErrorL: 1, delErr:%d", delErr);
+ delete iTempFile;
+ iTempFile = NULL;
+ }
+
+ switch (iError)
+ {
+ case KErrInUse:
+ {
+ ShowErrorNote(R_VEI_IN_USE);
+ break;
+ }
+ case KErrUnableToEditVideo:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_EDIT);
+ break;
+ }
+ case KErrUnableToInsertVideo:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_INSERT_VIDEO);
+ break;
+ }
+ case KErrUnableToInsertSound:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_INSERT_SOUND);
+ break;
+ }
+ case KErrUnableToInsertImage:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_INSERT_IMAGE);
+ break;
+ }
+ case KErrUnableToInsertText:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_INSERT_TEXT);
+ break;
+ }
+ case KErrUnableToMergeVideos:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_MERGE_VIDEOS);
+ break;
+ }
+ case KErrUnableToMergeVideoAndImage:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_MERGE_VIDEO_IMAGE);
+ break;
+ }
+ case KErrUnableToChangeSound:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_CHANGE_SOUND);
+ break;
+ }
+ case KErrVideoFormatNotSupported:
+ {
+ ShowErrorNote(R_VEI_UNABLE_TO_INSERT_VIDEO);
+ break;
+ }
+ case KErrAudioFormatNotSupported:
+ {
+ ShowErrorNote(R_VEI_AUDIO_FORMAT_NOT_SUPPORTED);
+ break;
+ }
+ case KErrImageFormatNotSupported:
+ {
+ ShowErrorNote(R_VEI_IMAGE_FORMAT_NOT_SUPPORTED);
+ break;
+ }
+ case KErrNoMemory:
+ {
+ ShowErrorNote(R_VEI_NOT_ENOUGH_MEMORY);
+ break;
+ }
+ default:
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleErrorL: 4");
+ ShowErrorNote(R_VEI_ERROR_NOTE);
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleErrorL: 5");
+ break;
+ }
+ }
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::HandleErrorL: Out");
+ }
+
+//=============================================================================
+void CSimpleVideoEditorImpl::ShowErrorNote( const TInt aResourceId ) const
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ShowErrorNoteL: In");
+
+ TRAP_IGNORE(
+ HBufC* stringholder = StringLoader::LoadLC( aResourceId, &iEnv );
+ CAknErrorNote* dlg = new ( ELeave ) CAknErrorNote( ETrue );
+ dlg->ExecuteLD( *stringholder );
+ CleanupStack::PopAndDestroy( stringholder );
+ );
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ShowErrorNoteL: out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartWaitDialogL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartWaitDialogL: In");
+ if (iWaitDialog)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartWaitDialogL: 2");
+ delete iWaitDialog;
+ iWaitDialog = NULL;
+ }
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartWaitDialogL: 3");
+
+ iWaitDialog = new ( ELeave ) CAknWaitDialog(
+ reinterpret_cast<CEikDialog**>(&iWaitDialog), ETrue ); // !!!
+ iWaitDialog->PrepareLC(R_VEI_WAIT_NOTE_WITH_CANCEL);
+ iWaitDialog->SetCallback( this );
+
+ HBufC* stringholder = StringLoader::LoadLC( R_VEI_NOTE_PROCESSING, &iEnv );
+ iWaitDialog->SetTextL( *stringholder );
+ CleanupStack::PopAndDestroy(stringholder);
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartWaitDialogL: 4");
+ iWaitDialog->RunLD();
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartWaitDialogL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartProgressDialogL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartProgressDialogL: In");
+
+ if (iProgressDialog)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartProgressDialogL: 1");
+ delete iProgressDialog;
+ iProgressDialog = NULL;
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartProgressDialogL: 2");
+
+ iProgressDialog = new (ELeave) CAknProgressDialog(
+ reinterpret_cast<CEikDialog**>(&iProgressDialog), ETrue );
+ iProgressDialog->PrepareLC(R_VESM_PROGRESS_NOTE_WITH_CANCEL);
+ iProgressDialog->SetCallback( this );
+
+ TInt resId = -1;
+ HBufC* stringholder = NULL;
+ switch (iOperationMode)
+ {
+ case EOperationModeMergeWithVideo:
+ case EOperationModeMergeWithImage:
+ TApaAppCaption caption;
+ TRAPD( err, ResolveCaptionNameL( caption ) );
+
+ // If something goes wrong, show basic "Saving" note
+ if ( err )
+ {
+ stringholder = iEnv.AllocReadResourceLC( R_VEI_NOTE_PROCESSING );
+ }
+ else
+ {
+ stringholder = StringLoader::LoadLC( R_VEI_NOTE_MERGING, caption, &iEnv );
+ }
+ break;
+ case EOperationModeChangeAudio:
+ resId = R_VEI_NOTE_ADDING_AUDIO;
+ stringholder = StringLoader::LoadLC( resId, &iEnv );
+ break;
+ case EOperationModeAddText:
+ resId = R_VEI_NOTE_ADDING_TEXT;
+ stringholder = StringLoader::LoadLC( resId, &iEnv );
+ break;
+ default :
+ resId = R_VEI_NOTE_PROCESSING;
+ stringholder = StringLoader::LoadLC( resId, &iEnv );
+ break;
+ }
+
+ iProgressDialog->SetTextL( *stringholder );
+ CleanupStack::PopAndDestroy(stringholder);
+
+ iProgressDialog->GetProgressInfoL()->SetFinalValue( 100 );
+ iProgressDialog->RunLD();
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::StartProgressDialogL: Out");
+ }
+
+//=============================================================================
+void CSimpleVideoEditorImpl::ResolveCaptionNameL( TApaAppCaption& aCaption ) const
+ {
+ RApaLsSession appArcSession;
+ CleanupClosePushL( appArcSession );
+ User::LeaveIfError( appArcSession.Connect() );
+
+ // Get Media Gallery caption
+ TApaAppInfo appInfo;
+ User::LeaveIfError( appArcSession.GetAppInfo( appInfo, TUid::Uid( KMediaGalleryUID3 ) ) );
+
+ aCaption = appInfo.iCaption;
+
+ CleanupStack::PopAndDestroy( &appArcSession );
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::StartAnimatedProgressDialogL ()
+ {
+ delete iAnimatedProgressDialog;
+ iAnimatedProgressDialog = NULL;
+ iAnimatedProgressDialog = new (ELeave) CExtProgressDialog( &iAnimatedProgressDialog );
+
+ iAnimatedProgressDialog->PrepareLC(R_WAIT_DIALOG);
+ iAnimatedProgressDialog->SetCallback( this );
+
+ TInt labelResId = -1;
+ TInt animResId = -1;
+ switch (iOperationMode)
+ {
+ case EOperationModeMerge:
+ labelResId = R_VEI_NOTE_MERGING;
+ animResId = VideoEditor::EAnimationMerging;
+ break;
+ case EOperationModeChangeAudio:
+ labelResId = R_VEI_NOTE_ADDING_AUDIO;
+ animResId = VideoEditor::EAnimationChangeAudio;
+ break;
+ case EOperationModeAddText:
+ labelResId = R_VEI_NOTE_ADDING_TEXT;
+ animResId = VideoEditor::EAnimationAddText;
+ break;
+ default :
+ labelResId = R_VEI_NOTE_PROCESSING;
+ // @ : what is best default animation?
+ animResId = VideoEditor::EAnimationMerging;
+ break;
+ }
+
+ HBufC* stringholder = StringLoader::LoadLC( labelResId, &iEnv );
+ iAnimatedProgressDialog->SetTextL( *stringholder );
+ CleanupStack::PopAndDestroy(stringholder);
+
+ iAnimatedProgressDialog->SetAnimationResourceIdL( animResId );
+
+ iAnimatedProgressDialog->GetProgressInfoL()->SetFinalValue( 100 );
+ iAnimatedProgressDialog->StartAnimationL();
+ iAnimatedProgressDialog->RunLD();
+ }
+
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyMovieProcessingStartedL(CVedMovie& /*aMovie*/)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingStartedL: In");
+
+ iPercentagesProcessed = 0;
+
+ StartProgressDialogL();
+ //StartAnimatedProgressDialogL();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingStartedL: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyMovieProcessingProgressed(CVedMovie& /*aMovie*/, TInt aPercentage)
+ {
+ iPercentagesProcessed = aPercentage;
+ User::ResetInactivityTime();
+ if (iAnimatedProgressDialog)
+ {
+ TRAP_IGNORE( iAnimatedProgressDialog->GetProgressInfoL()->SetAndDraw( aPercentage ) );
+ }
+
+ if (iProgressDialog)
+ {
+ TRAP_IGNORE( iProgressDialog->GetProgressInfoL()->SetAndDraw( aPercentage ) );
+ }
+
+ if ( iCancelPercentage <= aPercentage )
+ {
+ iCancelPercentage = 101;
+ }
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted(CVedMovie& /*aMovie*/, TInt aError)
+ {
+ LOGFMT2(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: In, aError:%d, iPercentagesProcessed:%d", aError, iPercentagesProcessed);
+
+ iError = aError;
+ iError = FilterError();
+
+ if (KErrNone == aError)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: 1");
+ iState = EStateProcessingOk;
+ }
+ else
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: 2");
+ iState = EStateProcessingFailed;
+ }
+
+ if (iAnimatedProgressDialog)
+ {
+ TRAP_IGNORE( iAnimatedProgressDialog->GetProgressInfoL()->SetAndDraw( 100 ) );
+ delete iAnimatedProgressDialog;
+ iAnimatedProgressDialog = NULL;
+ }
+ if (iProgressDialog)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: 3");
+ TRAP_IGNORE( iProgressDialog->GetProgressInfoL()->SetAndDraw( 100 ) );
+ TRAP_IGNORE( iProgressDialog->ProcessFinishedL() );
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: 4");
+ }
+
+ // CompleteRequest() moved to DialogDismissed()
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyMovieProcessingCompleted: Out");
+ }
+
+
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyAudioClipInfoReady( CVedAudioClipInfo& aInfo, TInt aError )
+ {
+
+ LOGFMT( KVideoEditorLogFile, "CVeiEditVideoView::NotifyAudioClipInfoReady: in, aError:%d", aError );
+
+ if ( aError == KErrNone )
+ {
+ LOG( KVideoEditorLogFile, "CVeiEditVideoView::NotifyAudioClipInfoReady: 1" );
+
+ TTimeIntervalMicroSeconds audioDuration = aInfo.Duration();
+ TTimeIntervalMicroSeconds videoDuration = iMovie->Duration();
+ TInt changeSound = 1;
+
+ TRAP_IGNORE( changeSound = QueryAudioInsertionL( videoDuration, audioDuration ));
+
+ if ( changeSound )
+ {
+ iState = EStateInsertAudio;
+ }
+ else
+ {
+ iState = EStateFinalizing;
+ }
+ CompleteRequest();
+
+ LOG( KVideoEditorLogFile, "CVeiEditVideoView::NotifyAudioClipInfoReady: 2" );
+ }
+ else
+ {
+ iError = aError;
+ iError = FilterError();
+ iState = EStateFinalizing;
+ CompleteRequest();
+ }
+
+ LOG( KVideoEditorLogFile, "CVeiEditVideoView::NotifyAudioClipInfoReady: out" );
+ }
+
+
+//=======================================================================================================
+TInt CSimpleVideoEditorImpl::QueryAudioInsertionL( TTimeIntervalMicroSeconds aVideoDuration,
+ TTimeIntervalMicroSeconds aAudioDuration )
+ {
+ TInt changeSound = 1;
+
+ // round the durations to seconds so that the comparing will be more realistic
+ TTimeIntervalSeconds videoDurationInSeconds = aVideoDuration.Int64()/1000000;
+ TTimeIntervalSeconds audioDurationInSeconds = aAudioDuration.Int64()/1000000;
+
+ if ( audioDurationInSeconds < videoDurationInSeconds )
+ {
+ HBufC* queryString = StringLoader::LoadLC( R_VIE_QUERY_INSERT_SHORT_AUDIO );
+ CAknQueryDialog* dlg = new( ELeave )CAknQueryDialog( *queryString, CAknQueryDialog::ENoTone );
+ changeSound = dlg->ExecuteLD( R_VIE_CONFIRMATION_QUERY );
+ CleanupStack::PopAndDestroy( queryString );
+ }
+ else if ( audioDurationInSeconds > videoDurationInSeconds )
+ {
+ HBufC* queryString = StringLoader::LoadLC( R_VIE_QUERY_INSERT_LONG_AUDIO );
+ CAknQueryDialog* dlg = new( ELeave )CAknQueryDialog( *queryString, CAknQueryDialog::ENoTone );
+ changeSound = dlg->ExecuteLD( R_VIE_CONFIRMATION_QUERY );
+ CleanupStack::PopAndDestroy( queryString );
+ }
+ //else the audio clip is the same length as the video clip
+
+ return changeSound;
+ }
+
+
+
+//=======================================================================================================
+
+void CSimpleVideoEditorImpl::ProcessingOkL()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingOkL: In");
+ RFs& fs = iEnv.FsSession();
+ CFileMan* fileman = CFileMan::NewL( fs );
+ CleanupStack::PushL( fileman );
+
+ TInt moveErr( KErrNone );
+ if ( iTempFile->Left(1) == iOutputFileName.Left(1) )
+ {
+ moveErr = fileman->Rename( *iTempFile, iOutputFileName );
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingOkL: 1 renamed temp file: err %d", moveErr);
+ }
+ else
+ {
+ moveErr = fileman->Move( *iTempFile, iOutputFileName );
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingOkL: 2 moved tem file: err %d", moveErr);
+ }
+ CleanupStack::PopAndDestroy( fileman );
+
+ delete iTempFile;
+ iTempFile = NULL;
+ iError = moveErr;
+
+ iState = EStateFinalizing;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingOkL: Out");
+ }
+//=======================================================================================================
+
+void CSimpleVideoEditorImpl::ProcessingFailed()
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingFailed: In");
+ TInt delErr = iEnv.FsSession().Delete( *iTempFile );
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingFailed: 1, delErr:%d", delErr);
+ if ( delErr )
+ {
+ // @: should something be done?
+ }
+ delete iTempFile;
+ iTempFile = NULL;
+ iState = EStateFinalizing;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::ProcessingFailed: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyVideoClipAdded(CVedMovie& /*aMovie*/, TInt /*aIndex*/)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyVideoClipAdded: In");
+
+ if ( EStateInsertInputFirst == iState )
+ {
+ // Next insert the second item (i.e. video|image|audio|text)
+ iState = EStateInsertInputSecond;
+ }
+ else if ( EStateInsertVideo == iState || EStateInsertImage == iState
+ || EStateInsertTextToBegin == iState || EStateInsertTextToEnd == iState)
+ {
+ // Next start processing the movie
+ iState = EStateProcessing;
+ }
+ // if cancel is pressed in the middle of iMovie->InsertVideoClip(), state is put to iStateFinalizing to stop
+ // the process
+ else if ( EStateFinalizing == iState || EStateReady == iState )
+ {
+ ;
+ }
+ else
+ {
+ User::Invariant();
+ }
+
+ if ( iWaitDialog )
+ {
+ TRAP_IGNORE(iWaitDialog->ProcessFinishedL());
+ }
+ //CompleteRequest();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyVideoClipAdded: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyVideoClipAddingFailed(CVedMovie& /*aMovie*/, TInt aError)
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyVideoClipAddingFailed: In, aError:%d", aError);
+
+ iError = aError;
+ iError = FilterError();
+
+ // Next handle error and exit
+ iState = EStateFinalizing;
+
+ if ( iWaitDialog )
+ {
+ TRAP_IGNORE(iWaitDialog->ProcessFinishedL());
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyVideoClipAddingFailed: Out");
+ }
+
+
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyAudioClipAdded(CVedMovie& /*aMovie*/, TInt /*aIndex*/)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyAudioClipAdded: In");
+
+ ASSERT(iMovie && iMovie->VideoClipCount() == 1);
+
+ if ( EStateInsertAudio == iState )
+ {
+ TInt audioClipCount = iMovie->AudioClipCount();
+ TTimeIntervalMicroSeconds currentAudioClipEndTime = iMovie->AudioClipEndTime( audioClipCount - 1 ); // in movie timebase
+
+ TTimeIntervalMicroSeconds videoClipEndTime = iMovie->VideoClipEndTime(0); // in movie timebase
+ if( currentAudioClipEndTime > videoClipEndTime )
+ {
+ // Adjust the length so that the audio duration does not exceed video duration.
+ CVedAudioClipInfo* audioClip = iMovie->AudioClipInfo( audioClipCount - 1 );
+ TInt64 cutOutTime = audioClip->Duration().Int64() - ( currentAudioClipEndTime.Int64() - videoClipEndTime.Int64() );
+ iMovie->AudioClipSetCutOutTime( audioClipCount - 1, TTimeIntervalMicroSeconds(cutOutTime) ); // in clip timebase
+ }
+ ASSERT( iMovie->Duration() == videoClipEndTime );
+
+ TTimeIntervalMicroSeconds audioClipEndTime = iMovie->AudioClipEndTime( audioClipCount - 1);
+
+ ASSERT( audioClipEndTime.Int64() <= videoClipEndTime.Int64() );
+
+ TInt error = KErrNone;
+
+ if ( audioClipEndTime == videoClipEndTime )
+ {
+ if ( iMovie->VideoClipIsMuteable(0) )
+ {
+ iMovie->VideoClipSetMuted(0, ETrue);
+ }
+ }
+
+ // if the audio clip is shorter than the video clip, the original sound
+ // of the video clip has to be muted until the end of the new sound clip
+ else if ( audioClipEndTime < videoClipEndTime )
+ {
+
+ if ( iMovie->VideoClipEditedHasAudio(0) )
+ {
+
+ TVedDynamicLevelMark mark1( TTimeIntervalMicroSeconds(0), KAudioLevelMin );
+
+ TInt64 time = audioClipEndTime.Int64() - KFadeInTimeMicroSeconds;
+
+ TVedDynamicLevelMark mark2( TTimeIntervalMicroSeconds(time) , KAudioLevelMin );
+
+ TVedDynamicLevelMark mark3( audioClipEndTime, 0 );
+
+ TRAP( error, iMovie->VideoClipInsertDynamicLevelMarkL( 0, mark1 ) );
+
+ if ( error == KErrNone )
+ {
+ TRAP( error, iMovie->VideoClipInsertDynamicLevelMarkL( 0, mark2 ) );
+ }
+
+ if ( error == KErrNone )
+ {
+ TRAP( error, iMovie->VideoClipInsertDynamicLevelMarkL( 0, mark3 ) );
+ }
+
+ if ( error != KErrNone )
+ {
+ iError = error;
+ iError = FilterError();
+ }
+
+ }
+ }
+
+ if ( error == KErrNone )
+ {
+ iState = EStateProcessing;
+ }
+ else
+ {
+ iState = EStateProcessingFailed;
+ }
+ }
+
+ if( iWaitDialog )
+ {
+ TRAP_IGNORE(iWaitDialog->ProcessFinishedL());
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyAudioClipAdded: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyAudioClipAddingFailed(CVedMovie& /*aMovie*/, TInt aError)
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyAudioClipAddingFailed: In, aError:%d", aError);
+
+ iError = aError;
+
+ iError = FilterError();
+
+ // Next handle error and exit
+ iState = EStateFinalizing;
+ if ( iWaitDialog )
+ {
+ TRAP_IGNORE(iWaitDialog->ProcessFinishedL());
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyAudioClipAddingFailed: Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyImageClipGeneratorInitializationComplete(CVeiImageClipGenerator& /*aGenerator*/, TInt aError)
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyImageClipGeneratorInitializationComplete, In, aError:%d", aError);
+
+ iError = aError;
+
+ // If the wait dialog has been dismissed, i.e the action has been cancelled,
+ // we expect that the DialogDismissedL() method has set the correct state and won't
+ // set the state ourselves.
+ iGeneratorComplete = ETrue;
+ if( !iDialogDismissed )
+ {
+ if (KErrNone == aError)
+ {
+ iState = EStateInsertImage;
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyImageClipGeneratorInitializationComplete: 2");
+ }
+ else
+ {
+ iError = FilterError();
+ // Next handle error and exit
+
+ /*
+ If iImageClipGenerator is deleted here (in NotifyImageClipGeneratorInitializationComplete), endless
+ loop is resulted, because calling iImageClipGenerator's destructor leads to calling NotifyImageClipGeneratorInitializationComplete
+ again until stack overdoses etc.
+ iImageClipGenerator does not have to be deleted here, it is deleted in destructor.
+ delete iImageClipGenerator;
+ iImageClipGenerator = 0;
+ */
+
+ iState = EStateFinalizing;
+ }
+ }
+
+ CompleteRequest();
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::NotifyImageClipGeneratorInitializationComplete, Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::DialogDismissedL( TInt aButtonId )
+ {
+ LOGFMT(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DialogDismissedL, In, aButtonId:%d", aButtonId);
+
+ if ( aButtonId != EAknSoftkeyDone)
+ {
+ // If the action was cancelled, we set up the correspondig state
+ // and also set the iDialogDismissed property to indicate that.
+ iDialogDismissed = ETrue;
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DialogDismissedL, 1");
+
+ if (EStateProcessing == iState && iMovie)
+ {
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DialogDismissedL, 2, canceling processing...");
+ iState = EStateProcessingFailed;
+ /*
+ It depends on scheduling of active objects whether NotifyMovieProcessingCompleted()
+ gets called. If iProgressDialog is NULLed by itself in the time DialogDismissed() gets called
+ it should be nonrelevant whether NotifyMovieProcessingCompleted() called or not because
+ in NotifyMovieProcessingCompleted() iProgressDialog->ProcessFinished() is called only if
+ it is not NULL leading to another call to DialogDismissed(). But even if DialogDismissed()
+ gets called multiple times it should not cause any harm.
+ */
+ iMovie->CancelProcessing();
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DialogDismissedL, 4, ...canceling called");
+ }
+ else
+ {
+ // if wait dialog is canceled during inserts
+ iError = KErrCancel;
+ iState = EStateFinalizing;
+ }
+
+ // this problem is because in add text mode orientation is forced to portrait in
+ // such an early stage
+ // ask Heikki's opinion, why appUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationPortrait);
+ // is called in InitializeOperationL()?
+ // Can it be moved to where it is neede, in GetText()?
+ if (EOperationModeAddText == iOperationMode)
+ {
+ RestoreOrientation();
+ }
+ }
+
+ // Only if the VeiImageClipGenerator::NewL() called from the RunL() has finished and called
+ // the NotifyImageClipGeneratorInitializationComplete() method we complete and activate again.
+ // If not, we rely that the NotifyImageClipGeneratorInitializationComplete() method
+ // calls CompleteRequest() when it's called.
+ if( iGeneratorComplete )
+ {
+ CompleteRequest();
+ }
+
+ LOG(KVideoEditorLogFile, "CSimpleVideoEditorImpl::DialogDismissedL, Out");
+ }
+
+//=======================================================================================================
+void CSimpleVideoEditorImpl::NotifyVideoClipRemoved(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipIndicesChanged(CVedMovie& /*aMovie*/, TInt /*aOldIndex*/, TInt /*aNewIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipTimingsChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipSettingsChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipColorEffectChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipAudioSettingsChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipGeneratorSettingsChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipDescriptiveNameChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyStartTransitionEffectChanged(CVedMovie& /*aMovie*/){}
+void CSimpleVideoEditorImpl::NotifyMiddleTransitionEffectChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyEndTransitionEffectChanged(CVedMovie& /*aMovie*/){}
+void CSimpleVideoEditorImpl::NotifyAudioClipRemoved(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyAudioClipIndicesChanged(CVedMovie& /*aMovie*/, TInt /*aOldIndex*/, TInt /*aNewIndex*/){}
+void CSimpleVideoEditorImpl::NotifyAudioClipTimingsChanged(CVedMovie& /*aMovie*/, TInt /*aIndex*/){}
+void CSimpleVideoEditorImpl::NotifyMovieQualityChanged(CVedMovie& /*aMovie*/){}
+void CSimpleVideoEditorImpl::NotifyMovieReseted(CVedMovie& /*aMovie*/){}
+void CSimpleVideoEditorImpl::NotifyMovieOutputParametersChanged(CVedMovie& /*aMovie*/){}
+void CSimpleVideoEditorImpl::NotifyAudioClipDynamicLevelMarkInserted(CVedMovie& /*aMovie*/, TInt /*aClipIndex*/, TInt /*aMarkIndex*/){}
+void CSimpleVideoEditorImpl::NotifyAudioClipDynamicLevelMarkRemoved(CVedMovie& /*aMovie*/, TInt /*aClipIndex*/, TInt /*aMarkIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipDynamicLevelMarkInserted(CVedMovie& /*aMovie*/, TInt /*aClipIndex*/, TInt /*aMarkIndex*/){}
+void CSimpleVideoEditorImpl::NotifyVideoClipDynamicLevelMarkRemoved(CVedMovie& /*aMovie*/, TInt /*aClipIndex*/, TInt /*aMarkIndex*/){}
+// End of file