diff -r 072a5fa0c63b -r c6bafb5162d8 voicerecorder/RecViewSrc/CVRRecViewModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voicerecorder/RecViewSrc/CVRRecViewModel.cpp Wed Sep 01 12:29:14 2010 +0100 @@ -0,0 +1,2476 @@ +/* +* Copyright (c) 2002 - 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This class is the data model and state machine of the Recorder View. +* The state machine is defined by a VR_STATEMACHINE resource structure. +* +*/ + + +// INCLUDE FILES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Key definitions +#include +#include +#include +#include +#include +#include +#include + +#include // Feature manager +#include // Disable e-mail +#include "MessagingDomainCRKeys.h" // Disable e-mail variation flag + +#include // link against centralrepository.lib +#ifdef RD_MULTIPLE_DRIVE +#include +#endif +#include "VoiceRecorderInternalCRKeys.h" + +#include +#include "CVRMemo.h" +#include "TVRState.h" +#include "CVRMdaRecorder.h" +#include "VRConsts.h" +#include "CVRSystemEventHandler.h" +#include "CVRMediaRemovalMonitor.h" +#include "VRUtils.h" +#include "CVRRecViewModel.h" +#include + +#include "VRUSBStateHanlder.h" + + +// CONSTANTS +const TInt KAllowInCallRecording( 1 ); + +// Shown if maximum recording time is not known +_LIT( KVRBeforeFirstEstimateLabel, "--:--:--" ); +// MMS/High text is inserted here +_LIT( placeForQuality, "%U" ); + + +// ================= MEMBER FUNCTIONS ======================================== +// --------------------------------------------------------------------------- +// CVRRecViewModel::CVRRecViewModel +// +// --------------------------------------------------------------------------- +// +CVRRecViewModel::CVRRecViewModel() + : iStateArray( 2 ), + iLabelSets( 2 ), + iPreviousCallState( EPSCTsyCallStateNone ), + iCanHandleCommands( ETrue ), + iCBAEnabled( ETrue ), + iIsDriveReady( ETrue ) + { + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::~CVRRecViewModel +// +// --------------------------------------------------------------------------- +// +CVRRecViewModel::~CVRRecViewModel() + { + // It might be possible to make this method leaving and put it + // somewhere else than destructor + SaveVolumeSettings(); + iLabelSets.ResetAndDestroy(); + iStateArray.Reset(); + + delete[] iLabelLayoutLinks; + delete iMemo; + delete iRecorder; + if ( iGlobalNote && iIsNoteLaunched ) + { + // nothing much to do but ignore. + TRAP_IGNORE( iGlobalNote->CancelNoteL( iNoteId ) ); + } + + delete iGlobalNote; + + if (iCurrentCallHandler) + { + delete iCurrentCallHandler; + } + delete iCurrentMMCEjectHandler; + + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ConstructFromResourceL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::ConstructFromResourceL( TResourceReader& aReader ) + { + + TRAP_IGNORE( iCurrentCallHandler = CVRSystemEventHandler::NewL() ); + iCurrentCallHandler->Listen( KPSUidCtsyCallInformation, KCTsyCallState, + this ); + //listen MMC eject + TInt driveRemovableMassStorage = VRUtils::GetRemovableMassStorageL(); + iCurrentMMCEjectHandler = CVRMediaRemovalMonitor::NewL(driveRemovableMassStorage, CEikonEnv::Static()->FsSession(), this); + + if ( FeatureManager::FeatureSupported( KFeatureIdKeypadNoVoiceKey ) && + FeatureManager::FeatureSupported( + KFeatureIdApplicationControllableAudioRouting ) ) + { + ReadDefaultSpeakerL(); + } + else + { + iIhfState = ETrue; + } + + LoadVolumeSettingsL(); + // Connecting and initialization: + CRepository* myRepSession = CRepository::NewLC( KCRUidVoiceRecorder ); + + // Get the values from the repository + User::LeaveIfError( myRepSession->Get( KVRDefaultAudioFormat, + iVRAudioFormat ) ); + + User::LeaveIfError( myRepSession->Get( KVRAllowInCallRecording, + iVRAllowInCallRecording ) ); + CleanupStack::PopAndDestroy( myRepSession ); + + iGlobalNote = CAknGlobalNote::NewL(); + + iMemo = new( ELeave ) CVRMemo; + iMemo->ConstructL( iVRAudioFormat ); + + TInt numLabelSets( aReader.ReadInt16() ); + TInt i; + + for ( i = 0; i < numLabelSets; i++ ) + { + CDesCArray* labelSet; + TInt numLabels( aReader.ReadInt16() ); + + if ( numLabels > 0 ) + { + // TResourceReader re-reads the length, have to rewind + aReader.Rewind( sizeof( TInt16 ) ); + labelSet = aReader.ReadDesCArrayL(); + } + else + { + // create an empty array "by hand", + // TResourceReader is not able to do this + labelSet = new( ELeave ) CDesCArrayFlat( 1 ); + } + + CleanupStack::PushL( labelSet ); + iLabelSets.AppendL( labelSet ); + CleanupStack::Pop( labelSet); + } + + TInt linkCount( aReader.ReadInt16() ); + iLabelLayoutLinks = new( ELeave ) TVRLabelLayoutLink[ linkCount ]; + for ( i = 0; i < linkCount; i++ ) + { + iLabelLayoutLinks[ i ].ReadFromResource( aReader ); + } + + TInt numUiStates( aReader.ReadInt16() ); + + TVRState uistate; + for ( i = 0; i < numUiStates; i++ ) + { + uistate.ReadFromResource( aReader ); + uistate.iId = i; + iStateArray.AppendL( uistate ); + } + + iState = &iStateArray.At( 0 ); + + TInt numContexts( aReader.ReadInt16() ); + for ( i = 0; i < numContexts; i++ ) + { + TInt id( aReader.ReadInt8() ); + TVRContext* context = &iContexts[ id ]; + context->iValid = ETrue; + context->iInitialTransition.iCommandId = aReader.ReadUint8(); + context->iInitialTransition.iNewState = aReader.ReadUint8(); + context->iInitialTransition.iFunctionId = aReader.ReadUint8(); + context->iInitialTransition.iValid = ETrue; + + + TInt numStates( aReader.ReadInt16() ); + for ( TInt j = 0; j < numStates; j++ ) + { + TInt id( aReader.ReadInt8() ); + TVRContext::TState* state = &context->iStates[ id ]; + state->iValid = ETrue; + TInt numTransitions( aReader.ReadInt16() ); + __ASSERT_DEBUG( numTransitions <= KVRMaxTransitions, + User::Panic( KVRPanic, EPanicTooManyTransitions ) ); + + for ( TInt k = 0; k < numTransitions; k++ ) + { + TVRContext::TTransition* trans = &state->iTransitions[ k ]; + trans->iCommandId = aReader.ReadUint8(); + trans->iNewState = aReader.ReadUint8(); + trans->iFunctionId = aReader.ReadUint8(); + trans->iValid = ETrue; + } + } + } + + StringLoader::Load( iDateUsualWithZero, R_QTN_DATE_USUAL_WITH_ZERO ); + StringLoader::Load( iTimeUsualWithZero, R_QTN_TIME_USUAL_WITH_ZERO ); + StringLoader::Load( iTimeDuratLong, R_QTN_TIME_DURAT_LONG ); + StringLoader::Load( iTimeDuratMinSecWithZero, + R_QTN_TIME_DURAT_MIN_SEC_WITH_ZERO ); + + + + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ProcessKeyEventL +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::ProcessKeyEventL( const TKeyEvent& aKeyEvent, + const TEventCode aType ) + { + TBool retval( EFalse ); + if ( aType != EEventKey ) + { + return retval; + } + + switch ( aKeyEvent.iCode ) + { + case EKeyPhoneEnd: + { + TInt currentState( iCurrentCallHandler->StateL(KPSUidCtsyCallInformation, KCTsyCallState) ); + + if ( ( currentState != EPSCTsyCallStateNone ) ) + { + HandleCommandL( ECmdDisconnectCall ); + retval = EKeyWasNotConsumed; + } + else + { + // Voice recorder wasn't here =), retval stays EFalse + iIsEndKey = ETrue; + + // Exit if app is not fully initialized + if ( !iContextEntered ) + { + CEikonEnv::Static()->EikAppUi()-> + HandleCommandL( EEikCmdExit ); + } + } + break; + } + case EKeyBackspace: + { + HandleCommandL( ECmdDelete ); + retval = ETrue; + break; + } + case EKeyYes: + { + if( aKeyEvent.iRepeats > 0 ) + { + if( VisualStateId() == EStateRecording || + VisualStateId() == EStatePlaying ) + { + HandleCommandL( ECmdPause ); + } + } + break; + } + case EKeySide: + { + retval = ETrue; + + if ( aKeyEvent.iRepeats ) + { + switch ( iState->iId ) + { + case EStateIdle: + { + HandleCommandL( ECmdPlay ); + break; + } + case EStateRecording: + case EStateRecordEmbedded: + case EStateRecordingPaused: + case EStatePlaying: + case EStatePlayingPaused: + { + HandleCommandL( ECmdStop ); + break; + } + case EStateDeleted: + default: + { + retval = EFalse; + break; + } + } + } + else + { + switch ( iState->iId ) + { + case EStateIdle: + case EStateDeleted: + case EStateRecordingPaused: + { + HandleCommandL( ECmdRecord ); + break; + } + case EStateRecording: + case EStateRecordEmbedded: + case EStatePlaying: + { + HandleCommandL( ECmdPause ); + break; + } + case EStatePlayingPaused: + { + HandleCommandL( ECmdPlay ); + break; + } + default: + { + retval = EFalse; + break; + } + } + } + break; + } + default: + { + break; + } + } + return retval; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HandleCommandL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::HandleCommandL( TInt aCommandId ) + { + // This command must be acceptable all times. + if ( aCommandId == ECmdCancelNote ) + { + if ( iIsNoteLaunched ) + { + // nothing much to do but ignore. + TRAP_IGNORE( iGlobalNote->CancelNoteL( iNoteId ) ); + } + return; + } + + if ( !CanAcceptCommands() ) + { + return; + } + + if ( !CanHandleCommands() ) + { + return; + } + if ( EStateRecording == iState->iId && ECmdRecord == aCommandId || + EStateRecording == iState->iId && ECmdRename == aCommandId ) + { + return; + } + + switch ( aCommandId ) + { + case ECmdHelp: + { + CEikonEnv::Static()->EikAppUi()->HandleCommandL( aCommandId ); + break; + } + case EEikCmdExit: + { + CEikonEnv::Static()->EikAppUi()->HandleCommandL( EAknSoftkeyExit); + break; + } + + case EAknSoftkeyExit: + { + CEikonEnv::Static()->EikAppUi()->HandleCommandL( aCommandId ); + break; + } + case ECmdSendVia: + { + CEikonEnv::Static()->EikAppUi()->HandleCommandL( aCommandId ); + break; + } + case ECmdSaveAttachment: + { + __ASSERT_DEBUG( iRecorder, User::Panic( KVRPanic, KErrNotFound ) ); + iRecorder->DetachMemo(); + // Save permanently but do not remove the original + + HBufC* label = StringLoader::LoadLC( R_VR_SAVE_WAITNOTE_LABEL ); + + iIsNoteLaunched = ETrue; + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, *label, ETrue ); + + if ( iStateInfoObserver ) + { + iStateInfoObserver->Update(); + } + iRecorder->AttachToMemoL( iMemo ); + + // Remove the waitnote + iGlobalNote->CancelNoteL( iNoteId ); + iIsNoteLaunched = EFalse; + + CleanupStack::PopAndDestroy( label ); + break; + } + // FLOWTHROUGH + // in case of end key, different command must be given to state + // machine - recview gives ECmdAutoStopInterrupted + case ECmdAutoStopInterrupted: + { + if ( iIsEndKey ) + { + aCommandId = ECmdEndKey; + iIsEndKey = EFalse; + } + } + // Other commands are given to the state machine + default: + { + TVRContext::TTransition transition; + GetTransition( transition, aCommandId ); + TBool functionOK( ETrue ); + TRAPD( err, functionOK = + CallFunctionByIdL( transition.iFunctionId ) ); + + if ( err != KErrNone ) + { + // This is done to enable button events + iCanHandleCommands = ETrue; + } + + // We may have detached memo and we must reattach + if ( err == KErrInUse ) + { + __ASSERT_DEBUG( iRecorder, + User::Panic( KVRPanic, KErrNotFound ) ); + iRecorder->AttachToMemoL( iMemo ); + } + + if ( err == KErrNotReady && iIsNoteLaunched && iGlobalNote ) + { + // nothing much to do but ignore. + TRAP_IGNORE( iGlobalNote->CancelNoteL( iNoteId ) ); + } + + // If the disk gets full while saving, the next state is deleted + if ( err == KErrDiskFull || err == KErrArgument ) + { + if ( iContext == EContextRecordNewNormal || + iContext == EContextNormal || + iContext == EContextEmptyNormal ) + { + ChangeState( EStateDeleted, ETrue ); + } + else + { + // In record new embedded context the UI is left in + // idle state, so the memo must be attached + // (EFunctionOK detaches it) + __ASSERT_DEBUG( iRecorder, + User::Panic( KVRPanic, KErrNotFound ) ); + if(!dynamic_cast(iRecorder)->IsAttachedToMemo()) + { + iRecorder->AttachToMemoL( iMemo ); + } + } + + if ( err == KErrDiskFull ) + { + // Maybe an error note should be shown + return; + } + + // Propagate to the error handler to show a note. + User::Leave( err ); + } + else + { + // The LeaveIfError must be here because CallFunctionByIdL + // might have called Exit() (leaving with -1002) and the + // framework might be half-dead leading to access violation, + // if the UI state is changed + User::LeaveIfError( err ); + if ( functionOK ) + { + // If the in-call recording disabling feature is active, + // then the state of the UI will have to reflect that + TUint newState(transition.iNewState); + + if ( iVRAllowInCallRecording != KAllowInCallRecording ) + { + TInt currentState( iCurrentCallHandler->StateL( KPSUidCtsyCallInformation, KCTsyCallState ) ); + + if ( currentState != EPSCTsyCallStateNone ) + { + currentState = iCurrentCallHandler->StateL( + KPSUidCtsyCallInformation, KCTsyCallType ); + + switch ( currentState ) + { + case EPSCTsyCallTypeCSVoice: + case EPSCTsyCallTypeHSCSD: + case EPSCTsyCallTypeH324Multimedia: + case EPSCTsyCallTypeVoIP: + { + newState = EStateDisableButtons; + break; + } + default: + { + break; + } + } + + } + } + + // Function didn't want to cancel the state change + ChangeState( newState ); + } + } + + break; + } + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetTransition +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetTransition( TVRContext::TTransition& aTransition, + TUint aCommandId ) const + { + __ASSERT_DEBUG( iContexts[ iContext ].iValid, User::Panic( KVRPanic, + EPanicInvalidContext ) ); + __ASSERT_DEBUG( iContexts[ iContext ].iStates[ iState->iId ].iValid, + User::Panic( KVRPanic, EPanicInvalidState ) ); + + const TVRContext::TState* state = + &(iContexts[ iContext ].iStates[ iState->iId ]); + for ( TInt i = 0; i < KVRMaxTransitions; i++ ) + { + const TVRContext::TTransition* transition = &state->iTransitions[ i ]; + if ( ( transition->iCommandId == aCommandId ) && + ( transition->iValid ) ) + { + aTransition = *transition; + return; + } + } + + User::Panic( KVRPanic, EPanicInvalidTransition ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetTransition +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetTransition( + TVRContext::TTransition& aTransition ) const + { + aTransition = iContexts[ iContext ].iInitialTransition; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ChangeState +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::ChangeState( TUint aNewState, TBool aForced ) + { + if ( !aForced ) + { + if ( ( aNewState == iState->iId ) || ( aNewState == EStateInitial ) ) + { + return; + } + } + + iState = &iStateArray.At( aNewState ); + + if ( iStateInfoObserver ) + { + iStateInfoObserver->Update(); + } + if ( iButtonPanelObserver ) + { + iResetButtons = ETrue; + iButtonPanelObserver->Update( EVRUpdateStateChange ); + } + if ( iDecoratorObserver ) + { + iDecoratorObserver->Update(); + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::EnterContextL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::EnterContextL( const TVRRecViewContexts& aContext ) + { + iContextEntered = EFalse; + if ( iRecorder ) + { + delete iRecorder; + iRecorder = NULL; + } + + CVRMdaRecorder* recorder = new( ELeave ) CVRMdaRecorder(); + CleanupStack::PushL( recorder ); + recorder->ConstructL(); + CleanupStack::Pop(); + iRecorder = recorder; + + iRecorder->RegisterObserver( iStateInfoObserver ); + iRecorder->SetAutoStopObserver( this ); + + LeaveContext(); + iContext = aContext; + + iRecorder->AttachToMemoL(iMemo); + + TVRContext::TTransition transition; + GetTransition( transition ); + + ChangeState( transition.iNewState, ETrue ); + CallFunctionByIdL( transition.iFunctionId ); + + iContextEntered = ETrue; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::LeaveContext +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::LeaveContext() + { + iContextEntered = EFalse; + if( iRecorder ) + { + iRecorder->UnregisterObserver( iStateInfoObserver ); + iRecorder->UnregisterObserver( iButtonPanelObserver ); + + iRecorder->DetachMemo(); + + iRecorder->RegisterObserver( iStateInfoObserver ); + iRecorder->RegisterObserver( iButtonPanelObserver ); + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CbaResourceId +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::CbaResourceId() const + { + return iState->iCbaResourceId; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetHelpContext +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetHelpContext( TCoeHelpContext& aContext ) const + { + if (FeatureManager::FeatureSupported(KFeatureIdHelp)) + { + if ( iState->iId == EStateDeleted ) + { + aContext.iContext = KVOREC_HLP_EMPTY_RECORDER; + } + else + { + aContext.iContext = KVOREC_HLP_MAIN; + } + } + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetDecoratorObserver +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetDecoratorObserver( MVRObserver* aObserver ) + { + iDecoratorObserver = aObserver; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::MenuBarResourceId +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::MenuBarResourceId() const + { + return iState->iMenubarResourceId; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ButtonCount +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::ButtonCount() const + { + + return iState->iButtonCount; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CBAEnabled +// from MVRDecoratorModel +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::CBAEnabled() const + { + return iCBAEnabled; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ButtonState +// Checks and returns whether the state of the button should be in active or +// dimmed state. aButtonId tells the index of the button to be checked. Few +// special cases (end and the beginning of the clip) can be handled here. +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::ButtonState( TInt aButtonId ) const + { + if(CVRUSBStateHanlder::IsUsbActive() || !iIsDriveReady) + { + return EDimmed; + } + // Disable rewind button if there's nothing to rewind + if ( aButtonId == EButtonRewind && + ( Position().Int64() / KVRSecondAsMicroSeconds ) < 1 ) + { + return EDimmed; + } + + // Disable forward button if position is at the end or the length of the + // clip is smaller than 1 + if ( aButtonId == EButtonForward && ( Position() == Duration() || + ( Duration().Int64() / KVRSecondAsMicroSeconds ) < 1 ) ) + { + return EDimmed; + } + + // Jeffery: the following ifs are temperary. they need to be removed after "Pause" is supported in plugin +#ifdef __AAC_ENCODER_PLUGIN + if ( iState->iId == EStateRecording && aButtonId == EButtonRecord && iMemo->Quality() == EQualityHigh) + { + return EDimmed; + } +#endif + + return iState->ButtonState( aButtonId ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CommandId +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::CommandId( TInt aButtonId ) const + { + return iState->ButtonCommandId( aButtonId ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::InitialFocusButtonId +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::InitialFocusButtonId() const + { + return iState->iFocusButtonId; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetButtonPanelObserver +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetButtonPanelObserver( MVRObserver* aObserver ) + { + if ( iRecorder ) + { + if ( iButtonPanelObserver ) + { + iRecorder->RegisterObserver( aObserver ); + } + else + { + iRecorder->UnregisterObserver( iButtonPanelObserver ); + } + } + + iButtonPanelObserver = aObserver; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ResetNeeded +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::ResetNeeded() + { + if ( iResetButtons ) + { + iResetButtons = EFalse; + return ETrue; + } + + return iResetButtons; // EFalse always + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::VisualStateId() +// Returns the id of VR current (visual) state +// --------------------------------------------------------------------------- +// +TUint CVRRecViewModel::VisualStateId() const + { + return iState->iStateId; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CanHandleCommands() +// Returns ETrue if model can handle new commands, EFalse otherwise +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::CanHandleCommands() const + { + return iCanHandleCommands; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::Duration +// +// --------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CVRRecViewModel::Duration() const + { + if ( ( iState->iId == EStateRecording ) || + ( iState->iId == EStateRecordingPaused ) ) + { + return iMemo->MaxDuration(); + } + return iMemo->Duration(); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::Position +// +// --------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CVRRecViewModel::Position() const + { + if ( ( iState->iId == EStateRecording ) || + ( iState->iId == EStateRecordingPaused ) ) + { + return iMemo->Duration(); + } + return iMemo->Position(); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetLabel +// Non-leaving version +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetLabel( TDes& aName, TInt aLabelIndex ) const + { + TRAP_IGNORE( GetLabelL( aName, aLabelIndex ) ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetLabelL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetLabelL( TDes& aName, TInt aLabelIndex ) const + { + if ( !iMemo->IsValid() ) + { + aName.SetLength( 0 ); + return; + } + + CDesCArray* labels = iLabelSets.At( iState->iLabelSetId ); + User::LeaveIfNull( labels ); + + if ( aLabelIndex < labels->Count() ) + { + TInt index = aLabelIndex; + + TBuf< VRLABELMAXLENGTH > formatStr( + labels->MdcaPoint( index ) ); + TBuf< VRLABELMAXLENGTH > formattedTime; + + switch ( aLabelIndex ) + { + case ELabelMemoName: + { + //StringLoader::Format( aName, formatStr, -1, iMemo->Name() ); + aName.Copy(iMemo->Name()); + break; + } + case ELabelMemoDate: + { + iMemo->DateCreated().FormatL( formattedTime, + iDateUsualWithZero ); + StringLoader::Format( aName, formatStr, 0, formattedTime ); + + iMemo->DateCreated().FormatL( formattedTime, + iTimeUsualWithZero ); + formatStr.Copy( aName ); + StringLoader::Format( aName, formatStr, 1, formattedTime ); + AknTextUtils::LanguageSpecificNumberConversion( aName ); + break; + } + case ELabelMemoQuality: + { + // Display empty row if feature is not on + if ( !VRUtils::FeatureEnabled( EVRFeatureShowQualitySetting ) ) + { + aName.Copy( KNullDesC ); + break; + } + + aName.Copy( formatStr ); + break; + } + case ELabelQualityText: + { + // Display empty row if feature is not on + if ( !VRUtils::FeatureEnabled( EVRFeatureShowQualitySetting ) ) + { + aName.Copy( KNullDesC ); + break; + } + + formatStr.Copy( placeForQuality ); + + switch( iMemo->Quality() ) + { + case EQualityMMSOptimized: + { + StringLoader::Load( formattedTime, R_VOREC_QUALITY_MMS_OPTIMIZED ); + StringLoader::Format( aName, formatStr, -1, formattedTime ); + break; + } + + // EQualityNormal is used only when mp4 is supported. In this case the file is saved as wav. +#ifdef __AAC_ENCODER_PLUGIN + case EQualityNormal: + { + StringLoader::Load( formattedTime, R_VOREC_QUALITY_NORMAL ); + StringLoader::Format( aName, formatStr, -1, formattedTime ); + break; + } +#endif + + case EQualityHigh: + { + StringLoader::Load( formattedTime, R_VOREC_QUALITY_HIGH ); + StringLoader::Format( aName, formatStr, -1, formattedTime ); + break; + } + default: + { + aName.Copy( KNullDesC ); + break; + } + } + break; + } + case ELabelBarMin: + { + aName.Copy( KNullDesC ); + break; + } + case ELabelBarMax: + { + // This label layout is nowadays taking automatically care of + // string mirroring in the case of mirrored layout. So use of + // AknLayoutUtils::LayoutMirrored() isn't needed anymore + + TTimeIntervalMicroSeconds max( 0 ); + if ( ( iState->iId == EStateRecording ) || + ( iState->iId == EStateRecordingPaused ) ) + { + max = iMemo->MaxDuration(); + } + else + { + max = iMemo->Duration().Int64(); + + if ( max.Int64() < 0 ) + { + max = 0; + } + } + + TTime lengthAsTime( max.Int64() ); + TTime positionAsTime( iMemo->Position().Int64() ); + TBuf< VRLABELMAXLENGTH > formattedPosition; + + // current memo quality + TVRQuality quality( iMemo->Quality() ); + + // Show --:--:-- if estimate for maximum recording time is not + // known yet. Done only when memo quality is High + if ( ( ( iState->iId == EStateRecording ) || + ( iState->iId == EStateRecordingPaused )) && + ( Position() < KVRFirstEstimateTime ) && + ( quality == EQualityHigh ) && + ( max.Int64() < 0) ) + { + formattedTime.Append( KVRBeforeFirstEstimateLabel ); + } + // Show normal maximum time + else + { + // Show longer format if time is more than 1 hour + FormatTimeL( lengthAsTime, formattedTime ); + } + + // Show longer format if time is more than 1 hour + FormatTimeL( positionAsTime, formattedPosition ); + + StringLoader::Format( aName, formatStr, 0, formattedPosition ); + formatStr.Copy( aName ); + StringLoader::Format( aName, formatStr, 1, formattedTime ); + AknTextUtils::LanguageSpecificNumberConversion( aName ); + + break; + } + case ELabelStatus: + { + aName.Copy( iState->iStatus ); + break; + } + default: + { + break; + } + } + } + else + { + aName.SetLength( 0 ); + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ResourceIdForLabel +// +// --------------------------------------------------------------------------- +// +TInt CVRRecViewModel::ResourceIdForLabel( TInt aLabelIndex, + TAknLayoutId aLayout ) const + { + switch ( aLayout ) + { + case EAknLayoutIdELAF: + default: + return iLabelLayoutLinks[ aLabelIndex ].iEuroId; + + case EAknLayoutIdABRW: + return iLabelLayoutLinks[ aLabelIndex ].iArabicHebrewId; + + case EAknLayoutIdAPAC: + return iLabelLayoutLinks[ aLabelIndex ].iApacId; + + } + + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetStateInfoObserver +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetStateInfoObserver( MVRObserver* aObserver ) + { + iStateInfoObserver = aObserver; + if( iRecorder ) + { + iRecorder->RegisterObserver( iStateInfoObserver ); + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetStateInfoPanelObserver +// Observes changes in state info panel +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetStateInfoPanelObserver( MVRStateInfoObserver* + aObserver ) + { + iStateInfoPanelObserver = aObserver; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HasProgressBar +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::HasProgressBar() const + { + return iState->iHasProgressBar; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetSelectedFilesLC +// +// --------------------------------------------------------------------------- +// +MDesCArray* CVRRecViewModel::GetSelectedFilesLC() const + { + CDesCArray* array = new( ELeave ) CDesCArrayFlat( 1 ); // granularity = 1 + CleanupStack::PushL( array ); + array->AppendL( iMemo->Filename() ); + return array; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetVolume +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetVolume( TInt aStep, TInt aMaxSteps ) + { + iIhfVolume = aStep; + iRecorder->SetVolume( aStep, aMaxSteps ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetMemoName +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetMemoName( const TDesC& aFilename ) + { + iMemo->SetName( aFilename ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetMemoNameNewL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetMemoNameNewL( TBool aEmbedded ) + { + iMemo->SetTemporaryNameL( aEmbedded ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::Filename +// +// --------------------------------------------------------------------------- +// +const TDesC& CVRRecViewModel::Filename() const + { + return iMemo->Filename(); + } + +void CVRRecViewModel::SetSavingLocationL( const TDesC& aPath ) + { + iMemo->SetSavingLocationL( aPath ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::Update +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::Update( TVRUpdateCommand /*aCommand*/ ) + { + // Error is propagated to error handling method + TRAPD( err, HandleCommandL( ECmdAutoStopAtEnd ) ); + + // Ignore further errors + TRAP_IGNORE( HandleUpdateErrorL( err ) ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::IsEmbedded +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::IsEmbedded() const + { + return ( iContext == EContextRecordNewForRemote ) + || ( iContext == EContextViewer ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CanAcceptCommands +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::CanAcceptCommands() const + { + return ( iContextEntered != EFalse ) && iRecorder->CanAcceptCommands(); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SendViaL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SendViaL( CSendUi* aSendUi ) + { + // Don't accept commands during sending operation + iContextEntered = EFalse; + + iRecorder->DetachMemo(); + // Detaching resets the clip position so button panel needs to be updated + iButtonPanelObserver->Update( EVRUpdatePositionChange ); + + TSendingCapabilities capabilities + (0, KVRSendUiMsgSize, TSendingCapabilities::ESupportsAttachments); + CMessageData* messageData = CMessageData::NewL(); + CleanupStack::PushL( messageData ); + + messageData->AppendAttachmentHandleL( iMemo->File() ); + + // Get an array of the services that should be dimmed + CArrayFixFlat< TUid >* servicesToDim = SendViaServicesToDimLC(); + + // For some reason this function leaves when 'NO' is selected in bluetooth + // case's activation question. If this is not Trapped iContextEntered stays + // EFalse and no commands can be executed + TRAPD( err, aSendUi->ShowQueryAndSendL( messageData, + capabilities, + servicesToDim ) ); + + CleanupStack::PopAndDestroy( servicesToDim ); + CleanupStack::PopAndDestroy( messageData ); + + iRecorder->AttachToMemoL( iMemo ); + + iContextEntered = ETrue; + + // This is done so we get possible "Feature not supported" + // infonote from the framework + User::LeaveIfError( err ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SendViaServicesToDimLC +// Generates an array of the services (Uids) that should be dimmed from Send +// via menu. Returns a pointer to that array. Configuration in Messaging +// central repository defines services to dim. +// --------------------------------------------------------------------------- +// +CArrayFixFlat* CVRRecViewModel::SendViaServicesToDimLC() + { + CArrayFixFlat< TUid >* servicesToDim = + new( ELeave ) CArrayFixFlat< TUid >( 1 ); + CleanupStack::PushL( servicesToDim ); + + CRepository* repository = + CRepository::NewL( KCRUidMuiuMessagingConfiguration ); + TInt configuration = 0; + if ( !repository->Get( KMuiuSendUiConfiguration, configuration ) ) + { + configuration = configuration & KMuiuEmailDisabledInMultimedia; + } + delete repository; + + if ( configuration ) + { + servicesToDim->AppendL( KSenduiMtmSmtpUid ); // normal email + servicesToDim->AppendL( KSenduiMtmSyncMLEmailUid ); // sync email + } + + return servicesToDim; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CallFunctionByIdL +// +// --------------------------------------------------------------------------- +// +/* +IMPLEMENTATION NOTE: +This method needs refactoring with CVRMemo and CVRMdaRecorder. +Probably most of the logic should be transferred to CVRMemo. +*/ +TBool CVRRecViewModel::CallFunctionByIdL( TInt aFunctionId ) + { + switch ( aFunctionId ) + { + case EFunctionPlay: + { + CVRMdaRecorder* iRecorderUtility = NULL; + iRecorderUtility = dynamic_cast(iRecorder); + if ( VRUtils::UnsupportedCallTypeOngoing( ETrue ) || iRecorderUtility == NULL || !iRecorderUtility->IsAttachedToMemo()) + { + return EFalse; + } + + iIgnoreNextIhfChange = EFalse; + SetRecorderVolume(); + SetIHFIfCallNotActive( iIhfState ); + TInt mediaservErr( KErrNone ); + + // Don't accept CBA commands + iCBAEnabled = EFalse; + // Update CBAs + iDecoratorObserver->Update( EVRUpdateCBA ); + TRAPD( leaveErr, mediaservErr = iRecorder->PlayL() ); + + // Accept CBAs again. CBAs are updated when state is changed + iCBAEnabled = ETrue; + + if ( leaveErr == KErrNotReady ) + { + ShowNoteL( R_VR_CORRUPT_INFONOTE_LABEL, EAknGlobalErrorNote ); + return EFalse; + } + + if ( mediaservErr != KErrNone ) + { + // cancel the state change + // the error note is shown in CVRMdaRecorder + return EFalse; + } + User::LeaveIfError( leaveErr ); + break; + } + case EFunctionStop: + { + // Turn off the IHF after playing + SetIHFIfCallNotActive( EFalse ); + iRecorder->Stop(); + CheckIhfState(); + break; + } + case EFunctionStopWithNote: + { + // No need to do anything to IHF here since this is + // called after recording (IHF is not used) + iRecorder->Stop(); + ShowNoteL( R_VR_STOP_INFONOTE_LABEL, EAknGlobalInformationNote ); + break; + } + case EFunctionStopAndSave: + { + // No need to do anything to IHF here since this is + // called after recording (IHF is not used) + StopAndSaveL( 0 ); + break; + } + case EFunctionAutoStopAndSave: + { + // No need to do anything to IHF here since this is + // called after recording (IHF is not used) + StopAndSaveL( R_VR_STOP_INFONOTE_LABEL ); + break; + } + case EFunctionSilentStopAndSave: + { + // No need to do anything to IHF here since this is + // called after recording (IHF is not used) + StopAndSaveL( 0 ); + break; + } + + case EFunctionAutoStop: + { + // Turn off the IHF after playing + SetIHFIfCallNotActive( EFalse ); + iRecorder->Stop(); + CheckIhfState(); + break; + } + case EFunctionSaveBeforeExit: + { + StopAndCloseL( R_VR_STOP_SAVE_WAITNOTE_LABEL ); + break; + } + case EFunctionRecord: + { + CVRMdaRecorder* iRecorderUtility = NULL; + if ( VRUtils::UnsupportedCallTypeOngoing( ETrue ) ) + { + return EFalse; + } + + //if ( iRecorder->RecordL() != KErrNone ) + // { + // return EFalse; + // } + + if(iCurrentCallHandler->StateL(KPSUidCtsyCallInformation,KCTsyCallState )==EPSCTsyCallStateConnected) + { + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility != NULL) + { + iRecorderUtility->SetAudioInputL(CAudioInput::EVoiceCall); + iRecorderUtility->ConfigSampleRateOfVoiceCallL(); + } + } + //Audioinput can't be changed after Record + if ( iRecorder->RecordL() != KErrNone ) + { + return EFalse; + } + break; + } + case EFunctionPause: + { + + iRecorder->Pause(); + // Turn off the IHF after playing + SetIHFIfCallNotActive( EFalse ); + break; + } + case EFunctionForward: + { + TInt result = iRecorder->ForwardL(); + + // The volume setting is lost when the media server client object + // is stopped. + SetRecorderVolume(); + + if ( result ) + { + return EFalse; + } + break; + } + case EFunctionRewind: + { + iRecorder->RewindL(); + if ( iButtonPanelObserver ) + { + iButtonPanelObserver->Update(); + } + + // The volume setting is lost when the media server client object + // is stopped + SetRecorderVolume(); + break; + } + case EFunctionRecordNew: + { + CVRMdaRecorder* iRecorderUtility = NULL; + if ( VRUtils::UnsupportedCallTypeOngoing( ETrue ) ) + { + return EFalse; + } + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility == NULL) + { + return EFalse; + } + iRecorderUtility->SetInRecordingFlag(ETrue); + + iCanHandleCommands = EFalse; + // Don't accept CBA commands + iCBAEnabled = EFalse; + // Update CBAs + iDecoratorObserver->Update( EVRUpdateCBA ); + + iRecorder->DetachMemo(); + + TRAPD( leaveErr1, SetMemoNameNewL( + iContext == EContextRecordNewForRemote ) ); + + // Can't attach if memo name couldn't be generated + TInt leaveErr2( KErrNone ); + if( !leaveErr1 ) + { + TRAP( leaveErr2, iRecorder->AttachToMemoL( iMemo ) ); + } + + TBool ifAttach = iRecorderUtility->IsAttachedToMemo(); + + if ( leaveErr1 || leaveErr2 || !ifAttach) + { + iCanHandleCommands = ETrue; + iCBAEnabled = ETrue; + if ( leaveErr1 == KErrDiskFull || leaveErr2 == KErrDiskFull ) + { + if ( iMemo->StorageDrive() == VRUtils::GetRemovableMassStorageL()) + { + VRUtils::ShowMemoryFullConfirmationQuery(ETrue); + } + else + { + VRUtils::ShowMemoryFullConfirmationQuery(); + } + } + } + + User::LeaveIfError( leaveErr1 ); + User::LeaveIfError( leaveErr2 ); + if(!ifAttach) + { + User::Leave(KErrNotReady); + } + + // Indicates that a new memo is attached but not yet recording + // started -> handle can be reused and memo can be deleted in exit + iMemo->SetRecorded( EFalse ); + + TInt recError( KErrNone ); + + //TRAPD( recLeaveErr, recError = iRecorder->RecordL() ); + if(iCurrentCallHandler->StateL(KPSUidCtsyCallInformation,KCTsyCallState )==EPSCTsyCallStateConnected) + { + iRecorderUtility->SetAudioInputL(CAudioInput::EVoiceCall); + iRecorderUtility->ConfigSampleRateOfVoiceCallL(); + } + //Change for CS call:Audio input can't be changed after Record + TRAPD( recLeaveErr, recError = iRecorder->RecordL() ); + + if (GetInRecordingFlag()) + { + iRecorderUtility->SetInRecordingFlag(EFalse); + } + + if ( recError != KErrNone || recLeaveErr ) + { + iCanHandleCommands = ETrue; + iCBAEnabled = ETrue; + if ( recLeaveErr ) + { + User::LeaveIfError( recLeaveErr ); + } + else + { + return EFalse; + } + } + + + iCanHandleCommands = ETrue; + // Accept CBAs again. CBAs are updated when state is changed + iCBAEnabled = ETrue; + break; + } + case EFunctionDelete: + { + iRecorder->DetachMemo(); + // Detaching resets the clip position so button panel + // needs to be updated + iButtonPanelObserver->Update( EVRUpdatePositionChange ); + if ( !iMemo->QueryAndDeleteL() ) + { + iRecorder->AttachToMemoL( iMemo ); + return EFalse; + } + break; + } + case EFunctionRename: + { + iRecorder->DetachMemo(); + // Detaching resets the clip position so button panel + // needs to be updated + iButtonPanelObserver->Update( EVRUpdatePositionChange ); + if ( iMemo->QueryAndRenameL() ) + { + if ( iStateInfoObserver ) + { + iStateInfoObserver->Update(); + } + } + iRecorder->AttachToMemoL( iMemo ); + break; + } + case EFunctionOk: + { + + HBufC* label = StringLoader::LoadLC( R_VR_SAVE_WAITNOTE_LABEL ); + + iRecorder->DetachMemo(); + iIsNoteLaunched = ETrue; + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, *label ); + + CEikonEnv::Static()->EikAppUi()->HandleCommandL( + ECmdEmbeddedRecordingReady ); + + iGlobalNote->CancelNoteL( iNoteId ); + iIsNoteLaunched = EFalse; +#ifdef _DEBUG + RDebug::Print( _L( + "VoiceRecorder: CVRRecViewModel Note cancelled" ) ); +#endif + CleanupStack::PopAndDestroy( label ); + + HandleCommandL( EEikCmdExit ); + break; + } + case EFunctionCancel: + { + iRecorder->DetachMemo(); + iMemo->DeleteL(); + HandleCommandL( EEikCmdExit ); + break; + } + case EFunctionNop: + { + // dummy command, do nothing + break; + } + case EFunctionNRTStop: + { + // Turn off the IHF after playing + SetIHFIfCallNotActive( EFalse ); + + iRecorder->Stop(); + CheckIhfState(); + break; + } + case EFunctionNRTAutoStop: + { + // Turn off the IHF after playing + SetIHFIfCallNotActive( EFalse ); + CheckIhfState(); + break; + } + case EFunctionSetNewPosition: + { + TInt newValue( 0 ); + if ( iStateInfoPanelObserver ) + { + newValue = iStateInfoPanelObserver->ProgressBarPosition(); + } + + iRecorder->SetPositionL( newValue ); + + //Inform button Panel + if ( iButtonPanelObserver ) + { + iButtonPanelObserver->Update( EVRUpdateStateChange ); + } + break; + } + default: + { + User::Panic( KVRPanic, EPanicFunctionUnknown ); + break; + } + } + return ETrue; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::StopAndSaveL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::StopAndSaveL( TInt aResourceId ) + { + HBufC* label = NULL; + + // Don't show the note if aResourceId was not defined + if ( aResourceId ) + { + label = StringLoader::LoadLC( aResourceId ); + } + + iRecorder->DetachMemo(); + + if ( label ) + { + iIsNoteLaunched = ETrue; + if(iMemo) + { + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, *label ); + } + + // There is no more note showing in SavePermanentlyL() -function + // the note is shown here + ShowNoteL( aResourceId, EAknGlobalInformationNote ); + } + else + { + iIsNoteLaunched = ETrue; + if(iMemo) + { + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, KNullDesC ); + } + } + + TRAP_IGNORE(iRecorder->AttachToMemoL( iMemo )); + + iGlobalNote->CancelNoteL( iNoteId ); + iIsNoteLaunched = EFalse; + + if ( aResourceId ) + { + CleanupStack::PopAndDestroy( label ); + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::StopAndCloseL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::StopAndCloseL( TInt aResourceId ) + { + HBufC* label = NULL; + + // Don't show the note if aResourceId was not defined + if ( aResourceId ) + { + label = StringLoader::LoadLC( aResourceId ); + } + + iRecorder->DetachMemo(); + + if ( label ) + { + iIsNoteLaunched = ETrue; + if(iMemo) + { + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, *label ); + } + } + else + { + iIsNoteLaunched = ETrue; + if(iMemo) + { + iMemo->SavePermanentlyL( iGlobalNote, iNoteId, KNullDesC ); + } + } + + iGlobalNote->CancelNoteL( iNoteId ); + iIsNoteLaunched = EFalse; + + if ( aResourceId ) + { + CleanupStack::PopAndDestroy( label ); + } + } + +void CVRRecViewModel::ShowNoteL( TInt aResourceId, + TAknGlobalNoteType aNoteType ) + { + HBufC* label = StringLoader::LoadLC( aResourceId ); + iGlobalNote->ShowNoteL( aNoteType, *label ); + CleanupStack::PopAndDestroy( label ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetVolumeControlState +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::GetVolumeControlState( TVRVolumeControlState& aState, + TInt& aVolume ) + { + // ignored + TRAP_IGNORE( ReadDefaultSpeakerL() ); + if ( iState->iHasVolumeControl ) + { + if ( iIhfState ) + { + aState = EIhf; + + } + else + { + aState = EEarPiece; + } + aVolume = iIhfVolume; + } + else + { + aState = EDisabled; + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::LoadVolumeSettingsL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::LoadVolumeSettingsL() + { + iIhfVolume = VRUtils::DefaultVolumeL( ESpeakerIhf ); + // Prevent using incorrect values + if ( iIhfVolume < KVRVolumeControlMin || + iIhfVolume > KVRVolumeControlMax ) + { + iIhfVolume = KVRDefaultVolume; + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SaveVolumeSettings +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SaveVolumeSettings() + { + // Ignore all errors, because this will be called in destructor. It isn't + // disastrous if new values aren't saved, the previous values will be there + TRAP_IGNORE( VRUtils::SetDefaultVolumeL( ESpeakerIhf, iIhfVolume ); ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HandleSystemEventL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::HandleSystemEventL() + { + // Fetch the changed value from Pubsub + TInt currentState( iCurrentCallHandler->StateL(KPSUidCtsyCallInformation, KCTsyCallState ) ); + + if ( !iActive ) + { + iPreviousCallState = currentState; + return; + } + + + // Actions to take when playing + if ( iState->iId == EStatePlaying ) + { + switch ( currentState ) + { + case EPSCTsyCallStateAlerting: + case EPSCTsyCallStateRinging: + case EPSCTsyCallStateAnswering: + { + HandleCommandL( ECmdAutoStopAtEnd ); + break; + } + default: + { + break; + } + } + } + + // Actions to take when recording + if ( iState->iId == EStateRecording ) + { + switch ( currentState ) + { + case EPSCTsyCallStateAlerting: + case EPSCTsyCallStateRinging: + case EPSCTsyCallStateAnswering: + case EPSCTsyCallStateDisconnecting: + { + HandleCommandL( ECmdAutoStopAtEnd ); + break; + } + case EPSCTsyCallStateNone: + { + if( iPreviousCallState == EPSCTsyCallStateConnected ) + { + CVRMdaRecorder* iRecorderUtility = NULL; + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility != NULL) + { + iRecorderUtility->SetAudioInputL(CAudioInput::EDefaultMic); + } + HandleCommandL( ECmdAutoStopAtEnd ); + } + break; + } + default: + { + break; + } + } + } + + if ( iState->iId == EStateIdle && + currentState == EPSCTsyCallStateNone ) + { + iIhfState = ETrue; + } + + /* ------------------------- + * Disable in-call recording + * ------------------------- + */ + if ( iVRAllowInCallRecording != KAllowInCallRecording ) + { + if (( iState->iId == EStateIdle || iState->iId == EStateDeleted ) && + currentState == EPSCTsyCallStateAnswering) + { + // Disable record button + ChangeState( EStateDisableButtons, ETrue ); + } + if (( iState->iId == EStateDisableButtons ) && + ((currentState == EPSCTsyCallStateDisconnecting)|| (currentState == EPSCTsyCallStateNone))) + { + if (iContext != EContextRecordNewForRemote) + { + // Enable record button + ChangeState( EStateDeleted, ETrue ); + } + else + { + if (!(iMemo->Duration() > TTimeIntervalMicroSeconds(0))) + { + ChangeState( EStateRecordEmbedded, ETrue ); + } + else + { + ChangeState( EStateIdleRecordEmbedded, ETrue ); + } + } + } + } + + iPreviousCallState = currentState; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetIHFIfCallNotActive +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetIHFIfCallNotActive( TBool aIhf ) + { + if ( FeatureManager::FeatureSupported( + KFeatureIdApplicationControllableAudioRouting ) ) + { + TInt currentState( EPSCTsyCallStateNone ); + // Ignore the error, ihf is not set + TRAP_IGNORE( currentState = iCurrentCallHandler->StateL( + KPSUidCtsyCallInformation, KCTsyCallState ) ); + + if ( currentState == EPSCTsyCallStateNone ) + { + if ( iRecorder->SetIhf( aIhf ) == KErrNone ) + { + // So that the model knows that the next notify from shared + // data client is not a voice key activated IHF change. + iIgnoreNextIhfChange = ETrue; + } + } + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CheckIhfState +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::CheckIhfState() + { + if ( FeatureManager::FeatureSupported( KFeatureIdKeypadNoVoiceKey ) && + FeatureManager::FeatureSupported( + KFeatureIdApplicationControllableAudioRouting ) ) + { + if ( iDefaultSpeaker == ESpeakerIhf ) + { + iIhfState = ETrue; + } + else + { + iIhfState = EFalse; + } + } + else + { + // IHF is default on phones with voice key + iIhfState = ETrue; + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetRecorderVolume +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetRecorderVolume() + { + TInt activeVolume = iIhfVolume; + iRecorder->SetVolume( activeVolume, KVRMaxVolumeSteps ); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ActivateL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::ActivateL() + { + iActive = ETrue; + + if ( FeatureManager::FeatureSupported( KFeatureIdKeypadNoVoiceKey ) && + FeatureManager::FeatureSupported( + KFeatureIdApplicationControllableAudioRouting ) ) + { + // The user has visited another view and possibly altered the + // settings + ReadDefaultSpeakerL(); + } + + // If the in-call disable recording feature has been enabled, then check + // current status and enable/disable UI accordingly + if ( iVRAllowInCallRecording != KAllowInCallRecording ) + { + TInt currentState( iCurrentCallHandler->StateL( + KPSUidCtsyCallInformation, KCTsyCallState ) ); + if ( currentState != EPSCTsyCallStateNone ) + { + ChangeState (EStateDisableButtons, ETrue); + } + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::Deactivate +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::Deactivate() + { + iActive = EFalse; + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::ReadDefaultSpeakerL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::ReadDefaultSpeakerL() + { + iDefaultSpeaker = VRUtils::DefaultSpeakerL(); + + if ( iDefaultSpeaker == ESpeakerIhf ) + { + iIhfState = ETrue; + } + else + { + iIhfState = EFalse; + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::TVRLabelLayoutLink::ReadFromResource +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::TVRLabelLayoutLink::ReadFromResource + ( TResourceReader& aReader ) + { + iEuroId = aReader.ReadUint32(); + iApacId = aReader.ReadUint32(); + iArabicHebrewId = aReader.ReadUint32(); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::CanSetVolume +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::CanSetVolume() + { + return ETrue; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HandleUpdateErrorL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::HandleUpdateErrorL( TInt aErr ) + { + // Show error note. + if ( aErr == KErrDiskFull ) + { + +#ifndef RD_MULTIPLE_DRIVE + if ( VRUtils::MemoStoreL() == EMemoStorePhoneMemory ) + { + ShowNoteL( R_VR_MEMORY_WARNING, EAknGlobalWarningNote ); + } + else + { + ShowNoteL( R_VR_MEMORY_MMC_WARNING, EAknGlobalWarningNote ); + } + +//multiple drive +#else + TInt memoDrive = VRUtils::MemoDriveL(); + TUint status( 0 ); + VRUtils::GetDriveInfo( memoDrive, status ); + + if ( status & DriveInfo::EDriveInternal ) + { + ShowNoteL( R_VR_MEMORY_WARNING, EAknGlobalWarningNote ); + } + else + { + ShowNoteL( R_VR_MEMORY_MMC_WARNING, EAknGlobalWarningNote ); + } +#endif + + + } + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::MemoFileHandle +// +// --------------------------------------------------------------------------- +// +RFile& CVRRecViewModel::MemoFileHandle() + { + return iMemo->File(); + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetFileHandle +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetFileHandle( RFile& aFile ) + { + // Use app startup type as embbedding flag + iMemo->SetFileHandle( aFile, CEikonEnv::Static()->StartedAsServerApp() ); + if ( iRecorder ) + { + // First detach if already attached + iRecorder->DetachMemo(); + // The media server error will rise again somewhere where it's + // easier to handle if needed + TRAP_IGNORE( iRecorder->AttachToMemoL( iMemo ) ); + } + + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::FormatTimeL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::FormatTimeL( const TTime& aTime, TDes& aString ) const + { + + // Show longer format if duration more than 1 hour + if ( aTime.DateTime().Hour() >= 1 ) + { + aTime.FormatL( aString, + iTimeDuratLong ); + } + else + { + aTime.FormatL( aString, + iTimeDuratMinSecWithZero ); + } + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::EnableVolumeControl +// Enables/Disables the navi pane Volume Control drawing in the VR current +// visual state +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::EnableVolumeControl( TBool aVolumeControl ) + { + iState->iHasVolumeControl = aVolumeControl; + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HasVolumeControl +// Returns ETrue if volume setting is enabled in this VoiceRecorder state. +// Otherwise returns EFalse +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::HasVolumeControl() const + { + if( iState->iHasVolumeControl ) + { + return ETrue; + } + return EFalse; + } + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::IncomingCall +// Returns ETrue if a phone call is coming. +// Otherwise returns EFalse +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::IncomingCall() const + { +#ifdef _DEBUG + RDebug::Print( _L("CVRRecViewModel::IncomingCall enter") ); +#endif + + // Fetch the current value from Pubsub + TInt currentState = 0; + TRAP_IGNORE(currentState = iCurrentCallHandler->StateL( KPSUidCtsyCallInformation, KCTsyCallState )); + + if (currentState == EPSCTsyCallStateAlerting || + currentState == EPSCTsyCallStateRinging || + currentState == EPSCTsyCallStateAnswering ) + { + return ETrue; + } + else + { + return EFalse; + } + } + + +// --------------------------------------------------------------------------- +//Returns the active quality setting. +//return Quality setting of the active memo +// --------------------------------------------------------------------------- +TVRQuality CVRRecViewModel::Quality() const + { + return iMemo->Quality(); + } + + +// --------------------------------------------------------- +// GetInRecordingFlag +// +// --------------------------------------------------------- +// +TBool CVRRecViewModel::GetInRecordingFlag() + { + if(iRecorder) + { + CVRMdaRecorder* iRecorderUtility = NULL; + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility != NULL) + { + return iRecorderUtility->GetInRecordingFlag(); + } + return EFalse; + } + else + { + return EFalse; + } + + } + + +// --------------------------------------------------------- +// GetIfStopCalled +// +// --------------------------------------------------------- +// +TBool CVRRecViewModel::GetIfStopCalled() + { + if(iRecorder) + { + CVRMdaRecorder* iRecorderUtility = NULL; + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility != NULL) + { + return iRecorderUtility->GetIfStopCalled(); + } + return EFalse; + } + else + { + return EFalse; + } + + } + + +// --------------------------------------------------------- +// SetInRecordingFlag +// --------------------------------------------------------- +// +void CVRRecViewModel::SetInRecordingFlag(TBool aFlag) + { + if(iRecorder) + { + CVRMdaRecorder* iRecorderUtility = NULL; + iRecorderUtility = dynamic_cast(iRecorder); + if(iRecorderUtility != NULL) + { + return iRecorderUtility->SetInRecordingFlag(aFlag); + } + } + } + + + + +// --------------------------------------------------------------------------- +// CVRRecViewModel::HandleMMCEjectEventL +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::HandleMMCEjectEventL() + { + + // Actions to take when recording + TInt storageDrive = VRUtils::MemoDriveL(); + if ( ( ( storageDrive == VRUtils::GetRemovableMassStorageL()) || + ( iMemo != NULL && iMemo->StorageDrive() == VRUtils::GetRemovableMassStorageL() ) ) && + ( !CVRUSBStateHanlder::IsUsbActive() ) ) + { + //exit for mmc dismount + SendExitEvent(); + } + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SendExitEvent +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SendExitEvent() + { + TWsEvent event; + event.SetType( EAknSoftkeyExit ); + event.SetTimeNow(); + event.SetHandle( CCoeEnv::Static()->WsSession().WsHandle() ); + CCoeEnv::Static()->WsSession().SendEventToWindowGroup( CEikonEnv::Static()->RootWin().Identifier(), event ); + return; + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::SetIsDriveReady +// +// --------------------------------------------------------------------------- +// +void CVRRecViewModel::SetIsDriveReady(TBool aIsDriveReady) + { + iIsDriveReady = aIsDriveReady; + } + +// --------------------------------------------------------------------------- +// CVRRecViewModel::GetIsDriveReady +// +// --------------------------------------------------------------------------- +// +TBool CVRRecViewModel::GetIsDriveReady() + { + return iIsDriveReady; + } + + +// End of file