diff -r ebe688cedc25 -r 7fdbb852d323 mobilemessaging/mmsui/viewersrc/UniMmsViewerAppUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobilemessaging/mmsui/viewersrc/UniMmsViewerAppUi.cpp Wed Sep 01 12:31:54 2010 +0100 @@ -0,0 +1,5600 @@ +/* +* Copyright (c) 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: +* Provides CMmsViewerAppUi class methods. +* +*/ + + + +// INCLUDE FILES + +#include + +#include // EStdKey* + +#include // CEikMenuPane +#include // CEikMenuBar +#include +#include // CMsgBodyControl +#include // CMsgEditorView +#include // Base editor commands & enums +#include +#include +#include // bitmap identifiers +#include // resouce identifiers +#include +#include + +#include // CApaWindowGroupName + +#include +#include +#include +#include //Folder Selection dialog +#include +#include + +#include // CMuiuOperationWait +#include +#include // CAknInputBlock +#include + +#include +#include // R_AVKON_SOFTKEYS_OPTIONS_BACK, R_AVKON_NAVI_PANE_VOLUME_INDICATOR +#include // CAknNavigationDecorator +#include // CAknTitlePane +#include // CAknVolumeControl +#include +#include +#include +#include // CAknSinglePopupMenuStyleListBox +#include // +#include // CAknTabGroup +#include // CAknLocalScreenClearer +#include +#include +#include + +#include // CAiwGenericParamList + +#include +#include + +#include // KNullContactId + +#include +#include +#include +#include +#include +#include // silence mode status check +#include // KCRUidRichCallSettings +#include + +#include // silence mode status check + +#include // CDocumentHandler +#include // CommonPhoneParser + +#include // Find item stuff +#include // +#include // +#include // +#include // + +#include // StringLoader +#include // Default error notes + +#include // Character sets + +#include // KErrExtended, KLeaveExit + +#include +#include +#include +#include + +#include // Message entries +#include // MsvOperation +#include // CMsvStore +#include // function id of MessageInfo + +#include +#include // SendUI (for Reply via SMS) +#include // MTM Uids +#include + +#include +#include +#include // CNotePadApi + +// DRM +#include + +// SMIL Player +#include + +// Features +#include +#include + +// Help +#include +#include // For HlpLauncher + +#include "MmsMtmUi.h" // Mms Mtm Ui + +#include "MsgAttachmentUtils.h" // enumerations for objects view + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef RD_SVGT_IN_MESSAGING +#include +#endif +#include // CUniDataModel +#include // CUniSmilModel +#include // enumerations +#include +#include + +#include + +#include // Common objects view implementation +#include // Model part of the objects view +#include +#include +#include + +#include // CMmsClientMtm, mmsconst.h +#include +#include +#include + +#include "MmsViewer.hrh" // application specific commands & enums +#include "UniMmsViewerDocument.h" // CMmsViewerDocument +#include "UniMmsViewerAppUi.h" // CMmsViewerAppUi +#include "MmsViewerHeader.h" +#include "MmsViewerLaunchOperation.h" +#include "MmsViewerChangeSlideOperation.h" +#include "MmsViewerSendReadReportOperation.h" + +#include "MmsMtmConst.h" // File logger +#include + +#ifdef RD_SCALABLE_UI_V2 +#include // pen support on navi pane +#include // pen support of volume control of navi pane +#endif +#include +#include // for iMsgEditorAppUiExtension +#include +#include +#include +#include +// CONSTANTS + +// following is minimum value for player +const TInt KVolumeControlMinValuePlayer = 0; +// following are minimum values for avkon volume indicator component +const TInt KVolumeControlMinValue = 0; //from "AKNVOLUMECONTROL.CPP" +const TInt KVolumeControlMaxValue = 10; //from "AKNVOLUMECONTROL.CPP" +const TInt KVolumeDefault = 8; +const TInt KVolumeLevels = 10; +const TInt KMmsSizeWaitDialogDisabled = 204800; + +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +const TUint KNaviGranularity = 2; +const TInt KIconDefaultColor = 0; +#endif +_LIT( KMmsUiMbmFile, "mmsui.mbm" ); + +const TInt KReplyToSenderSize = 2048; +const TInt KReplyToAllSize = 2048; +const TMsvId KNewMessageFolder = KMsvDraftEntryIdValue; +const TInt KInvalidResourceId = -1; + +// Fast swap window group +#define KFastSwapAppUid TUid::Uid( 0x10207218 ) +#define KAknNotifyServerAppUid TUid::Uid( 0x10281ef2 ) +#define KScreenSaverAppUid TUid::Uid( 0x100056CF ) + +_LIT( KMmsViewerSpace, " " ); + +const TUid KNotepadUID3 = { KTextHandler }; // Notepad viever + +// Exiting in launch. Let this time to show error notes +//const TInt KDelayedExitShort = 100000; + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------- +// +CMmsViewerAppUi::CMmsViewerAppUi( ) : + iPendingNoteResource( KInvalidResourceId ), + iViewerFlags( EInitialFlags ), + iViewerState( ENormal ) + { + LOGTIMESTAMP("CMmsViewerAppUi::CMmsViewerAppUi "); + } + +// --------------------------------------------------------- +// Symbian OS default constructor can leave. +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ConstructL( ) + { + CMsgEditorAppUi::ConstructL( ); + + // Disable task swapper from options menu during launch + MenuBar()->SetMenuType( CEikMenuBar::EMenuOptionsNoTaskSwapper ); + + LOGTEXT(_L8("CMmsViewerAppUi::ConstructL starting") ); + FeatureManager::InitializeLibL( ); + if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + iSupportedFeatures |= EMmsFeatureHelp; + } + if ( FeatureManager::FeatureSupported( KFeatureIdDrmFull ) ) + { + iSupportedFeatures |= EMmsFeatureDrmFull; + } + if ( FeatureManager::FeatureSupported( KFeatureIdSideVolumeKeys ) ) + { + iSupportedFeatures |= EMmsFeatureSVK; + } + if ( FeatureManager::FeatureSupported( KFeatureIdSenduiMmsUpload ) ) + { + iSupportedFeatures |= EMmsFeatureUpload; + } + if ( FeatureManager::FeatureSupported( KFeatureIdAudioMessaging ) ) + { + iSupportedFeatures |= EMmsFeatureAudioMessaging; + } + FeatureManager::UnInitializeLib( ); + +#ifdef RD_SCALABLE_UI_V2 + // Creation of CMsgEditorView must be after toolbar is set visible otherwise layout things can go wrong. + // Toolbar itself seems to set itself invisible temporary at some startup time. Toolbar is set visible here, too. + if ( AknLayoutUtils::PenEnabled() ) + { + iToolbar = CurrentFixedToolbar(); + if ( iToolbar ) + { + iToolbar->SetToolbarObserver( this ); + iToolbar->SetToolbarVisibility( ETrue, EFalse ); + } + } +#endif + + iView = CMsgEditorView::NewL( *this, + CMsgEditorView::EMsgReadOnly | + CMsgEditorView::EMsgDoNotUseDefaultBodyControl ); + + iMtm = &(Document( )->Mtm( )); + iNaviPane = static_cast + ( StatusPane( )->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + iTitlePane = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) ); + iButtonGroup = Cba( ); + iSvkEvents = CMmsSvkEvents::NewL( *this ); + + if ( !iButtonGroup || !iNaviPane || !iMtm ) + { + User::Leave( KErrBadHandle ); + } + + TInt highlight = 0; + TInt drmPlayback = 0; + // Volume level storage + iMmsRepository = CRepository::NewL( KCRUidMmsui ); + + // Automatic highlight setting storage and change notifications + iCUiRepository = CRepository::NewL( KCRUidCommonUi ); + iCUiRepository->Get( KCuiAutomaticHighlight, highlight ); + iNotifyHandler = CCenRepNotifyHandler::NewL( *this, + *iCUiRepository, + CCenRepNotifyHandler::EIntKey, + KCuiAutomaticHighlight ); + iNotifyHandler->StartListeningL( ); + + CRepository* repository = CRepository::NewLC( KCRUidMusicPlayerFeatures ); + repository->Get( KRequireDRMInPlayback, drmPlayback ); + + if ( drmPlayback ) + { + TBuf<1> tmp; // Magic: 1 char to get length of actual value + TInt realLen = 0; + TInt err = repository->Get( KPlaybackRestrictedMimeTypes, + tmp, + realLen ); + + if ( err == KErrOverflow ) + { + // Prepare list of blocked MIME types + iProhibitMimeTypeBuffer = HBufC::NewL( realLen + KMmsViewerSpace().Length() ); + TPtr bufferPtr = iProhibitMimeTypeBuffer->Des(); + + User::LeaveIfError( repository->Get( KPlaybackRestrictedMimeTypes, bufferPtr ) ); + bufferPtr.Append( KMmsViewerSpace ); + } + else + { + User::LeaveIfError( err ); + } + } + + CleanupStack::PopAndDestroy( repository ); + repository = NULL; + + TInt features(0); + repository = CRepository::NewL( KCRUidMuiuVariation ); + + repository->Get( KMuiuMmsFeatures, features ); + if ( features & KMmsFeatureIdDeliveryStatusDialog ) + { + iSupportedFeatures |= EMmsFeatureDeliveryStatus; + } + + repository->Get( KMuiuUniEditorFeatures, features ); + if ( features & KUniEditorFeatureIdRestrictedReplyMms ) + { + iSupportedFeatures |= EMmsFeatureRestrictedReply; + } + delete repository; + + repository = CRepository::NewL( KCRUidUniEditor ); + repository->Get( KUniEditorMaxSlideCount, iMaxForwardSlideCount ); + delete repository; + + // Set up highlighting + if ( highlight == 0 ) + { + iViewerFlags &= ~EAutohighLightEnabled; + } + else + { + iViewerFlags |= EAutohighLightEnabled; + } + + if ( drmPlayback ) + { + iViewerFlags |= EProhibitNonDrmMusic; + } + + if ( Document( )->CreationMode( ) == EMmsCreationModeWarning ) + { + iViewerFlags |= EShowGuidedConf; + } + + iMmsConformance = CMmsConformance::NewL( ); + + // Set path of bitmap file + TParse fileParse; + fileParse.Set( KMmsUiMbmFile, &KDC_APP_BITMAP_DIR, NULL ); + + iAppIcon = AknsUtils::CreateGulIconL( + AknsUtils::SkinInstance(), + KAknsIIDQgnPropMceMmsTitle, + fileParse.FullName(), + EMbmMmsuiQgn_prop_mce_mms_title, + EMbmMmsuiQgn_prop_mce_mms_title_mask ); + + // Get important window group ids + GetNonStoppingWgIds( ); + + // Priority must be lower than the priority of iWrappedWaitDialog + // Constructed here to ensure exit on low memory situations. + iIdle = CPeriodic::NewL( EPriorityNormal - 1); + + if( !iEikonEnv->StartedAsServerApp( ) ) + { + Document( )->PrepareToLaunchL( this ); + } + LOGTEXT2(_L16("CMmsViewerAppUi::ConstructL read. iSupportedFeatures 0x%x"), iSupportedFeatures ); + iLongTapDetector = CAknLongTapDetector::NewL( this ); + iLongTapDetector->SetTimeDelayBeforeAnimation( KUniLongTapStartDelay ); + iLongTapDetector->SetLongTapDelay( KUniLongTapTimeDelay ); + iTapConsumed = EFalse; + } + +// --------------------------------------------------------- +// Destructor +// --------------------------------------------------------- +// +CMmsViewerAppUi::~CMmsViewerAppUi( ) + { + LOGTEXT(_L8("CMmsViewerAppUi::~CMmsViewerAppUi starting") ); + iViewerFlags |= EViewerExiting; + iViewerState = EReseted; + EndActiveWait(); + // Input blocker is also deleted + DeactivateInputBlocker(); + if ( iNotifyHandler ) + { + iNotifyHandler->StopListening( ); + } + delete iNotifyHandler; + delete iCUiRepository; + delete iMmsRepository; + + //iMtm not owned - just a reference pointer + //iSmilModel not owned - just a reference pointer + //iNaviPane not owned - just a reference pointer + //iButtonGroup not owned - just a reference pointer + +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT + delete iNaviDecorator; +#endif + delete iVolumeDecorator; + delete iWaitDialog; + delete iFindItemMenu; + delete iDocHandler; + + delete iHeader; + delete iSlideLoader; + delete iLaunchOperation; + delete iChangeSlideOperation; + delete iScreenClearer; + iUploadServices.ResetAndDestroy( ); + delete iMmsVoIPExtension; + delete iSvkEvents; + delete iMmsConformance; + delete iTitleIcon; + + delete iProhibitMimeTypeBuffer; + delete iSendReadReportOperation; + delete iIdle; + delete iAppIcon; + if(iLongTapDetector) + { + delete iLongTapDetector; + } + if(iEmbeddedObjectStylusPopup) + { + delete iEmbeddedObjectStylusPopup; + iEmbeddedObjectStylusPopup = NULL; + } + + LOGTEXT(_L8("CMmsViewerAppUi::~CMmsViewerAppUi end") ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::Document +// --------------------------------------------------------- +// +CMmsViewerDocument* CMmsViewerAppUi::Document( ) const + { + return static_cast( CMsgEditorAppUi::Document( ) ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MsgSaveExitL +// framework function +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoMsgSaveExitL( ) + { + MediaStop( ); + iExitMode = MApaEmbeddedDocObserver::TExitMode(CMsgEmbeddedEditorWatchingOperation::EMsgExternalExit); + Exit( ); + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::LaunchViewL +// --------------------------------------------------------- +// + +void CMmsViewerAppUi::LaunchViewL( ) + { + __ASSERT_DEBUG( Document( )->Entry( ).Id( ) != KMsvNullIndexEntryId, Panic( EMmsViewerNoMessage ) ); + TBool exitViewer( EFalse ); + if ( iViewerFlags & EViewerExiting ) + { + exitViewer = ETrue; + } + else + { + TRAPD( error, DoLaunchViewL() ); + + if ( error != KErrNone ) + { + iEikonEnv->HandleError( error ); + exitViewer = ETrue; + } + } + + if ( exitViewer ) + { + // Start the delayed exit here if exit command was given before application was + // ready to handle it or error happened when performing lauch view. + // Delayed exit is used as LauchViewL cannot make proper exit if Exit() is called here. + DoDelayedExit( 0 ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoLaunchViewL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoLaunchViewL() + { + // Exiting here leaves incomplete mms viewer view visible + // Let the launch happen until ViewerOperationEvent() + TRAPD( error, iMtm->LoadMessageL( ) ); + LOGTEXT2(_L16("CMmsViewerAppUi::LaunchViewL error %d"), error ); + if ( error ) + { + if ( error != KErrNoMemory ) + { + ShowErrorNoteL( R_MMSVIEWER_ERROR_MSG_CORRUPT ); + } + User::Leave( error ); + } + + iViewerState = EBusy; + iOpeningState = EOpeningMessage; + + // Disabling Wait Dialog for messages less than 200kB + if ( iMtm->MessageSize() > KMmsSizeWaitDialogDisabled ) + { + LaunchWaitDialogL( 0 ); + } + + // iWaitDialog was deleted in case of error. Is this needed ? + iLaunchOperation = new ( ELeave ) CMmsViewerLaunchOperation( + this, + *this, + *this, + *Document( ), + *iView, + iCoeEnv->FsSession( ) ); + ActivateInputBlockerL( iLaunchOperation ); + iLaunchOperation ? iLaunchOperation->Launch( ) : User::Leave( KErrNoMemory ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ChangeSlideL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ChangeSlideL( TInt aSlideNumber, TBool aScreenClearer ) + { + if ( aSlideNumber < 0 || aSlideNumber >= iSmilModel->SlideCount( ) ) + { + User::Leave( KErrArgument ); + } + MediaStop( ); + + iViewerState = EBusy; + iOpeningState = EOpeningSlide; + iViewerFlags |= EVideoHasAudio; + iVideo = NULL; + iAudio = NULL; + iImage = NULL; +#ifdef RD_SVGT_IN_MESSAGING + iSvgt = NULL; +#endif + iPendingNoteResource = KInvalidResourceId; + iPendingNotePriority = 0; + iPendingNoteObject = NULL; + iPendingNoteError = KErrNone; + + // use case: + // precondition: text on two slide and from field empty on the emulator + // crash when: + // - goto slide 2 and take selection menu on text + // - goto slide 1 and take selection menu on from field (which is empty) => crash + // iFindItem contains 'deleted' objects + delete iFindItemMenu; + iFindItemMenu = NULL; + + UpdateMskL(); + + + if ( !iChangeSlideOperation ) + { + iChangeSlideOperation = new ( ELeave )CMmsViewerChangeSlideOperation ( + *this, + *( Document( ) ), + *iHeader, + *iSlideLoader, + *iView, + iCoeEnv->FsSession( ) ); + } + + iChangeSlideOperation ? iChangeSlideOperation->ChangeSlide( aSlideNumber ) : User::Leave( KErrNoMemory ); + + if ( aScreenClearer ) + { + iScreenClearer = CAknLocalScreenClearer::NewLC( EFalse ); + CleanupStack::Pop( iScreenClearer ); + iScreenClearer->SetExtent( iScreenClearer->Position(), ClientRect().Size() ); + } + + if ( aScreenClearer ) + { + LaunchWaitDialogL( aSlideNumber ); + } + ActivateInputBlockerL( iChangeSlideOperation ); + + // TODO: Get rid of active wait! + BeginActiveWait( iChangeSlideOperation ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::LaunchWaitDialogL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::LaunchWaitDialogL( TInt aParam ) + { + if ( iWaitDialog ) + { + delete iWaitDialog; + iWaitDialog = NULL; + } + + if ( iOpeningState == EOpeningMessage ) + { + iWaitDialog = new ( ELeave ) CAknWaitDialog( + ( reinterpret_cast( &iWaitDialog ) ), + ETrue ); + iWaitDialog->ExecuteLD( R_MMSVIEWER_WAIT_LOADING ); + } + else if ( iOpeningState == EOpeningSlide ) + { + iWaitDialog = new ( ELeave ) CAknWaitDialog( + ( reinterpret_cast( &iWaitDialog ) ), + EFalse ); + CArrayFixFlat* array = new ( ELeave ) CArrayFixFlat(2); + CleanupStack::PushL( array ); + array->AppendL( aParam + 1 ); + array->AppendL( iSmilModel->SlideCount( ) ); + HBufC* string = StringLoader::LoadLC( + R_MMSVIEWER_OPENING_PAGE, + *array, + iCoeEnv ); + iWaitDialog->SetTextL( *string ); + iWaitDialog->ExecuteLD( R_MMSVIEWER_WAIT_OPENING_PAGE ); + CleanupStack::PopAndDestroy( 2, array ); // + string + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::SetPendingNote +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SetPendingNote( TInt aResourceId, + CUniObject* aObject, + TInt aError ) + { + TInt priority = 0; + switch ( aResourceId ) + { + case R_MMSVIEWER_DRM_ERROR: + { + // do not show note during launch or slide change except for image + if ( !aObject + || !aObject->MediaInfo( ) + || ( ( iOpeningState == EOpeningMessage + || iOpeningState == EOpeningSlide ) + && aObject->MediaType( ) != EMsgMediaImage ) ) + { + return; + } + else if ( aObject->MediaType( ) == EMsgMediaImage +#ifdef RD_SVGT_IN_MESSAGING + || aObject->MediaType( ) == EMsgMediaSvg +#endif + ) + { + if ( aObject->DrmInfo( ) ) + { + TBool consumed = EFalse; + aObject->DrmInfo( )->EvaluateRights( consumed ); + if ( consumed ) + { + return; + } + } + else + { + // can't do anything without drm info + return; + } + } + priority = 5; + break; + } + case R_MMSVIEWER_DRM_PREVIEW_RIGHTS: + priority = 4; + break; + case R_MMSVIEWER_DRM_OBJECT_REMOVED: + if (!priority) + { + priority = 3; + } + break; + case R_MMSVIEWER_CANNOT_DISPLAY_OBJECTS: + { + + // during launch only + if ( iOpeningState != EOpeningMessage ) + { + return; + } + if (!priority) + { + priority = 2; + } + break; + } + case R_QTN_MMS_CANNOT_OPEN_CORRUPTED: + { + // during play only + if ( iOpeningState != EOpeningNone ) + { + return; + } + priority = 1; + break; + } + default: + break; + } + if ( priority > iPendingNotePriority ) + { + iPendingNotePriority = priority; + iPendingNoteResource = aResourceId; + iPendingNoteObject = aObject; + iPendingNoteError = aError; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowPendingNoteL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ShowPendingNoteL( ) + { + // show note only once and after every control has been initialised + // in order to show the highest priority note + if ( !AreControlsReadyAndWaitNoteDismissedL() ) + { + return; + } + + iOpeningState = EOpeningNone; + + // It may occur that this code point is entered twice when control state changes take place + // Temp variable is second action to avoid it. Resetting iPending* variables earlier in ReloadControlL + // and ChangeSlide is first one + TInt pendingNoteResource = iPendingNoteResource; + iPendingNoteResource = KInvalidResourceId; + switch ( pendingNoteResource ) + { + case R_MMSVIEWER_DRM_ERROR: + { + if ( iPendingNoteObject + && iPendingNoteObject->DrmInfo( ) ) + { + TRAP_IGNORE( iPendingNoteObject->DrmInfo( )->HandleDrmErrorL( iPendingNoteError ) ); + } + break; + } + case R_MMSVIEWER_DRM_PREVIEW_RIGHTS: + case R_MMSVIEWER_DRM_OBJECT_REMOVED: + case R_MMSVIEWER_CANNOT_DISPLAY_OBJECTS: + case R_QTN_MMS_CANNOT_OPEN_CORRUPTED: + { + ShowInformationNoteL( pendingNoteResource ); + } + break; + case KInvalidResourceId: + default: + break; + } + iPendingNotePriority = 0; + iPendingNoteObject = NULL; + iPendingNoteError = KErrNone; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::InitNavipaneL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::InitNavipaneL( ) + { +#ifdef RD_MSG_NAVIPANE_IMPROVEMENT + if ( !iNaviDecorator ) + { + TMsgEditorMsgPriority priority = EMsgEditorMsgPriorityNormal; + + if ( iMtm->MessagePriority() == EMmsPriorityHigh ) + { + priority = EMsgEditorMsgPriorityHigh; + } + else if ( iMtm->MessagePriority() == EMmsPriorityLow ) + { + priority = EMsgEditorMsgPriorityLow; + } + + CreateViewerNaviPaneL( Document()->Entry().iDate, priority, ETrue ); + } + + if ( MediaIsRunning( iAudio ) || + MediaIsRunning( iVideo ) ) + { + iNaviPane->PushL( *iVolumeDecorator ); + } + else + { + iNaviPane->PushL( *iNaviDecorator ); + } +#else + TInt indexInFolder = 0; + TInt msgsInFolder = 0; + MessageIndexInFolderL( indexInFolder, msgsInFolder ); + + if ( indexInFolder < 0 + || msgsInFolder == 0 ) + { + // this may occur when viewer is used in cover ui. Viewer is started as + // stand alone without current folder and '1/0' would be visible. + iNaviPane->PushDefaultL( ); + return; + } + + CArrayFixFlat* array = new ( ELeave ) CArrayFixFlat(KNaviGranularity); + CleanupStack::PushL( array ); + array->AppendL( indexInFolder + 1 ); + array->AppendL( msgsInFolder ); + + HBufC* buf = StringLoader::LoadLC( R_MMSVIEWER_ORDINAL_NUMBER, *array, iCoeEnv ); + //Pushed into CleanupStack + + //Creates iNaviDecorator + CreateTabGroupL( *buf ); + CleanupStack::PopAndDestroy( 2, array ); // + buf + + iNaviDecorator->MakeScrollButtonVisible( ETrue ); + + //NaviButtons are dimmed by default + if ( IsNextMessageAvailableL( ETrue ) ) + { + iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, EFalse ); + } + if ( IsNextMessageAvailableL( EFalse ) ) + { + iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, EFalse ); + } + + if ( !MediaIsRunning( iAudio ) + && !MediaIsRunning( iVideo ) ) + { + iNaviPane->PushL( *iNaviDecorator ); + } +#endif + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::UpdatePanesL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::UpdatePanesL( TBool aAudioPlaying, TBool aVideoPlaying ) + { + if ( aAudioPlaying || aVideoPlaying ) + { + // Silent mode is handled in DoChangeVolumeL + TInt newVolume = DoChangeVolumeL( 0, ETrue, aAudioPlaying ); + if ( newVolume >= KVolumeControlMinValue ) + { + // Show the volume + ShowVolumeL( newVolume, aAudioPlaying ); + } + if ( aAudioPlaying ) + { + iButtonGroup->SetCommandSetL( R_MMSVIEWER_SOFTKEYS_EMPTY_STOP ); + } + else if ( aVideoPlaying ) + { + iButtonGroup->SetCommandSetL( R_MMSVIEWER_SOFTKEYS_EMPTY_STOPVIDEO ); + } + else + { + iButtonGroup->SetCommandSetL( R_MMSVIEWER_SOFTKEYS_OPTIONS_BACK_EMPTY ); + } + + if ( iNaviDecorator + && iNaviPane->Top( ) == iNaviDecorator ) + { + // Silent mode is ON or video has not audio + // Hide navi pane during playback + iNaviPane->PushDefaultL( ); + } + } + else + { + iButtonGroup->SetCommandSetL( R_MMSVIEWER_SOFTKEYS_OPTIONS_BACK_EMPTY ); + if ( iNaviDecorator ) + { + iNaviPane->PushL( *iNaviDecorator ); + } + else + { + iNaviPane->PushDefaultL( ); + } + } + // forces to update MSK, which was overridden here + iMskId = 0; + iButtonGroup->DrawNow( ); +#ifdef RD_SCALABLE_UI_V2 + SetToolBarItemVisibilities(); +#endif + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::CreateTabGroupL +// --------------------------------------------------------- +// +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +void CMmsViewerAppUi::CreateTabGroupL( const TDesC& aText ) + { + if ( !iNaviDecorator ) + { + // Create TabGroup + iNaviDecorator = iNaviPane->CreateTabGroupL(); + } + +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + iNaviDecorator->SetNaviDecoratorObserver( this ); + } +#endif + + CAknTabGroup* tabGroup = static_cast( iNaviDecorator->DecoratedControl() ); + // Create message priority bitmap + if ( iMtm->MessagePriority() == EMmsPriorityHigh || + iMtm->MessagePriority() == EMmsPriorityLow ) + { + TRect naviPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane, naviPane ); + + TAknLayoutRect naviTabsPane; + naviTabsPane.LayoutRect( naviPane, + AknLayoutScalable_Avkon::navi_navi_tabs_pane().LayoutLine() ); + + TAknLayoutRect navi2TabsPane; + navi2TabsPane.LayoutRect( naviTabsPane.Rect(), + AknLayoutScalable_Avkon::navi_tabs_2_pane().LayoutLine() ); + + TAknLayoutRect tabs2ActivePane; + tabs2ActivePane.LayoutRect( navi2TabsPane.Rect(), + AknLayoutScalable_Avkon::tabs_2_active_pane( 0 ).LayoutLine() ); + + TAknLayoutRect tabs2ActivePaneIcon; + tabs2ActivePaneIcon.LayoutRect( tabs2ActivePane.Rect(), + AknLayoutScalable_Avkon::tabs_2_active_pane_g1().LayoutLine() ); + + TSize indicatorIconSize( tabs2ActivePaneIcon.Rect().Size() ); + + // Set path of bitmap file + TParse fileParse; + fileParse.Set( KMmsUiMbmFile, &KDC_APP_BITMAP_DIR, NULL ); + + CFbsBitmap* bitmapPriority = NULL; + CFbsBitmap* maskPriority = NULL; + + if ( iMtm->MessagePriority() == EMmsPriorityHigh ) + { + // Create high priority bitmap + AknsUtils::CreateColorIconL( AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMcePriorityHigh, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG7, + bitmapPriority, + maskPriority, + fileParse.FullName(), + EMbmMmsuiQgn_indi_mce_priority_high, + EMbmMmsuiQgn_indi_mce_priority_high_mask, + AKN_LAF_COLOR( KIconDefaultColor ), + indicatorIconSize, + EAspectRatioPreserved ); + } + else + { + // Create low priority bitmap + AknsUtils::CreateColorIconL( AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMcePriorityLow, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG7, + bitmapPriority, + maskPriority, + fileParse.FullName(), + EMbmMmsuiQgn_indi_mce_priority_low, + EMbmMmsuiQgn_indi_mce_priority_low_mask, + AKN_LAF_COLOR( KIconDefaultColor ), + indicatorIconSize, + EAspectRatioPreserved ); + } + + if ( !bitmapPriority ) + { + User::Leave( KErrNotFound ); + } + + CleanupStack::PushL( bitmapPriority ); + CleanupStack::PushL( maskPriority ); + + if ( tabGroup->TabCount() == 0 ) + { + tabGroup->AddTabL( 0, aText, bitmapPriority, maskPriority ); + } + else + { + tabGroup->ReplaceTabL( 0, aText, bitmapPriority, maskPriority ); + } + + CleanupStack::Pop( maskPriority ); // ownership tranferred to tabgroup + CleanupStack::Pop( bitmapPriority ); // ownership tranferred to tabgroup + } + else + { + // Set / + if ( tabGroup->TabCount() == 0 ) + { + tabGroup->AddTabL( 0, aText ); + } + else + { + tabGroup->ReplaceTabL( 0, aText ); + } + } + + tabGroup->SetActiveTabById( 0 ); + tabGroup->SetTabFixedWidthL( KTabWidthWithOneTab ); + } +#endif // !RD_MSG_NAVIPANE_IMPROVEMENT + +// --------------------------------------------------------- +// CMmsViewerAppUi::DynInitMenuPaneL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DynInitMenuPaneL( TInt aMenuId, CEikMenuPane* aMenuPane ) + { + TInt amountOfItems( aMenuPane->NumberOfItemsInPane( ) ); + if ( !IsLaunched( ) ) + { + if ( amountOfItems ) + { + aMenuPane->DeleteBetweenMenuItems( 0, amountOfItems - 1 ); + } + return; + } + + if ( !iFindItemMenu ) + { + iFindItemMenu = CFindItemMenu::NewL( EFindItemMenuPlaceHolder ); + iFindItemMenu->SetCallSubMenuVisibility ( EFalse ); // Click-To-Call + if ( iHeader->SenderType( ) == EMuiuAddressTypeEmail ) + { + // Set sender type to find menu + iFindItemMenu->SetSenderDescriptorType( CItemFinder::EEmailAddress ); + } + } + + if ( iSupportedFeatures & EMmsFeatureUpload && + !( iViewerFlags & EUploadInitialized ) ) + { + iViewerFlags |= EUploadInitialized; + CSendUi* sendui = CSendUi::NewLC( ); + sendui->AvailableServicesL( iUploadServices, KMmsDirectUpload ); + sendui->AvailableServicesL( iUploadServices, KMmsIndirectUpload ); + CleanupStack::PopAndDestroy( sendui ); + } + + + switch ( aMenuId ) + { + case R_MMSVIEWER_SELECTIONMENU: + { + // No find item for recipient fields in Sent folder + if ( !IsOwnMessage( ) ) + { + if( (FocusedControlId( ) == EMsgComponentIdFrom) && ( ( iMtm->Sender( ) ).Length() ) ) + { + iFindItemMenu->SetSenderHighlightStatus( ETrue ); + iFindItemMenu->SetSenderDisplayText( TMmsGenUtils::PureAddress( iMtm->Sender( ) ) ); + } + else + { + iFindItemMenu->SetSenderHighlightStatus( EFalse ); + } + } + iFindItemMenu->AddItemFindMenuL( + ( FocusedControlId( ) == EMsgComponentIdBody ) ? iView->ItemFinder( ) : 0, + aMenuPane, + EFindItemContextMenuPlaceHolder, + TMmsGenUtils::PureAddress( iMtm->Sender( ) ), + iHeader->Alias( ) && !iHeader->IsRemoteAlias( ) ? ETrue : EFalse, //"Is sender known" + ETrue ); + + + break; + } + case R_MMSVIEWER_OPTIONSMENU: + { + + if ( iViewerState == EReseted ) + { + //Exit is the last item... leave it there. + aMenuPane->DeleteBetweenMenuItems( 0, amountOfItems - 2 ); + return; + } + + TInt focusedControl = FocusedControlId( ); + + TBool senderHighlighted = EFalse; + if ( focusedControl == EMsgComponentIdFrom ) + { + CMsgAddressControl* address = static_cast( + iView->ControlById( EMsgComponentIdFrom ) ); + + if ( address && address->Editor().SelectionLength() ) + { + senderHighlighted = ETrue; + } + } + + if ( !IsOwnMessage( ) ) + { + if( ( focusedControl == EMsgComponentIdFrom ) && ( ( iMtm->Sender( ) ).Length() ) + && senderHighlighted ) + { + iFindItemMenu->SetSenderHighlightStatus( ETrue ); + iFindItemMenu->SetSenderDisplayText( TMmsGenUtils::PureAddress( iMtm->Sender( ) ) ); + } + else + { + iFindItemMenu->SetSenderHighlightStatus( EFalse ); + } + } + + iFindItemMenu->AddItemFindMenuL( + ( iView->ItemFinder() && + iView->ItemFinder()->CurrentSelection().Length() ) + ? iView->ItemFinder() : 0, + aMenuPane, + EFindItemMenuPlaceHolder, + senderHighlighted ? + TMmsGenUtils::PureAddress( iMtm->Sender( ) ) : KNullDesC(), + iHeader->Alias( ) && !iHeader->IsRemoteAlias( ) ? ETrue : EFalse, //"Is sender known" + EFalse ); + + const TMsvEntry& context = Document( )->Entry( ); + // local variation for MMS Delivery Status dialog feature + if (! ( iSupportedFeatures & EMmsFeatureDeliveryStatus + && ( ( context.iMtmData2 & KMmsDeliveryStatusMask) != KMmsDeliveryStatusNotRequested ) ) ) + { + aMenuPane->DeleteMenuItem(EMmsViewerDeliveryStatus); + } + + if ( iSmilModel->SlideCount( ) > iMaxForwardSlideCount ) + { + aMenuPane->SetItemDimmed( EMmsViewerForward, ETrue ); + } + + + + if ( ! ( iSupportedFeatures & EMmsFeatureUpload ) + || !iUploadServices.Count( ) ) + { + aMenuPane->SetItemDimmed( EMmsViewerUpload, ETrue ); + } + + // Set help menu-item visibility according featureManager + if ( !( iSupportedFeatures & EMmsFeatureHelp ) ) + { + aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue ); + } + if ( !Document( )->SmilList( )->Count( ) ) + { + aMenuPane->SetItemDimmed( EMmsViewerShowMessage, ETrue ); + + } + else + { + if ( Document( )->SmilType( ) != EMmsSmil ) + { + aMenuPane->SetItemDimmed( EMmsViewerShowMessage, ETrue ); + } + + } + + if ( !ShowReplyMenu( ) ) + { + aMenuPane->SetItemDimmed( EMmsViewerReplyMenu, ETrue ); + } + + if ( Document( )->ObjectList( )->Count( ) == 0 && + Document( )->AttachmentList( )->Count( ) == 0 ) + { + aMenuPane->SetItemDimmed( EMmsViewerObjects, ETrue ); + } + break; + } + case R_MMSVIEWER_REPLY_SUBMENU: + { + if ( IsOwnMessage( ) + || !HasSender( ) ) + { + aMenuPane->SetItemDimmed( EMmsViewerReplyToSender, ETrue ); + } + if ( !ShowReplyToAll( ) ) + { + aMenuPane->SetItemDimmed( EMmsViewerReplyToAll, ETrue ); + } + if ( !( iSupportedFeatures & EMmsFeatureAudioMessaging ) + || IsOwnMessage( ) + || !HasSender( ) + || iSupportedFeatures & EMmsFeatureRestrictedReply ) + { + aMenuPane->SetItemDimmed( EMmsViewerReplyViaAudio, ETrue ); + } + + if ( IsOwnMessage( ) || + iHeader->SenderType( ) != EMuiuAddressTypeEmail || + iSupportedFeatures & EMmsFeatureRestrictedReply || + MsvUiServiceUtilitiesInternal::DefaultServiceForMTML( + Document( )->Session( ), + KSenduiMtmSmtpUid, + ETrue ) + == KMsvUnknownServiceIndexEntryId ) + { + // "Reply via e-mail" feature + aMenuPane->SetItemDimmed( EMmsViewerReplyViaMail, ETrue ); + } + break; + } + case R_MMSVIEWER_ZOOM_SUBMENU: + { + TInt zoomLevel = KErrGeneral; + iMsgEditorAppUiExtension-> + iSettingCachePlugin.GetValue( KAknLocalZoomLayoutSwitch, zoomLevel ); + switch ( zoomLevel ) + { + case EAknUiZoomAutomatic: + aMenuPane->SetItemButtonState( EMsgDispSizeAutomatic, + EEikMenuItemSymbolOn ); + break; + case EAknUiZoomNormal: + aMenuPane->SetItemButtonState( EMsgDispSizeNormal, + EEikMenuItemSymbolOn ); + break; + case EAknUiZoomSmall: + aMenuPane->SetItemButtonState( EMsgDispSizeSmall, + EEikMenuItemSymbolOn ); + break; + case EAknUiZoomLarge: + aMenuPane->SetItemButtonState( EMsgDispSizeLarge, + EEikMenuItemSymbolOn ); + break; + default: + break; + } + } + break; + default: // we are in FindItem submenu + { + // this does nothing if we're not, so this is safe + iFindItemMenu->UpdateItemFinderMenuL( aMenuId, aMenuPane ); + break; + } + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::UploadL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::UploadL( ) + { + TInt count = iUploadServices.Count( ); + + TInt selectedIndex = 0; + CAknListQueryDialog* dlg = new ( ELeave ) + CAknListQueryDialog( &selectedIndex ); + dlg->PrepareLC( R_MMSVIEWER_UPLOAD_LIST_QUERY ); + + // Populate list query array + CDesCArrayFlat* array = new ( ELeave ) CDesCArrayFlat( 4 ); + CleanupStack::PushL( array ); + for ( TInt i = 0; i < count; i++ ) + { + array->AppendL( iUploadServices[ i ]->ServiceMenuName( ) ); + } + dlg->SetItemTextArray( array ); + CleanupStack::Pop( array ); + + if ( dlg->RunLD( ) ) + { + CSendingServiceInfo* info = iUploadServices[ selectedIndex ]; + TMsgUploadParameters uploadParams; + uploadParams.iDirect = ( info->ServiceProviderId( ) == KMmsDirectUpload ); + uploadParams.iRealAddress = info->ServiceAddress( ); + uploadParams.iAlias = info->ServiceName( ); + + // Pack upload parameters + TPckgBuf param( uploadParams ); + + MediaStop( ); + ResetViewL( ); + + //These are not used! They just have to be there. + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + + CAknInputBlock::NewLC( ); + CMuiuOperationWait* wait = + CMuiuOperationWait::NewLC( EActivePriorityWsEvents + 10 ); + + CMsvOperation* oper = Document( )->MtmUiL( ).InvokeAsyncFunctionL( + KMtmUiFunctionUpload, + *selection, + wait->iStatus, + param ); + + CleanupStack::PushL( oper ); + + wait->Start( ); + + CleanupStack::PopAndDestroy( 4, selection ); // absorber, wait, oper, selection + Exit( EAknSoftkeyClose ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::ProcessCommandL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ProcessCommandL( TInt aCommand ) + { + if ( aCommand == EAknSoftkeyOptions + && iViewerState == EBusy) + { + LOGTEXT(_L8("CMmsViewerAppUi::ProcessCommandL returns immediately...")); + return; + } + CAknAppUi::ProcessCommandL( aCommand ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleCommandL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleCommandL( TInt aCommand ) + { +#ifdef USE_LOGGER + LOGTEXT2(_L16("CMmsViewerAppUi::HandleCommandL in. Command %d"), aCommand ); + TRAPD(error, DoHandleCommandL( aCommand ) ); + LOGTEXT2(_L16("CMmsViewerAppUi::HandleCommandL %d"), error ); + User::LeaveIfError( error ); +#else + DoHandleCommandL( aCommand ); +#endif + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoHandleCommandL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoHandleCommandL( TInt aCommand ) + { + if ( !IsLaunched() ) + { + if ( aCommand == EEikCmdExit ) + { + LOGTEXT(_L8("CMmsViewerAppUi::DoHandleCommandL Setting iViewerFlags |= EViewerExiting")); + iViewerFlags |= EViewerExiting; + } + return; + } + + if ( iFindItemMenu && iFindItemMenu->CommandIsValidL( aCommand ) ) + { + iFindItemMenu->HandleItemFinderCommandL( aCommand ); + return; + } + //MediaStop( ); + switch ( aCommand ) + { + case EMmsViewerShowPresentation: + case EMmsViewerShowMessage: + DoShowPresentationL( ); + break; + case EMmsViewerForward: + if ( !ShowOutOfDiskNoteIfBelowCriticalLevelL( + Document( )->MessageSize( ) ) ) + { + DoForwardL( ); + } + break; + case EMmsViewerDelete: + DoDeleteAndExitL( ); + break; + case EMmsViewerViewImage: + MediaPlayL( iImage ); + break; + case EMmsViewerPlayAudio: + MediaPlayL( iAudio ); + break; + case EMmsViewerPlayVideo: + MediaPlayL( iVideo ); + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMmsViewerPlaySvg: + MediaPlayL( iSvgt ); + break; +#endif + case EMmsViewerObjects: + DoObjectsL( ); + break; + case EMmsViewerMessageInfo: + DoMessageInfoL( ); + break; + case EMmsViewerDeliveryStatus: + OpenDeliveryPopupL( ); + break; + case EMmsViewerMove: + DoMoveMessageL( ); + break; + case EMmsViewerReplyToSender: + if ( !ShowOutOfDiskNoteIfBelowCriticalLevelL( + KReplyToSenderSize ) ) + { + DoReplyL( ETrue ); + } + break; + case EMmsViewerReplyToAll: + if ( !ShowOutOfDiskNoteIfBelowCriticalLevelL( + KReplyToAllSize ) ) + { + DoReplyL( EFalse ); + } + break; + case EMmsViewerReplyViaAudio: + case EMmsViewerReplyViaMail: + if ( !ShowOutOfDiskNoteIfBelowCriticalLevelL( + KReplyToAllSize ) ) + { + DoReplyViaL( aCommand ); + } + break; + + case EMmsViewerSoftStopVideo: + MediaStop(iVideo); + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMmsViewerSoftStopSvg: + MediaStop( iSvgt ); + break; +#endif + + case EMmsViewerSaveObject: + SaveObjectL( ); + break; + + case EMmsViewerUpload: + { + UploadL( ); + break; + } + + case EMmsViewerSoftStopAudio: + MediaStop(iAudio); + break; + case EMsgDispSizeAutomatic: + case EMsgDispSizeLarge: + case EMsgDispSizeNormal: + case EMsgDispSizeSmall: + HandleLocalZoomChangeL( (TMsgCommonCommands)aCommand ); + break; + case EAknCmdHelp: + LaunchHelpL( ); + break; + + case EAknSoftkeyBack: + MediaStop( ); + Exit( EAknSoftkeyClose ); + break; + case EEikCmdExit: + { + DoMsgSaveExitL( ); + break; + } + default: + break; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CMmsViewerAppUi::HandleKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + if ( !IsLaunched( ) ) + { + return EKeyWasNotConsumed; + } + if ( aType != EEventKey ) + { + return EKeyWasNotConsumed; + } + + if ( iViewerState == EBusy + || iViewerState == EReseted ) + { + return EKeyWasConsumed; + } + switch ( aKeyEvent.iCode ) + { + case EKeyLeftArrow: + { + if ( iVolumeDecorator + && iNaviPane->Top( ) == iVolumeDecorator ) + { + if( !( iSupportedFeatures & EMmsFeatureSVK ) ) + { + ChangeVolumeL( -1, ETrue ); + } + else if ( IsNextMessageAvailableL( EFalse ) ) + { + // playing audio/video is stopped by destructor + NextMessageL( EFalse ); + } + } + else if ( iNaviDecorator + && iNaviPane->Top( ) == iNaviDecorator ) + { + if ( IsNextMessageAvailableL( EFalse ) ) + { + NextMessageL( EFalse ); + } + } + } + break; + case EKeyRightArrow: + { + if ( iVolumeDecorator + && iNaviPane->Top( ) == iVolumeDecorator ) + { + if( !( iSupportedFeatures & EMmsFeatureSVK ) ) + { + ChangeVolumeL( +1, ETrue ); + } + else if ( IsNextMessageAvailableL( ETrue ) ) + { + // playing audio/video is stopped by destructor + NextMessageL( ETrue ); + } + } + else if ( iNaviDecorator + && iNaviPane->Top( ) == iNaviDecorator ) + { + if ( IsNextMessageAvailableL( ETrue ) ) + { + NextMessageL( ETrue ); + } + } + } + break; + case EKeyDevice3: //Selection key + case EKeyEnter: //Enter Key + { + CMsgExpandableControl* ctrl = NULL; + TBool checkHighlight = EFalse; + + if( iView->FocusedControl() ) + { + ctrl = static_cast( iView->FocusedControl() ); + if ( ctrl->ControlType() == EMsgAddressControl + && !ctrl->Editor().SelectionLength() ) + { + checkHighlight = ETrue; + } + else if ( ctrl->ControlType() == EMsgBodyControl ) + { + CItemFinder* itemFinder = iView->ItemFinder(); + if ( FocusedControlId() == EMsgComponentIdBody && itemFinder + && !itemFinder->CurrentSelection().Length() ) + { + checkHighlight = ETrue; + } + } + } + if ( ctrl && checkHighlight ) + { + // Check if highlight needs to be restored to editor, + // address/body editor offerkeyevent will handle it + if ( ctrl->Editor().OfferKeyEventL( aKeyEvent, aType ) + == EKeyWasConsumed ) + { + // Highlight was restored, just return, no cs menu needed + return EKeyWasConsumed; + } + } + + TInt focusedControl = FocusedControlId( ); + CMsgMediaControl* control = MediaControlById(focusedControl); + if (control) + { + if ( MediaCanStop( control ) ) + { + MediaStop(control); + } + else + { + MediaOpenL(control); + } + } + else if( focusedControl == EMsgComponentIdAttachment ) + { + DoObjectsL( ); + } + else if ( Document( )->SmilType( ) != EMmsSmil + && focusedControl == EMsgComponentIdImage ) + { + DoShowPresentationL( ); + } + else if ( iViewerState == ENormal ) + { + MenuBar( )->SetMenuTitleResourceId( R_MMSVIEWER_SELECTMENU ); + MenuBar()->SetMenuType(CEikMenuBar::EMenuContext); + TRAP_IGNORE( MenuBar( )->TryDisplayMenuBarL( ) ); + MenuBar( )->SetMenuTitleResourceId( R_MMSVIEWER_MENU ); + MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions); + } + break; + } + case EKeyYes: //Send key + DoHandleSendKeyL( ); + break; + case EKeyBackspace: // clear key + if ( !MediaIsRunning( iAudio ) && + !MediaIsRunning( iVideo ) ) + { + DoDeleteAndExitL( ); + } + break; + case EKeyNo: // End key + { + LOGTEXT(_L8("CMmsViewerAppUi::HandleKeyEventL EKeyNo")); + if ( MediaIsRunning( iAudio ) ) + { + MediaStop(iAudio); + } + else if ( MediaIsRunning( iVideo ) ) + { + MediaStop(iVideo); + } + // fall through + } + default: + // - Audio countdown & audio play cancelled on + // HandleViewDeactivation event!!! + // + //Power key + //Apps key + //End key + //Up key + //Down key + //Numeric keys + //Clear key + //Shift key + return iView->OfferKeyEventL( aKeyEvent, aType ); + } + return EKeyWasConsumed; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleWsEventL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleWsEventL(const TWsEvent& aEvent,CCoeControl* aDestination) + { + TInt type = aEvent.Type( ); + switch ( type ) + { + case EEventFocusGroupChanged: + { + if ( !iIsStopPlaybackWgId ) + { + ResolveCurrentWgIdL( ); + + // Stop only if temporary change e.g. a waiting note etc. + if ( iIsStopPlaybackWgId ) + { + MediaStop(iAudio); + MediaStop(iVideo); + StopAnimation( ); + } + } + // else - no need to stop + break; + } + case EEventFocusGained: + { + if ( iIsStopPlaybackWgId ) + { + iIsStopPlaybackWgId = EFalse; + StartAnimationL( ); + }; + break; + } + // case EEventFocusLost: + default: + break; + } + CMsgEditorAppUi::HandleWsEventL(aEvent, aDestination); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::CreateCustomControlL +// --------------------------------------------------------- +// +CMsgBaseControl* CMmsViewerAppUi::CreateCustomControlL( + TInt /*aControlType*/ ) + { + return NULL; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowInformationNoteL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ShowInformationNoteL( TInt aResourceId ) + { + HBufC* string = StringLoader::LoadLC( aResourceId, iCoeEnv ); + CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue ); + note->ExecuteLD( *string ); + CleanupStack::PopAndDestroy( string ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowErrorNoteL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ShowErrorNoteL( TInt aResourceId ) + { + HBufC* string = StringLoader::LoadLC( aResourceId, iCoeEnv ); + CAknErrorNote* note = new ( ELeave ) CAknErrorNote( ETrue ); + note->ExecuteLD( *string ); + CleanupStack::PopAndDestroy( string ); + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowConfirmationQueryL +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::ShowConfirmationQueryL( TInt aResourceId ) const + { + HBufC* queryString = StringLoader::LoadLC( + aResourceId, + iCoeEnv ); + CAknQueryDialog* dlg = CAknQueryDialog::NewL( ); + TInt retVal = dlg->ExecuteLD( R_MMSVIEWER_CONFIRMATION_QUERY, *queryString ); + CleanupStack::PopAndDestroy( queryString ); + return retVal; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowConfirmationQueryL +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::ShowConfirmationQueryL( TInt aResourceId, + const TDesC& aString) const + { + HBufC* queryString = StringLoader::LoadLC( + aResourceId, + aString, + iCoeEnv ); + CAknQueryDialog* dlg = CAknQueryDialog::NewL( ); + TInt retVal = dlg->ExecuteLD( R_MMSVIEWER_CONFIRMATION_QUERY, *queryString ); + CleanupStack::PopAndDestroy( queryString ); + return retVal; + } + +// --------------------------------------------------------- +// ShowGuidedModeConfirmationQueryL +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::ShowGuidedModeConfirmationQueryL( TInt aResourceID ) + { + TInt retVal = EFalse; + if ( iViewerFlags & EShowGuidedConf ) + { + retVal = ShowConfirmationQueryL( aResourceID ); + if ( retVal ) + { + iViewerFlags &= ~EShowGuidedConf; + } + + } + else + { + retVal = ( Document( )->CreationMode( ) != EMmsCreationModeRestricted ); + } + return retVal; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowOutOfDiskNoteIfBelowCriticalLevelL +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::ShowOutOfDiskNoteIfBelowCriticalLevelL( TInt aSize ) + { + //Check whether there is enough free disk + //to create a copy of the message. + if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL( + Document( )->Session( ), + aSize ) ) + { + CErrorUI* errorUI = CErrorUI::NewLC( *iCoeEnv ); + errorUI->ShowGlobalErrorNoteL( KErrDiskFull ); + //Returns TInt! (ETrue if note was displayed, EFalse otherwise) + //...ignored... + CleanupStack::PopAndDestroy( errorUI ); + return ETrue; + } + else + { + return EFalse; + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoReplyL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoReplyL( TBool aReplyToSender ) + { + iViewerState = EBusy; + TRAPD ( error, + { + if ( !(iEditorBaseFeatures & EStayInViewerAfterReply )) + { + MediaStop( ); + ResetViewL( ); + } + + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( ETrue ); + } + + // Enable Dialer as MMS Settings dialog may be launched + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + if ( aReplyToSender ) + { + ReplyL( KNewMessageFolder ); //Draft + } + else + { + ReplyToAllL( KNewMessageFolder ); //Draft + } + + if (!(iEditorBaseFeatures & EStayInViewerAfterReply)) + { + Exit( EAknSoftkeyClose ); + } + + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); + } + iViewerState = ENormal; + }); //end TRAP + if ( error ) + { + LOGTEXT2(_L16("CMmsViewerAppUi::DoReplyL error %d"), error ); + iViewerState = EReseted; + User::Leave( error ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoForwardL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoForwardL( ) + { + TInt resourceId = 0; + Document()->DataModel().FinalizeMediaParse(); + if ( !CanForwardL( resourceId ) ) + { + // This if cannot be combined with the above + // one. -> Else would not work correctly. + if ( resourceId ) + { + ShowInformationNoteL( resourceId ); + } + } + else + { + iViewerState = EBusy; + TRAPD ( error, + { + if ( !(iEditorBaseFeatures & EStayInViewerAfterReply )) + { + MediaStop( ); + ResetViewL( ); + } + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( ETrue ); + } + + // Enable Dialer as MMS Settings dialog may be launched + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + if(iFindItemMenu) + { + delete iFindItemMenu; + iFindItemMenu = NULL; + } + + ForwardL( KNewMessageFolder ); //Draft + + if ( !(iEditorBaseFeatures & EStayInViewerAfterReply )) + { + Exit( EAknSoftkeyClose ); + } + + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); + } + iViewerState = ENormal; + } ); //end TRAP + if ( error ) + { + LOGTEXT2(_L16("CMmsViewerAppUi::DoForwardL error %d"), error ); + iViewerState = EReseted; + User::Leave( error ); + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::CanForward +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::CanForwardL( TInt& aResourceId ) + { + + TInt msgSize = Document( )->MessageSize( ); + if ( msgSize > TInt32( Document( )->MaxMessageSize( ) ) ) + { + // This could happen if MaxReceiveSize > MaxSendSize + aResourceId = R_MMSVIEWER_CANNOT_FW_BIG; + return EFalse; + } + + if ( Document( )->CreationMode( ) == EMmsCreationModeRestricted ) + { + if ( Document( )->SmilType( ) != EMmsSmil || + iViewerFlags & ESuspiciousSmil ) + { + aResourceId = ( iMmsConformance->CreationModeUserChangeable( ) && + !iMmsConformance->CreationMode( ) ) ? + R_MMSVIEWER_RMODE_CANNOT_FW_PRES: + R_MMSVIEWER_CANNOT_FW_PRES; + return EFalse; + } + else if ( msgSize > KClassMaxSizeVideoRich ) + { + aResourceId = R_MMSVIEWER_CANNOT_FW_BIG; + return EFalse; + } + } + TBool objectsOk = CanForwardObjectsL( aResourceId ); + TInt conformanceSize = KClassMaxSizeVideoRich; + if(iMmsConformance->ConformanceVersion() > KMmsVersion12) + { + conformanceSize = KClassMaxSizeMegapixel; + } + + if ( objectsOk && Document( )->CreationMode( ) == EMmsCreationModeWarning ) + { + if ( Document( )->SmilType( ) != EMmsSmil || + iViewerFlags & ESuspiciousSmil ) + { + aResourceId = 0; + return ShowGuidedModeConfirmationQueryL( R_MMSVIEWER_QUEST_GUIDED_PRESENTATION ); + } + else if ( msgSize > conformanceSize ) + { + aResourceId = 0; + return ShowGuidedModeConfirmationQueryL( R_MMSVIEWER_QUEST_GUIDED_INC_OBJ ); + } + } + return objectsOk; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::CanForwardObjectsInListL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::CanForwardObjectsInListL( + CUniObjectList* aObjectList, + TInt& aSdCount, + TInt& aFlCount, + TInt& aNonConfCount, + TInt& aNormalCount, + TInt& aResourceId ) const + { + __ASSERT_ALWAYS( aObjectList, Panic( EMmsViewerNullPointer ) ); + for ( TInt i = aObjectList->Count( ); --i >= 0; ) + { + TUint32 confStatus( EMmsConfOk ); + + CUniObject* obj = aObjectList->GetByIndex( i ); + if ( obj + && obj->MediaInfo( ) ) + { + TMmsConformance conf = iMmsConformance->MediaConformance( * ( obj->MediaInfo( ) ) ); + confStatus = conf.iConfStatus; + } + if ( confStatus & EMmsConfNokTooBig ) + { + aFlCount++; + continue; + } + + if ( confStatus == EMmsConfOk ) + { + aNormalCount++; + continue; + } + + if ( iSupportedFeatures & EMmsFeatureDrmFull && + obj->MediaInfo( )->Protection( ) & EFileProtSuperDistributable ) + { + aSdCount++; + continue; + } + + if ( confStatus & EMmsConfNokDRM ) + { + + + aResourceId = ( iSupportedFeatures & EMmsFeatureDrmFull ) + ? R_MMSVIEWER_CANNOT_FW_DRM + : R_MMSVIEWER_CANNOT_FW_OBJECTS; + + if ( aResourceId == R_MMSVIEWER_CANNOT_FW_OBJECTS + && ( iMmsConformance->CreationModeUserChangeable( ) && + !iMmsConformance->CreationMode( ) ) ) + { + aResourceId = R_MMSVIEWER_RMODE_CANNOT_FW_OBJECTS; + } + + aFlCount++; + continue; + } + + if ( confStatus != EMmsConfOk ) + { + aNonConfCount++; + } + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::CanForwardObjects +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::CanForwardObjectsL( TInt& aResourceId ) + { + + TInt normalCount = 0; + TInt sdCount = 0; + TInt deniedCount = 0; + TInt nonConfCount = 0; + + CanForwardObjectsInListL( Document( )->ObjectList( ), + sdCount, + deniedCount, + nonConfCount, + normalCount, + aResourceId ); + CanForwardObjectsInListL( Document( )->AttachmentList( ), + sdCount, + deniedCount, + nonConfCount, + normalCount, + aResourceId ); + + if ( deniedCount ) + { + // resource ID set by CanForwardObjectsInListL + return EFalse; + } + + switch ( Document( )->CreationMode( ) ) + { + case EMmsCreationModeRestricted: + if ( sdCount || nonConfCount ) + { + aResourceId = ( iMmsConformance->CreationModeUserChangeable( ) && + !iMmsConformance->CreationMode( ) ) ? + R_MMSVIEWER_RMODE_CANNOT_FW_OBJECTS: + R_MMSVIEWER_CANNOT_FW_OBJECTS; + return EFalse; + } + break; + case EMmsCreationModeWarning: + { + if ( nonConfCount == 1 ) + { + aResourceId = 0; + return ShowGuidedModeConfirmationQueryL( R_MMSVIEWER_QUEST_GUIDED_INC_OBJ ); + } + else if ( nonConfCount ) + { + aResourceId = 0; + return ShowGuidedModeConfirmationQueryL( R_MMSVIEWER_QUEST_GUIDED_INC_OBJS ); + } + } + // Fallthrough + case EMmsCreationModeFree: + default: + { + if ( sdCount ) + { + // default singular + TInt everyWoRights = R_MMSVIEWER_QUEST_SEND_ONE_WO_RIGHTS; + if ( sdCount > 1) + { + // plural + everyWoRights = R_MMSVIEWER_QUEST_SEND_EVERY_WO_RIGHTS; + } + + aResourceId = 0; //Make sure resource id is zero. + return ( ShowConfirmationQueryL( normalCount + ? R_MMSVIEWER_QUEST_SEND_SOME_WO_RIGHTS + : everyWoRights ) ); + } + } + break; + } + + return ETrue; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoReplyViaL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoReplyViaL( TInt aCase ) + { + if ( iHeader->SenderType( ) != EMuiuAddressTypeNone ) + { + TInt cleanupCount = 0; + + CMessageData* msgData = CMessageData::NewLC( ); + cleanupCount++; + + // Add address and alias + // Basically alias is taken from TMsvEntry.iDetails (see MmsViewerHeader.cpp) + // Alias can be one of the following in precedence order + // 1) local alias + // 2) remote alias. Remote alias maybe available when message arrives from + // email address + // 3) sender's address + const TPtrC sender = iMtm->Sender( ); + + if ( sender != KNullDesC( ) ) + { + if ( iHeader->Alias( ) ) + { + //const TPtrC alias = iHeader->Alias( ); + msgData->AppendToAddressL( TMmsGenUtils::PureAddress( sender ), *iHeader->Alias( ) ); + } + else + { + msgData->AppendToAddressL( TMmsGenUtils::PureAddress( sender ) ); + } + } + + TUid mtmUid( KSenduiMtmAudioMessageUid ); + switch( aCase ) + { + case EMmsViewerReplyViaAudio: + // default value OK + break; + case EMmsViewerReplyViaMail: + if ( iHeader->SenderType( ) == EMuiuAddressTypePhoneNumber ) + { + __ASSERT_DEBUG( EFalse, Panic( EMmsViewerUnexpectedReplyEvent ) ); + } + mtmUid = KSenduiMtmSmtpUid; + break; + default: + __ASSERT_DEBUG( EFalse, Panic( EMmsViewerUnexpectedReplyEvent ) ); + break; + } + + // audio message has not subject field + if ( mtmUid == KSenduiMtmSmtpUid ) + { + HBufC* prefixSubject = CreateSubjectPrefixStringL( iMtm->SubjectL( ), ETrue ); + CleanupStack::PushL( prefixSubject ); + if ( prefixSubject ) + { + msgData->SetSubjectL( prefixSubject ); + } + else + { + TPtrC subjectDes = iMtm->SubjectL( ); + msgData->SetSubjectL( &subjectDes ); + } + CleanupStack::PopAndDestroy( prefixSubject ); + } + + CSendUi* sendUi = CSendUi::NewLC( ); + cleanupCount++; + + iViewerState = EBusy; + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( ETrue ); + } + + // Enable Dialer as MMS Settings dialog may be launched + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + TRAPD ( error, + { + if ( !(iEditorBaseFeatures & EStayInViewerAfterReply )) + { + MediaStop( ); + ResetViewL( ); + } + + sendUi->CreateAndSendMessageL( + mtmUid, + msgData); + + } ); //TRAPD + CleanupStack::PopAndDestroy( cleanupCount ); + + if ( error ) + { + LOGTEXT2(_L16("CMmsViewerAppUi::DoReplyViaL error %d"), error ); + iViewerState = EReseted; + User::Leave( error ); + } + else if ( !(iEditorBaseFeatures & EStayInViewerAfterReply )) + { + Exit( EAknSoftkeyClose ); + } + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); + } + iViewerState = ENormal; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoObjectsL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoObjectsL( ) + { + MediaClose( iVideo ); + CUniObjectsModel& objectsViewModel = + static_cast( Document( )->AttachmentModel( ) ); + + iViewerState = EBusy; + + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( ETrue ); + } + // Enable Dialer + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + TUniObjectsDialogExitCmd dlgRet = EUniObjectsViewBack; +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT + iNoTitlePaneUpdate = ETrue; +#endif + + iViewerFlags |= EInObjectsView; + TRAP_IGNORE ( CUniObjectsViewDialog::ObjectsViewL ( + CUniObjectsViewDialog::EViewer, + objectsViewModel, + iEikonEnv, + dlgRet, + Document()->DataModel( ) ) ); + + iViewerFlags &= ~EInObjectsView; +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT + iNoTitlePaneUpdate = EFalse; +#endif + objectsViewModel.Reset(); + + if ( !IsAppShutterRunning() ) + { + if ( iToolbar ) + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); + } + iViewerState = ENormal; + if ( dlgRet == EUniObjectsViewBack ) + { + if ( iVideo ) + { + CUniObject* videoObject = ObjectByBaseControl( *iVideo ); + if ( videoObject ) + { + ReloadControlL( iVideo, *videoObject ); + } + } + } + + InitNavipaneL( ); + + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoShowPresentationL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoShowPresentationL( ) + { + TMsvAttachmentId smilId = Document( )->SmilList( )->GetSmilAttachmentByIndex( 0 ); + + if ( smilId ) + { + MediaClose(); + + // Finish parsing media objects + Document()->DataModel().FinalizeMediaParse(); + + if ( Document( )->SmilType( ) == EMmsSmil && + !( iViewerFlags & ESuspiciousSmil ) ) + { + if ( !iSmilModel->ChangeLayoutL( Document( )->DataModel().Dom( ) ) ) + { + Document( )->DataModel().SetDom( iSmilModel->ComposeL( ) ); + } + + if ( !iSmilModel->CorrectTimingL( Document( )->DataModel().Dom( ) ) ) + { + Document( )->DataModel().SetDom( iSmilModel->ComposeL( ) ); + } + } + + CUniObjectList* objectList = Document( )->ObjectList( ); + TInt expiredCount = 0; + TInt norightsCount = 0; + + iViewerFlags &= (~EPresentationHasAudio); + for ( TInt index = 0; index < objectList->Count( ); index++ ) + { + CUniObject* current = objectList->GetByIndex( index ); + TBool ignoreConsumed (EFalse ); + TInt result = KErrNone; + if ( current + && current->DrmInfo( ) ) + { + result = current->DrmInfo( )->EvaluateRights( ignoreConsumed ); + } + + LOGTEXT2(_L16("CMmsViewerAppUi::DoShowPresentationL result %d"), result ); + if ( result == DRMCommon::ENoRights ) + { + norightsCount++; + } + else if ( result == DRMCommon::ERightsExpired ) + { + expiredCount++; + } + else if ( current ) + { + // Rights exist + // Smil player needs info whether audio clip is present or (one of the) video clip(s) + // has audio stream + TMsgMediaType media = current->MediaType( ); + if ( media == EMsgMediaAudio ) + { + iViewerFlags |= EPresentationHasAudio; + } + else if ( media == EMsgMediaVideo && + static_cast( current->MediaInfo() )->IsAudio() ) + { + // existence of audio is checked after initialisation + iViewerFlags |= EPresentationHasAudio; + } + } + } + + if ( norightsCount > 0 ) + { + ShowInformationNoteL( R_QTN_DRM_NO_RIGHTS_FOR_SOME ); + } + else if ( expiredCount > 0 ) + { + ShowInformationNoteL( R_QTN_DRM_GEN_RIGHTS_EXP ); + } + + delete iSvkEvents; + iSvkEvents = NULL; + //EJJN-7MY3SM::MMS viewer, ReTe, RM505_MeDo_ivalo_rnd: Panic with note + //"Application closed: Multimedia" occurs after some operation. + + CEikButtonGroupContainer* cba1 = CEikButtonGroupContainer::Current(); + if (cba1) + { + cba1->MakeVisible(EFalse); + } + + if ( iToolbar ) + { + iToolbar->SetToolbarVisibility(EFalse, EFalse); + } + // Enable Dialer + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + CSmilPlayerDialog* dialog = CSmilPlayerDialog::NewL( + Document( )->DataModel().Dom( ), + Document( )->ObjectList( ), + KNullDesC( ), + EFalse, + iViewerFlags & EPresentationHasAudio ); + + iViewerState = EBusy; + TRAPD( error, dialog->ExecuteLD( ) ); + + CAknAppUiBase* appUi = static_cast( iEikonEnv->EikAppUi( ) ); + TRAP_IGNORE( appUi->SetOrientationL( CAknAppUiBase::EAppUiOrientationAutomatic ) ); + + if ( iToolbar ) + { + iToolbar->SetToolbarVisibility(ETrue, EFalse); + } + + iViewerState = ENormal; + + // re-calculate all pos and dimensions of layout's widgets, after + // status pane is set back to usual and fixed-toolbar is made visible. + HandleResourceChangeL(KEikDynamicLayoutVariantSwitch); + + if ( !IsAppShutterRunning() ) + { + ReloadSlideL( ); + } + else + { + InitNavipaneL( ); + } + + iSvkEvents = CMmsSvkEvents::NewL( *this ); + + User::LeaveIfError( error ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoHandleSendKeyL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoHandleSendKeyL( ) + { + if ( MediaIsRunning( iAudio ) || + MediaIsRunning( iVideo ) ) + { + //-> inactive + return; + } + + if ( !iMmsVoIPExtension ) + { + iMmsVoIPExtension = CMsgVoIPExtension::NewL( ); + } + + TPtrC senderAddr = KNullDesC( ); + TPtrC senderAlias = KNullDesC( ); + TBool dialerDisabled = EFalse; + + senderAddr.Set( TMmsGenUtils::PureAddress( iMtm->Sender() ) ); + if ( iHeader->Alias( ) ) + { + senderAlias.Set( *( iHeader->Alias( ) ) ); + } + + TPtrC focusedAddr = KNullDesC( ); + if ( FocusedControlId( ) == EMsgComponentIdBody && + iView->ItemFinder( ) ) + { + const CItemFinder::CFindItemExt& item = + iView->ItemFinder( )->CurrentItemExt( ); + if ( item.iItemDescriptor + && ( item.iItemType == CItemFinder::EPhoneNumber + || item.iItemType == CItemFinder::EEmailAddress ) ) + { + //Dialer is opened when creating a VoIP call from MMS via Call creation key + //Disabling the dialer when send is pressed + iAvkonAppUi->SetKeyEventFlags( + CAknAppUiBase::EDisableSendKeyShort | + CAknAppUiBase::EDisableSendKeyLong ); + dialerDisabled = ETrue; + focusedAddr.Set( *(item.iItemDescriptor) ); + } + } + + if ( FocusedControlId( ) == EMsgComponentIdFrom && + senderAddr.Length() && + iHeader->SenderType( ) == EMuiuAddressTypePhoneNumber ) + { + // Disable dialer + iAvkonAppUi->SetKeyEventFlags( + CAknAppUiBase::EDisableSendKeyShort | + CAknAppUiBase::EDisableSendKeyLong ); + dialerDisabled = ETrue; + } + // Only when dialer is disabled try placing the call + if ( dialerDisabled ) + { + MsvUiServiceUtilitiesInternal::InternetOrVoiceCallServiceL( + *iMmsVoIPExtension, + senderAddr, + senderAlias, + focusedAddr, + ETrue, + iEikonEnv ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoMessageInfoL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoMessageInfoL( ) + { + TPckgBuf nullParam( 0 ); + + //These are not used! They just have to be there. + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + + CMsvSingleOpWatcher* watch = CMsvSingleOpWatcher::NewLC( *Document( ) ); + CMsvOperation* op = Document( )->MtmUiL( ).InvokeAsyncFunctionL( + KMtmUiFunctionMessageInfo, + *selection, + watch->iStatus, + nullParam ); + CleanupStack::Pop( watch ); + Document( )->AddSingleOperationL( op, watch ); + + CleanupStack::PopAndDestroy( selection ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoDeleteAndExitL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoDeleteAndExitL( ) + { + // Confirm from user deletion of message and delete if needed. + if ( ShowConfirmationQueryL( R_MMSVIEWER_QUEST_DELETE_MESSAGE ) ) + { + MediaStop( ); + //Reset view (i.e. close all files!) + //If image is open, extra delay needs to be added that + //server side components can finish their tasks + iViewerState = EReseted; + ResetViewL( ); + // create delay, because every media object is not necessary closed immediately + Document( )->DeleteModel( ); + User::After(50000); + DeleteAndExitL( ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoMoveMessageL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoMoveMessageL( ) + { + //ask folder with a dialog (from muiu) + TMsvId target = Document( )->Entry( ).Parent( ); + HBufC* title = StringLoader::LoadLC( R_MMSVIEWER_MOVE_TEXT, iCoeEnv ); + TBool success = CMsgFolderSelectionDialog::SelectFolderL(target, *title); + CleanupStack::PopAndDestroy( title ); + if (success) + { + MediaStop( ); + iViewerState = EReseted; + ResetViewL( ); + iViewerState = EBusy; + TInt error(KErrNone); + TRAP(error, MoveMessageEntryL( target ) ); + iViewerState = EReseted; + + LOGTEXT2(_L16("CMmsViewerAppUi::DoMoveMessageL %d"), error ); + User::LeaveIfError( error ); + Exit( EAknSoftkeyClose ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::IsOwnMessage +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::IsOwnMessage( ) const + { + const TMmsMsvEntry* mmsEntry = + static_cast( &Document( )->Entry( ) ); + return ( !(mmsEntry->IsMobileTerminated( ) ) ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HasSender +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::HasSender( ) const + { + return ( iMtm->Sender( ).Length( ) > 0 ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowReplyToAll +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::ShowReplyToAll( ) const + { + return ( iMtm->AddresseeList( ).Count( ) > + ( IsOwnMessage( ) ? 0 : 1 ) ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ShowReplyMenu +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::ShowReplyMenu( ) const + { + if ( Document( )->IsUpload( ) ) + { + return EFalse; + } + else + { + return ( HasSender( ) || ShowReplyToAll( ) ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ResetViewL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ResetViewL( ) + { + iVideo = NULL; + iAudio = NULL; + iImage = NULL; +#ifdef RD_SVGT_IN_MESSAGING + iSvgt = NULL; +#endif + + if ( iSlideLoader ) + { + iSlideLoader->ResetViewL( ); + } + // When attachments view is visible but not focused, eye striking focus movement takes + // place to attachments field e.g durign forwarding. + iHeader->RemoveAttachmentL(); + iHeader->RemoveFromViewL( ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::EditorObserver +// --------------------------------------------------------- +// +void CMmsViewerAppUi::EditorObserver(TMsgEditorObserverFunc aFunc, TAny* aArg1, TAny* aArg2, TAny* aArg3) + { + TRAP_IGNORE(DoEditorObserverL(aFunc,aArg1,aArg2,aArg3 ) ); + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::EditorObserver +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoEditorObserverL(TMsgEditorObserverFunc aFunc, TAny* aArg1, TAny* aArg2, TAny* aArg3) + { + TInt slides = iSmilModel->SlideCount( ); + TBool multiSlide = + ( Document( )->SmilType( ) == EMmsSmil && slides > 1 ); + switch ( aFunc ) + { + case EMsgScrollParts: + { + if ( multiSlide ) + { + TInt* parts = static_cast( aArg1 ); + *parts = slides; + } + } + break; + case EMsgHandleFocusChange: + { + // Enable Dialer + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + + TMsgFocusEvent event = + *( static_cast( aArg1 ) ); + TMsgAfterFocusEventFunc* after = + static_cast( aArg2 ); + TInt* currPart = + static_cast( aArg3 ); + + switch (event) + { + case EMsgFocusAtBottom: +#ifdef RD_SCALABLE_UI_V2 + // check the legality of slide change + if ( multiSlide && *currPart > Document( )->CurrentSlide( ) ) + { + TInt moveToSlide( *currPart ); + if ( moveToSlide >= slides ) + { + moveToSlide = slides - 1; + } + + ChangeSlideL( moveToSlide, ETrue ); + *after = EMsgCursorToBodyBeginning; + } + else + { + *after = EMsgAfterFocusNone; + } + *currPart = Document( )->CurrentSlide( ); +#else + if ( multiSlide && Document( )->CurrentSlide( ) + 1 < slides ) + { + ChangeSlideL( Document( )->CurrentSlide( ) + 1, ETrue); + *after = EMsgCursorToBodyBeginning; + *currPart = Document( )->CurrentSlide( ); + } +#endif + break; + case EMsgFocusAtTop: +#ifdef RD_SCALABLE_UI_V2 + // check the legality of slide change + if ( multiSlide && *currPart < Document( )->CurrentSlide( ) ) + { + TInt moveToSlide( *currPart ); + if ( moveToSlide < 0 ) + { + moveToSlide = 0; + } + + ChangeSlideL( moveToSlide, ETrue); + *after = EMsgCursorToBodyEnd; + } + else + { + *after = EMsgAfterFocusNone; + } + *currPart = Document( )->CurrentSlide( ); +#else + if ( multiSlide && Document( )->CurrentSlide( ) > 0 ) + { + ChangeSlideL( Document( )->CurrentSlide( ) - 1, ETrue); + *after = EMsgCursorToBodyEnd; + *currPart = Document( )->CurrentSlide( ); + } +#endif + break; + case EMsgFocusMovingFrom: + { + if ( MediaIsRunning( iVideo ) ) + { + MediaStop( iVideo ); + } + break; + } + case EMsgFocusMovedTo: + { + StartAnimationL( ); + UpdateMskL( ); + break; + } + case EMsgFocusToBody: + case EMsgFocusToHeader: + default: + break; + } + } + break; + case EMsgControlPointerEvent: + { +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + TPointerEvent* pointerEvent = static_cast( aArg2 ); + CMsgBaseControl* baseControl = static_cast( aArg1 ); + TWsEvent* wsEvent = static_cast(aArg2); + + if ( pointerEvent + && pointerEvent->iType == TPointerEvent::EButton1Down ) + { + // We are looking for a valid tap (button down and up) + // on a focused object. + iPointerTarget = baseControl; + + if ( baseControl && + ( baseControl->ControlId() == EMsgComponentIdAudio || + baseControl->ControlId() == EMsgComponentIdImage || + baseControl->ControlId() == EMsgComponentIdVideo || + baseControl->ControlId() == EMsgComponentIdSvg )&& + ((Document()->SmilType()!=ETemplateSmil)&&(Document()->SmilType()!=E3GPPSmil) )) + { + if(iLongTapDetector) + { + iLongTapDetector->EnableLongTapAnimation(ETrue); + iLongTapDetector->PointerEventL( *pointerEvent ); + } + } + iTapConsumed = EFalse; + } + else if ( (!iTapConsumed) && (pointerEvent + && pointerEvent->iType == TPointerEvent::EButton1Up) ) + { + iLongTapDetector->MonitorWsMessage(*wsEvent); + iTapConsumed = ETrue; + CMsgBaseControl* focusedControl = iView->FocusedControl(); + if ( baseControl && iPointerTarget == baseControl ) + { + switch( iMskId ) + { + // Tapping on selected object functions as a + // selection key was pressed. But command set + // is limited to ones below. + case R_MMSVIEWER_MSK_BUTTON_PLAY_PRESENTATION: // fallthrough + case R_MMSVIEWER_MSK_BUTTON_PLAY_AUDIO: // fallthrough + case R_MMSVIEWER_MSK_BUTTON_OPEN_IMAGE: // fallthrough + case R_MMSVIEWER_MSK_BUTTON_PLAY_VIDEO: // fallthrough + case R_MMSVIEWER_MSK_BUTTON_STOP_AUDIO: + case R_MMSVIEWER_MSK_BUTTON_STOP_VIDEO: + case R_MMSVIEWER_MSK_BUTTON_OPEN_OBJECTS: +#ifdef RD_SVGT_IN_MESSAGING + case R_MMSVIEWER_MSK_BUTTON_PLAY_SVG: +#endif + { + HandleSelectionKeyL(); + *static_cast( aArg3 ) = ETrue; // handled + } + default: + ; + } + } + else if ( focusedControl && iPointerTarget == focusedControl ) + { + if ( iMskId == R_MMSVIEWER_MSK_BUTTON_PLAY_VIDEO || + iMskId == R_MMSVIEWER_MSK_BUTTON_STOP_VIDEO ) + { + HandleSelectionKeyL(); + *static_cast( aArg3 ) = ETrue; // handled + } + } + + iPointerTarget = NULL; + } + } +#endif // RD_SCALABLE_UI_V2 + break; + } + case EMsgButtonEvent: + { +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + if ( iHeader->AttachmentControl( ) == static_cast( aArg1 ) ) + { + DoObjectsL(); + } + } +#endif // RD_SCALABLE_UI_V2 + break; + } + default: + break; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleNotifyInt +// +// Notification from central repository +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleNotifyInt( TUint32 /*aId*/, TInt aNewValue ) + { + if ( aNewValue == 0 ) + { + iViewerFlags &= ~EAutohighLightEnabled; + } + else + { + iViewerFlags |= EAutohighLightEnabled; + } + TRAP_IGNORE( SetFindModeL( iViewerFlags & EAutohighLightEnabled ) ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleNotifyGeneric +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleNotifyGeneric( TUint32 /*aId*/ ) + { + //Nothing. + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleNotifyError +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleNotifyError( TUint32 /*aId*/, TInt /*error*/, CCenRepNotifyHandler* /*aHandler*/ ) + { + //Nothing. + } + +// +// NOTICE: +// +// Startup observer moved to own class because Publish & Subscribe +// requires an active object for event handling. +// + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleIteratorEventL +// --------------------------------------------------------- +// +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +void CMmsViewerAppUi::HandleIteratorEventL( TMessageIteratorEvent aEvent ) + { + if ( aEvent == EFolderCountChanged + && iViewerState == ENormal + && !iNoTitlePaneUpdate ) + { + InitNavipaneL( ); + } + } +#endif + +// --------------------------------------------------------- +// MmsSvkChangeVolumeL +// --------------------------------------------------------- +// Callback function +void CMmsViewerAppUi::MmsSvkChangeVolumeL( TInt aVolumeChange ) + { + ChangeVolumeL( aVolumeChange, ETrue ); + } + +// --------------------------------------------------------- +// ChangeVolumeL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ChangeVolumeL( TInt aVolume, TBool aChange ) + { + TBool audioPlaying ( MediaCanStop( iAudio ) ); + TBool videoPlaying = + ( ( MediaCanStop( iVideo ) ) && + ( FocusedControlId( ) == EMsgComponentIdVideo ) ); + + if ( audioPlaying || videoPlaying ) + { + TInt newVolume = DoChangeVolumeL( aVolume, aChange, audioPlaying ); + if ( newVolume >= KVolumeControlMinValue ) + { + // Finally show the volume + ShowVolumeL( newVolume, audioPlaying ); + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoChangeVolumeL +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::DoChangeVolumeL( TInt aVolume, TBool aChange, TBool aAudioPlaying ) + { +#ifdef _DEBUG + if ( aAudioPlaying ) + { + __ASSERT_DEBUG( iAudio, Panic( EMmsViewerNullPointer ) ); + } + else + { + __ASSERT_DEBUG( iVideo, Panic( EMmsViewerNullPointer ) ); + } +#endif + TInt newVolume = aVolume; + // In practise the variable indicates whether volume indicator is shown in the navi pane + // and whether audio can be heard + TBool updateIntoCenRepAllowed( aAudioPlaying ); + + // Changes the volume level into the CenRep, if: + // 1) audio is playing or + // 2) video is playing and video has audio and silent mode is not On + // + // Sets the volume level into audio/video player if + // 1) as above + // 2) video is playing and silent mode is On + // + if ( aAudioPlaying + || ( !aAudioPlaying + && iViewerFlags & EVideoHasAudio ) ) + { + if ( !aAudioPlaying + && iViewerFlags & EVideoHasAudio + && !IsSilenceL( ) ) + { + updateIntoCenRepAllowed = ETrue; + } + else if ( !aAudioPlaying ) + { + updateIntoCenRepAllowed = EFalse; + } + + // First determine new value to be written into Cenrep + TInt currVolume( KVolumeDefault ); + if ( aChange ) + { + iMmsRepository->Get( KMmsuiHandsfreeVolume, currVolume ); + newVolume = currVolume+aVolume; + } + else + { + // force change + currVolume = KErrNotFound; + } + // else - newVolume has correct value and currVolume forces always change + + newVolume = Max( KVolumeControlMinValue, + Min( KVolumeControlMaxValue, newVolume ) ); + if ( updateIntoCenRepAllowed + && newVolume != currVolume ) + { + iMmsRepository->Set( KMmsuiHandsfreeVolume, newVolume ); + } + + // Then write the value into control + if ( aAudioPlaying ) + { + if (iAudio) + { + TInt maxVolume = reinterpret_cast(iAudio)->MaxVolume( ); + reinterpret_cast(iAudio)-> + SetVolume( ( newVolume * maxVolume ) / KVolumeLevels ); + } + } + else + { + if ( iVideo ) + { + if ( !updateIntoCenRepAllowed ) + { + newVolume = KVolumeControlMinValuePlayer; + } + + TInt maxVolume = reinterpret_cast( iVideo )->MaxVolume( ); + TInt dummy(KErrNone); + TRAP( dummy, + reinterpret_cast(iVideo)-> + SetVolumeL( ( newVolume * maxVolume ) / KVolumeLevels ) ); + } + } + } + if ( !updateIntoCenRepAllowed ) + { + newVolume = KErrNotFound; + } + return newVolume; + } + +// --------------------------------------------------------- +// ShowVolumeL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ShowVolumeL( TInt aNewVolume, + TBool aAudioPlaying ) + { + // Shows volume control, if: + // 1) audio is playing or + // 2) video is playing and (either or both of the below conditions is ETrue ) + // - silent mode is not On or + // - video has audio + if ( aAudioPlaying + || ( !aAudioPlaying + && ( iViewerFlags & EVideoHasAudio ) + || !IsSilenceL( ) ) ) + { + if ( !iVolumeDecorator ) + { + iVolumeDecorator = iNaviPane->CreateVolumeIndicatorL( R_AVKON_NAVI_PANE_VOLUME_INDICATOR ); + +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + static_cast + ( iVolumeDecorator->DecoratedControl() )->SetObserver( this ); + } +#endif + } + + if ( ! ( iViewerFlags & EVolumeControlTriggered ) ) + { + // Set new volume and show it + static_cast + ( iVolumeDecorator->DecoratedControl() )->SetValue( aNewVolume ); + } + iNaviPane->PushL( *iVolumeDecorator ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MsgAsyncControlStateChanged +// --------------------------------------------------------- +// +void CMmsViewerAppUi::MsgAsyncControlStateChanged( + CMsgBaseControl& aControl, + TMsgAsyncControlState aNewState, + TMsgAsyncControlState aOldState ) + + { + switch ( aControl.ControlId( ) ) + { + case EMsgComponentIdAudio: + case EMsgComponentIdVideo: + case EMsgComponentIdImage: + case EMsgComponentIdSvg: + // Must be derived from CMsgMediaControl + TRAP_IGNORE( DoMsgMediaControlStateChangedL( + static_cast( aControl ), + aNewState, + aOldState ) ); + break; + default: + // not derived from CMsgMediaControl + break; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MsgAsyncControlStateChanged +// --------------------------------------------------------- +void CMmsViewerAppUi::MsgAsyncControlResourceChanged( CMsgBaseControl& aControl, TInt aType ) + { + if ( aType == KEikDynamicLayoutVariantSwitch && + aControl.ControlType() == EMsgImageControl ) + { + CMsgImageControl& imageControl = static_cast( aControl ); + + if ( imageControl.IconBitmapId() == EMbmMmsuiQgn_graf_mms_play ) + { + // 3GPP icons needs to be handled by ourself + TAknLayoutRect iconLayout; + iconLayout.LayoutRect( MsgEditorCommons::MsgDataPane(), + AknLayoutScalable_Apps::msg_data_pane_g4().LayoutLine() ); + + TRAP_IGNORE( imageControl.SetIconSizeL( iconLayout.Rect().Size() ) ); + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoMsgMediaControlStateChangingL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoMsgMediaControlStateChangedL( + CMsgMediaControl& aControl, + TMsgAsyncControlState aNewState, + TMsgAsyncControlState aOldState ) + { +#ifdef USE_LOGGER + switch ( aControl.ControlId( ) ) + { + case EMsgComponentIdAudio: + LOGTEXT2(_L16("CMmsViewerAppUi::MsgMediaControlStateChanged. Audio: Old state %d"), aOldState ); + LOGTEXT2(_L16(" Audio: new state %d"), aNewState ); + LOGTEXT2(_L16(" Audio: error %d"), aControl.Error() ); + if ( aNewState == EMsgAsyncControlStateReady ) + { + LOGTIMESTAMP("CMmsViewerAppUi::DoMsgMediaControlStateChangedL Audio is ready "); + } + break; + case EMsgComponentIdVideo: + LOGTEXT2(_L16("CMmsViewerAppUi::MsgMediaControlStateChanged. Video: Old state %d"), aOldState ); + LOGTEXT2(_L16(" Video: new state %d"), aNewState ); + LOGTEXT2(_L16(" Video: error %d"), aControl.Error() ); + if ( aNewState == EMsgAsyncControlStateReady ) + { + LOGTIMESTAMP("CMmsViewerAppUi::DoMsgMediaControlStateChangedL Video is ready "); + } + break; + case EMsgComponentIdImage: + LOGTEXT2(_L16("CMmsViewerAppUi::MsgMediaControlStateChanged. Image: Old state %d"), aOldState ); + LOGTEXT2(_L16(" Image: new state %d"), aNewState ); + LOGTEXT2(_L16(" Image: error %d"), aControl.Error() ); + if ( aNewState == EMsgAsyncControlStateReady ) + { + LOGTIMESTAMP("CMmsViewerAppUi::DoMsgMediaControlStateChangedL Image is ready "); + } + break; + case EMsgComponentIdSvg: + LOGTEXT2(_L16("CMmsViewerAppUi::MsgMediaControlStateChanged. Svg: Old state %d"), aOldState ); + LOGTEXT2(_L16(" Svg: new state %d"), aNewState ); + LOGTEXT2(_L16(" Svg: error %d"), aControl.Error() ); + if ( aNewState == EMsgAsyncControlStateReady ) + { + LOGTIMESTAMP("CMmsViewerAppUi::DoMsgMediaControlStateChangedL Svg is ready "); + } + break; + default: + // not derived from CMsgMediaControl + break; + } +#endif + + // Resets iOpeningState + ShowPendingNoteL( ); + + // component independent + switch ( aNewState ) + { + case EMsgAsyncControlStatePlaying: + UpdatePanesL( MediaIsRunning( iAudio ) ,MediaIsRunning( iVideo ) ); + break; + + case EMsgAsyncControlStateStopped: + case EMsgAsyncControlStateNoRights: + case EMsgAsyncControlStateCorrupt: + UpdatePanesL( EFalse, EFalse ); + break; + + default: + break; + } + + // Keep UpdateMskL() after UpdatePanesL( ) + UpdateMskL( ); + + // component specific + switch ( aControl.ControlId( ) ) + { + case EMsgComponentIdVideo: + { + if ( aNewState == EMsgAsyncControlStateReady && + !static_cast( aControl ).HasAudioL() ) + { + iViewerFlags &= ~EVideoHasAudio; + } + else if ( aNewState == EMsgAsyncControlStateReady ) + { + // Lie that video is playing to set initial volume level. + DoChangeVolumeL( 0, ETrue, EFalse ); + } +#ifdef USE_LOGGER + if ( aNewState == EMsgAsyncControlStateReady ) + { + LOGTEXT2(_L16("CMmsViewerAppUi::DoMsgMediaControlStateChangedL. Video: HasAudioL()? %d"), static_cast( aControl ).HasAudioL() ); + } +#endif + if ( aNewState == EMsgAsyncControlStateStopped + || aNewState == EMsgAsyncControlStateNoRights + || aNewState == EMsgAsyncControlStateCorrupt ) + { + CUniObject* object = ObjectByMediaControl( aControl ); + if ( object + && object->DrmInfo( ) ) + { + TInt err = object->DrmInfo( )->ReleaseRights( ); + } + } + break; + } + // fall through + case EMsgComponentIdAudio: + { + if ( aNewState == EMsgAsyncControlStateReady ) + { + // Lie that audio is playing to set initial volume level. + DoChangeVolumeL( 0, ETrue, ETrue ); + } + if ( aNewState == EMsgAsyncControlStateStopped + || aNewState == EMsgAsyncControlStateNoRights + || aNewState == EMsgAsyncControlStateCorrupt ) + { + CUniObject* object = ObjectByMediaControl( aControl ); + if ( object + && object->DrmInfo( ) ) + { + TInt err = object->DrmInfo( )->ReleaseRights( ); + } + } + break; + } + case EMsgComponentIdImage: + StartAnimationL(); + // fall through + case EMsgComponentIdSvg: + if ( aNewState == EMsgAsyncControlStateIdle ) + { + CUniObject* object = ObjectByMediaControl( aControl ); + if ( object + && object->DrmInfo( ) ) + { + TInt err = object->DrmInfo( )->ReleaseRights( ); + } + } + break; + default: + break; + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::LaunchHelpL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::LaunchHelpL( ) + { + // activate Help application + + if ( iSupportedFeatures & EMmsFeatureHelp ) + { + CArrayFix* helpContext = AppHelpContextL( ); + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession( ), helpContext ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::HelpContextL +// --------------------------------------------------------- +// +CArrayFix* CMmsViewerAppUi::HelpContextL( ) const + { + if ( iSupportedFeatures & EMmsFeatureHelp ) + { + CArrayFix* r = new ( ELeave ) CArrayFixFlat(1); + CleanupStack::PushL( r ); + r->AppendL( TCoeHelpContext( KUidMmsViewer, KMMS_HLP_MMS_VIEWER( ) ) ); + CleanupStack::Pop( r ); + return r; + } + return NULL; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::SetFindModeL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SetFindModeL( TBool aEnable ) + { + if ( iView ) + { + if ( iView->ItemFinder( ) ) + { + TInt findMode = aEnable ? + CItemFinder::EPhoneNumber | + CItemFinder::EUrlAddress | + CItemFinder::EEmailAddress : + CItemFinder::ENoneSelected; + iView->ItemFinder( )->SetFindModeL( findMode ); + } + CMsgBaseControl* fromControl = iView->ControlById( EMsgComponentIdFrom ); + if ( fromControl && iMtm->Sender( ).Length( ) ) + { + static_cast( fromControl ) + ->SetAddressFieldAutoHighlight( aEnable ); + } + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaOpenL +// for single control +// --------------------------------------------------------- +// This function is entered when selection key is pressed. +// Actions allowed are play, embedded play, activate and get rights. +void CMmsViewerAppUi::MediaOpenL( CMsgMediaControl* aMedia ) + { + if ( aMedia ) + { + if ( MediaInitializedL( aMedia ) ) + { + MediaPlayL( aMedia ); + } + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaPlayL +// for single control +// --------------------------------------------------------- +void CMmsViewerAppUi::MediaPlayL(CMsgMediaControl* aMedia) + { + if ( aMedia ) + { + CUniObject* currObject = ObjectByMediaControl( *aMedia ); + if ( currObject + && currObject->Corrupted() ) + { + UpdatePanesL( MediaIsRunning( iAudio ) ,MediaIsRunning( iVideo ) ); + UpdateMskL( ); + ShowInformationNoteL( R_QTN_MMS_CANNOT_OPEN_CORRUPTED ); + return; + } +#ifdef RD_SVGT_IN_MESSAGING + if ( aMedia == iSvgt || aMedia == iImage ) + { + ViewImageL( *aMedia ); + } +#else + if (aMedia == iImage) + { + ViewImageL( reinterpret_cast< CMsgImageControl& >( *aMedia ) ); + } +#endif + else + { + if (aMedia == iVideo) + { + if(IsVideoCall()) + { + ShowInformationNoteL( R_MMSVIEWER_CANNOT_PLAY_VIDEOCALL_ONGOING ); + return; + } + reinterpret_cast(aMedia)->ContinueOnFocus( ETrue ); + } + else if ( aMedia == iAudio ) + { + __ASSERT_ALWAYS( ObjectByMediaControl( *iAudio ) || ObjectByMediaControl( *iAudio )->MediaInfo( ), + Panic( EMmsViewerNullPointer ) ); + CUniObject* obj = ObjectByMediaControl( *iAudio ); + // Coverty fix, Null pointer return, http://ousrv057/cov.cgi?cid=37099 + if (obj) + { + if ( iViewerFlags & EProhibitNonDrmMusic + && !( obj->MediaInfo( )->Protection( ) & + ( EFileProtSuperDistributable | EFileProtForwardLocked ) ) ) + { + // Prepare buffer for aMimeType + HBufC* mimeBuffer = HBufC::NewLC( obj->MimeType().Length() + KMmsViewerSpace().Length() ); + TPtr mimeBufferPtr = mimeBuffer->Des(); + mimeBufferPtr.Copy( obj->MimeType() ); + + // FindF() would find "audio/3gpp" in "audio/3gpp2" without + // the added space. + mimeBufferPtr.Append( KMmsViewerSpace ); + + // If result is not KErrNotFound, this MIME-type is indeed on blocked list. + if ( iProhibitMimeTypeBuffer->FindF( mimeBufferPtr ) >= 0 ) + { + ShowInformationNoteL( R_MMSVIEWER_PLAIN_MUSIC_PROHIBITED ); + /* Allocated buffer must be destroyed and pop'd !!! */ + CleanupStack::PopAndDestroy( mimeBuffer ); + return; + } + /* Allocated buffer must be destroyed and pop'd !!! */ + CleanupStack::PopAndDestroy( mimeBuffer ); + } + } + if ( IsSilenceL( ) + && !ShowConfirmationQueryL( R_QTN_MMS_OBEY_SILENT_MODE ) ) + { + return; + } + } + + if ( !HandleConsumeRightsL( *aMedia ) ) + { + UpdatePanesL( MediaIsRunning( iAudio ) ,MediaIsRunning( iVideo ) ); + UpdateMskL( ); + return; + } + aMedia->PlayL( ); + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaStop +// for every control +// --------------------------------------------------------- +// +void CMmsViewerAppUi::MediaStop( ) + { + MediaStop( iImage ); + MediaStop( iAudio ); + MediaStop( iVideo ); +#ifdef RD_SVGT_IN_MESSAGING + MediaStop( iSvgt ); +#endif + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaStop +// for single control +// --------------------------------------------------------- +// +void CMmsViewerAppUi::MediaStop(CMsgMediaControl* aMedia ) + { + if ( MediaCanStop( aMedia ) ) + { + if (aMedia == iVideo) + { + reinterpret_cast( aMedia )->ContinueOnFocus( EFalse ); + } + CUniObject* object = ObjectByMediaControl( *aMedia ); + if ( object + && object->DrmInfo( ) ) + { + TInt err = object->DrmInfo( )->ReleaseRights( ); + } + aMedia->Stop( ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaClose +// for every control +// --------------------------------------------------------- +// +void CMmsViewerAppUi::MediaClose( ) + { + MediaClose( iImage ); + MediaClose( iAudio ); + MediaClose( iVideo ); +#ifdef RD_SVGT_IN_MESSAGING + MediaClose( iSvgt ); +#endif + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaClose +// for single control +// --------------------------------------------------------- +// +void CMmsViewerAppUi::MediaClose(CMsgMediaControl* aMedia) + { + if ( aMedia ) + { + if ( MediaCanStop ( aMedia ) ) + { + aMedia->Stop( ); + } + + // Release rights - image only + if ( aMedia + && iImage == aMedia ) + { + CUniObject* object = ObjectByMediaControl( *aMedia ); + if ( object + && object->DrmInfo( ) ) + { + TInt err = object->DrmInfo( )->ReleaseRights( ); + } + } + aMedia->Close( ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ReloadSlideL +// for every control +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ReloadSlideL( ) + { + LOGTEXT(_L8("CMmsViewerAppUi::ReloadSlideL")); + // Get focused control to restore focus after other view + if ( iView->FocusedControl( ) ) + { + iFocusedControlId = iView->FocusedControl( )->ControlId(); + if ( iFocusedControlId ) + { + // Disable autofind temporarily, if On, because when slide is reloaded + // focus moves to From: field temporarily. + // Autohighlight is disabled temporarily + if ( !IsOwnMessage( ) + && iFocusedControlId != EMsgComponentIdFrom ) + { + // Get highlight status + TInt highlight = 0; + iCUiRepository->Get( KCuiAutomaticHighlight, highlight ); + if ( highlight ) + { + SetFindModeL( EFalse ); + } + } + } + } + + if ( Document( )->SmilType( ) == EMmsSmil ) + { + ChangeSlideL( Document( )->CurrentSlide( ), EFalse ); + } + SetFindModeL( iViewerFlags & EAutohighLightEnabled ); + + InitNavipaneL( ); + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ReloadControlL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ReloadControlL( CMsgMediaControl* aControl, CUniObject& aObject ) + { + LOGTEXT(_L8("CMmsViewerAppUi::ReloadControlL")); + if ( aControl + && Document( )->SmilType( ) == EMmsSmil ) + { + // Get focused control to restore focus after other view + if ( iView->FocusedControl( ) ) + { + iFocusedControlId = iView->FocusedControl( )->ControlId(); + if ( iFocusedControlId ) + { + // Disable autofind temporarily, if On, because when slide is reloaded + // focus moves to From: field temporarily. + // Autohighlight is disabled temporarily + if ( !IsOwnMessage( ) + && iFocusedControlId != EMsgComponentIdFrom ) + { + // Get highlight status + TInt highlight = 0; + iCUiRepository->Get( KCuiAutomaticHighlight, highlight ); + if ( highlight ) + { + SetFindModeL( EFalse ); + } + } + } + } + + MediaStop( ); + + if ( iVideo + && iVideo == aControl ) + { + iScreenClearer = CAknLocalScreenClearer::NewLC( EFalse ); + CleanupStack::Pop( iScreenClearer ); + } + + iViewerState = EBusy; + iOpeningState = EOpeningSlide; + iViewerFlags |= EVideoHasAudio; + iVideo = NULL; + iAudio = NULL; + iImage = NULL; + #ifdef RD_SVGT_IN_MESSAGING + iSvgt = NULL; + #endif + iPendingNoteResource = KInvalidResourceId; + iPendingNotePriority = 0; + iPendingNoteObject = NULL; + iPendingNoteError = KErrNone; + + delete iFindItemMenu; + iFindItemMenu = NULL; + + UpdateMskL(); + + if ( !iChangeSlideOperation ) + { + iChangeSlideOperation = new ( ELeave )CMmsViewerChangeSlideOperation ( + *this, + *( Document( ) ), + *iHeader, + *iSlideLoader, + *iView, + iCoeEnv->FsSession( ) ); + } + + ActivateInputBlockerL( iChangeSlideOperation ); + iChangeSlideOperation->ReLoadControlL( aControl, &aObject ); + + // TODO: Get rid of active wait! + BeginActiveWait( iChangeSlideOperation ); + InitNavipaneL( ); + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::StopAnimation +// --------------------------------------------------------- +// +void CMmsViewerAppUi::StopAnimation( ) + { + if ( iImage + && iImage->IsAnimation( ) ) + { + iImage->Stop( ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::StartAnimationL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::StartAnimationL( ) + { + if ( iImage + && iImage->IsAnimation( ) ) + { + TMsgAsyncControlState state = iImage->State( ); + if ( state == EMsgAsyncControlStateReady + || state == EMsgAsyncControlStatePaused + || state == EMsgAsyncControlStateStopped ) + { + iImage->PlayL( ); + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ViewerOperationEvent +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ViewerOperationEvent( + TMmsViewerOperationType aOperation, + TMmsViewerOperationEvent aEvent, + TInt aError) + { + if ( aEvent == EMmsViewerOperationCancel ) + { + LOGTEXT(_L8("CMmsViewerAppUi::ViewerOperationEvent EMmsViewerOperationCancel") ); + // Operation by operation should be considered what is proper action + // in Cancel situation + ResetOperationState(); + return; + } + + if ( aOperation == EMmsViewerOperationReadReport + && aEvent == EMmsViewerOperationError ) + { + // Not worth exiting + aError = KErrNone; + } + + TInt error(aError); + if ( !error ) + { + + TRAP( error, DoViewerOperationEventL( aOperation, aEvent ) ); + if ( aEvent == EMmsViewerOperationCancel ) + { + // ignore errors + error = KErrNone; + } + } + else + { + ResetOperationState(); + if ( error == KErrCorrupt ) + { + TRAP_IGNORE( ShowErrorNoteL( R_MMSVIEWER_ERROR_MSG_CORRUPT ) ); + } + } + + if ( error ) + { + MediaStop( ); + Exit( error ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::ViewerOperationEvent +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoViewerOperationEventL( + TMmsViewerOperationType aOperation, + TMmsViewerOperationEvent aEvent ) + { + TInt error( KErrNone ); + switch ( aOperation ) + { + case EMmsViewerOperationChangeSlide: + { + EndActiveWait( ); + // restore focus + if ( iFocusedControlId > EMsgComponentIdNull ) + { + if ( FocusedControlId( ) != iFocusedControlId ) + { + CMsgBaseControl* control = iView->ControlById( iFocusedControlId ) ; + if ( control ) + { + iView->SetFocus( iFocusedControlId ); + } + } + iFocusedControlId = EMsgComponentIdNull; + } + iImage = reinterpret_cast< CMsgImageControl* > + ( iView->ControlById( EMsgComponentIdImage ) ); + HandleImageNoRightsInLaunch( ); + StartAnimationL( ); + iAudio = reinterpret_cast< CMsgAudioControl* > + ( iView->ControlById( EMsgComponentIdAudio ) ); + iVideo = reinterpret_cast< CMsgVideoControl* > + ( iView->ControlById( EMsgComponentIdVideo ) ); +#ifdef RD_SVGT_IN_MESSAGING + iSvgt = reinterpret_cast< CMsgSvgControl* > + ( iView->ControlById( EMsgComponentIdSvg ) ); +#endif + break; + } + case EMmsViewerOperationLaunch: + { + if ( aEvent == EMmsViewerOperationCancel ) + { + return; + } + else + { + LOGTEXT(_L8("CMmsViewerAppUi::DoViewerOperationEventL DoViewerOperationEventLaunchL in ")); + TRAP( error, DoViewerOperationEventLaunchL( ) ); + LOGTEXT(_L8("CMmsViewerAppUi::DoViewerOperationEventL DoViewerOperationEventLaunchL out ")); + } + break; + } + case EMmsViewerOperationReadReport: + // free resources + DeactivateInputBlocker(); + delete iSendReadReportOperation; + iSendReadReportOperation = NULL; + // Viewer is already running normally + return; + + default: + break; + } + + ResetOperationState(); + User::LeaveIfError( error ); + + SetFindModeL( iViewerFlags & EAutohighLightEnabled ); + ShowPendingNoteL( ); + + // iViewer state must be ENormal. + // UpdateMskL() must be after UpdatePanesL() + UpdatePanesL( EFalse, EFalse ); + UpdateMskL( ); + + // Call of SendReadReportL cannot be in DoViewerOperationEventLaunchL, because + // ResetOperationState() deletes the input blocker launched from SendReadReportL + if ( aOperation == EMmsViewerOperationLaunch + && aEvent == EMmsViewerOperationComplete ) + { + // Less important stuff follows. + // It is OK, that flags and state indicate successful launch +#ifndef USE_LOGGER + TRAP_IGNORE( SendReadReportL( aOperation, aEvent ) ); +#else + TRAPD( error, SendReadReportL( aOperation, aEvent ) ); + if ( error ) + { + LOGTEXT2(_L16("CMmsViewerAppUi::DoViewerOperationEventLaunchL SendReadReportL error %d"), error ); + } +#endif // USE_LOGGER + } + } + +// --------------------------------------------------------- +// DoViewerOperationEventLaunchL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoViewerOperationEventLaunchL( ) + { + if ( Document( )->ParseResult( ) & + ( ERegionMediaTypeMismatch | EBadlyReferencedObjects ) ) + { + iViewerFlags |= ESuspiciousSmil; + } + + iSmilModel = Document( )->SmilModel( ); + iHeader = iLaunchOperation->DetachHeader( ); + iSlideLoader = iLaunchOperation->DetachSlideLoader( ); + + TMsvEntry entry = iMtm->Entry( ).Entry( ); + if ( entry.iMtmData1 & EMmsDrmCorruptedAttachment ) + { + SetPendingNote( R_MMSVIEWER_DRM_OBJECT_REMOVED ); + } + + // Condition was EUnsupportedObjects, but region may be resolved even + // if it is set. + if ( Document( )->ParseResult( ) & EBadlyReferencedObjects ) + { + SetPendingNote( R_MMSVIEWER_CANNOT_DISPLAY_OBJECTS ); + } + + if ( Document( )->AttachmentList( )->Count( ) ) + { + SetPendingNote( R_MMSVIEWER_CANNOT_DISPLAY_OBJECTS ); + } + + ResolveDrmWaitingNotes( ); // e.g. R_MMSVIEWER_DRM_PREVIEW_RIGHTS + + TInt focusedControl = ( Document( )->SmilType( ) != EMmsSmil ) + ? EMsgComponentIdImage + : EMsgComponentIdNull; + iView->ExecuteL( ClientRect( ), focusedControl ); + + SetTitleIconL(); + InitNavipaneL( ); + TRAP_IGNORE( CheckAndSetDescriptionL( ) ); + + if (focusedControl != EMsgComponentIdImage ) + { + // 3GPP icon is not assigned + iImage = reinterpret_cast< CMsgImageControl* > + ( iView->ControlById( EMsgComponentIdImage ) ); + HandleImageNoRightsInLaunch( ); + StartAnimationL( ); + } + iAudio = reinterpret_cast< CMsgAudioControl* > + ( iView->ControlById( EMsgComponentIdAudio ) ); + iVideo = reinterpret_cast< CMsgVideoControl* > + ( iView->ControlById( EMsgComponentIdVideo ) ); +#ifdef RD_SVGT_IN_MESSAGING + iSvgt = reinterpret_cast< CMsgSvgControl* > + ( iView->ControlById( EMsgComponentIdSvg ) ); +#endif + // Enable task swapper to options menu after launch has been completed. + MenuBar()->SetMenuType( CEikMenuBar::EMenuOptions ); + +#ifdef RD_SCALABLE_UI_V2 + if ( iToolbar ) + { + SetToolBarItemVisibilities(); + } +#endif + } + +// --------------------------------------------------------- +// BeginActiveWait +// --------------------------------------------------------- +// +void CMmsViewerAppUi::BeginActiveWait( CMmsViewerOperation* aOperation ) + { + if( iWait.IsStarted() ) + { + if ( iActiveOperation ) + { + iActiveOperation->Cancel(); + } + else + { + return; + } + } + iActiveOperation = aOperation; + iWait.Start(); + } + +// --------------------------------------------------------- +// EndActiveWait +// --------------------------------------------------------- +// +void CMmsViewerAppUi::EndActiveWait( ) + { + if( !iWait.IsStarted( ) ) + { + return; + } + iWait.AsyncStop( ); + iActiveOperation = NULL; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::FocusedControlId +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::FocusedControlId( ) + { + TInt controlType = EMsgComponentIdNull; + if ( iView && iView->FocusedControl( ) ) + { + controlType = iView->FocusedControl( )->ControlId( ); + } + return controlType; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaControlById +// --------------------------------------------------------- +// +CMsgMediaControl* CMmsViewerAppUi::MediaControlById(TInt aControl) + { + CMsgMediaControl* control = NULL; + switch (aControl) + { + case EMsgComponentIdVideo: + control = iVideo; + break; + case EMsgComponentIdAudio: + control = iAudio; + break; + case EMsgComponentIdImage: + control = iImage; + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMsgComponentIdSvg: + control = iSvgt; + break; +#endif + default: + break; + } + return control; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaInitializedL +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::MediaInitializedL( CMsgMediaControl* aMedia ) + { + if ( aMedia ) + { + TBool noRights( EFalse ); + CUniObject* currObject = ObjectByMediaControl( *aMedia ); + // test has two purpose + // If object has not rights, assume it is initialised. + // Image: If rights have not been consumed, object had not rights. + // Other objects: DRM rights do not matter, because they are handled separately during + // 'launch'. + if ( currObject + && currObject->DrmInfo() ) + { + if ( aMedia == iImage ) + { + noRights = !IsRightsConsumed( *currObject ); + } + else + { + noRights = ( !IsRightsConsumed( *currObject ) + && !IsRightsNow( *currObject ) ); + } + } + + if ( noRights || MediaCanPlay( aMedia, currObject ) ) + { + return ETrue; + } + else + { + return EFalse; + } + } + // else - no media - assume initialized + return ETrue; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaCanPlay( ) +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::MediaCanPlay(const CMsgMediaControl* aMedia, + const CUniObject* aMmsObject ) const + { + TBool corrupted( EFalse ); + if ( aMmsObject + && aMmsObject->Corrupted() ) + { + corrupted = ETrue; + } + + if ( aMedia ) + { + TMsgAsyncControlState state = aMedia->State( ); + if ( state == EMsgAsyncControlStateReady + || state == EMsgAsyncControlStatePaused + || state == EMsgAsyncControlStateStopped + || state == EMsgAsyncControlStateNoRights + || state == EMsgAsyncControlStateCorrupt + || corrupted + || ( aMedia == iImage + && ( state == EMsgAsyncControlStatePlaying + || state == EMsgAsyncControlStatePaused ) + && iImage->IsAnimation() ) ) + { + return ETrue; + } + } + return EFalse; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaCanStop( ) +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::MediaCanStop(CMsgMediaControl* aMedia) + { + if ( aMedia ) + { + TMsgAsyncControlState state = aMedia->State( ); + if ( state == EMsgAsyncControlStateAboutToPlay + || state == EMsgAsyncControlStateBuffering + || state == EMsgAsyncControlStatePlaying + || state == EMsgAsyncControlStatePaused ) + { + return ETrue; + } + } + return EFalse; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::MediaIsRunning( ) +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::MediaIsRunning(CMsgMediaControl* aMedia) + { + if ( aMedia ) + { + TMsgAsyncControlState state = aMedia->State( ); + if ( state == EMsgAsyncControlStatePlaying ) + { + return ETrue; + } + } + return EFalse; + } + + + +// --------------------------------------------------------- +// CMmsViewerAppUi::ResolveDrmWaitingNotes( ) +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ResolveDrmWaitingNotes( ) + { + // resolve need of R_MMSVIEWER_DRM_PREVIEW_RIGHTS + TBool jumpOut(EFalse); + + // go through all recipients + CUniObjectList* objectList = Document( )->ObjectList( ); + TInt objectCount = 0; + if (objectList) + { + objectCount = objectList->Count( ); + } + + for ( TInt i = 0; i < objectCount && !jumpOut; i++ ) + { + CUniObject* obj = objectList->GetByIndex( i ); + if ( obj ) + { + switch ( obj->Region( ) ) + { + case EUniRegionImage: + // fall through + case EUniRegionAudio: + if ( obj->DrmInfo( ) + && obj->DrmInfo( )->IsDrmWithOnePreview( ) ) + { + SetPendingNote( R_MMSVIEWER_DRM_PREVIEW_RIGHTS, obj ); + jumpOut = ETrue; + } + break; + case EUniRegionText: + case EUniRegionUnresolved: + default: + // not interested + break; + } + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::SaveObjectL( ) +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SaveObjectL( ) + { + // returns only image, audio, video and svg controls + CMsgMediaControl* mediaControl = MediaControlById( FocusedControlId( ) ); + CMsgBaseControl* control = mediaControl; + if ( !control ) + { + if ( iView->FocusedControl() + && iView->FocusedControl()->ControlType() == EMsgXhtmlBodyControl ) + { + control = iView->FocusedControl(); + } + } + + if ( control ) + { + // if-branch intended for multimedia and xHTML + CUniObject* obj = ObjectByBaseControl( *control ); + if ( obj ) + { + DoSaveObjectL( *obj ); + } + } + else if (FocusedControlId( ) == EMsgComponentIdBody ) + { + CUniObject* textObj = NULL; + TUint objectCount = iSmilModel->SlideObjectCount( Document( )->CurrentSlide( ) ); + for ( TUint i = 0; i < objectCount; i++ ) + { + CUniObject* obj = iSmilModel->GetObjectByIndex( Document( )->CurrentSlide( ), i ); + if ( obj->Region( ) == EUniRegionText ) + { + // found + textObj = obj; + break; + } + } + + if ( textObj + && textObj->MediaType( ) == EMsgMediaText ) + { + // Save text files directly to Notepad. + // This is needed because automatic character set recognation + // is not too reliable. + TUint mibCharset = textObj->MimeInfo( )->Charset( ); + if ( !mibCharset ) + { + //assume US-ASCII - mandated by RFC 2046 + mibCharset = KCharacterSetMIBEnumUsAscii; + } + + TUint charconvCharsetID = Document( )->DataUtils( )->MibIdToCharconvIdL( mibCharset ); + RFile textFile = Document( )->GetAttachmentFileL( *textObj ); + + CleanupClosePushL( textFile ); + + CNotepadApi::SaveFileAsMemoL( + textFile, + charconvCharsetID ); + + CleanupStack::PopAndDestroy(&textFile); + + // Show confirmation note + RApaLsSession appList; + if ( appList.Connect( ) == KErrNone ) + { + TApaAppInfo appInfo; + if ( appList.GetAppInfo( appInfo, KNotepadUID3 ) == KErrNone ) + { + textObj->SetSaved( ETrue ); + HBufC* text = StringLoader::LoadLC( R_MMS_FILE_SAVED_TO, appInfo.iCaption ); + CAknConfirmationNote* note = new ( ELeave ) CAknConfirmationNote( ETrue ); + note->ExecuteLD( *text ); + CleanupStack::PopAndDestroy( text ); + } + appList.Close( ); + } + } + } + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::DoSaveObjectL( ) +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoSaveObjectL(CUniObject& aObject ) + { + CMsgMediaInfo* media = aObject.MediaInfo( ); + if ( media ) + { + TParsePtrC plainFileName( media->FullFilePath( ) ); + const TPtrC newName = plainFileName.NameAndExt( ); + TDataType dataType( aObject.MimeType( ) ); + + CDocumentHandler* docHandler = CDocumentHandler::NewL( ); + CleanupStack::PushL(docHandler); + + RFile mediaFile = Document( )->GetAttachmentFileL( aObject ); + CleanupClosePushL( mediaFile ); + + TInt ret = docHandler->CopyL( mediaFile, + newName, + dataType, + KEntryAttNormal ); + if ( ret != KErrNone && ret != KUserCancel ) + { + User::LeaveIfError( ret ); + } + else if ( ret == KErrNone ) + { + aObject.SetSaved( ETrue ); + } + + CleanupStack::PopAndDestroy(2, docHandler); // + mediaFile + } + } + + +// ---------------------------------------------------- +// IsSilenceL +// +// ---------------------------------------------------- +TBool CMmsViewerAppUi:: IsSilenceL( ) + { + TBool result( EFalse ); + + CRepository* repository = CRepository::NewLC( KCRUidProfileEngine ); + + TInt ringType( EProfileRingingTypeRinging ); + User::LeaveIfError( repository->Get( KProEngActiveRingingType, ringType ) ); + CleanupStack::PopAndDestroy( repository ); + + if ( ringType == EProfileRingingTypeSilent ) + { + result = ETrue; + } + return result; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::OpenDeliveryPopupL( ) +// Forwards the request to the MMS UI +// --------------------------------------------------------- +// +void CMmsViewerAppUi::OpenDeliveryPopupL( ) + { + + //These are not used! They just have to be there. + TPckgBuf param( 0 ); + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + + CMsvSingleOpWatcher* watch = CMsvSingleOpWatcher::NewLC( *Document( ) ); + CMsvOperation* op = Document( )->MtmUiL( ).InvokeAsyncFunctionL( + KMtmUiFunctionDeliveryStatus, + *selection, + watch->iStatus, + param ); // launch the dialog through MMSUI + CleanupStack::Pop( watch ); + Document( )->AddSingleOperationL( op, watch ); + + CleanupStack::PopAndDestroy( selection ); + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleResourceChangeL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleResourceChangeL(TInt aType) + { + // Base class call must be first + CMsgEditorAppUi::HandleResourceChangeL(aType); + + if ( iHeader ) + { + iHeader->HandleResourceChange(aType); + } + + if ( aType == KAknsMessageSkinChange ) + { + if ( iAppIcon ) + { + delete iAppIcon; + iAppIcon = NULL; + } + + // Set path of bitmap file + TParse fileParse; + fileParse.Set( KMmsUiMbmFile, &KDC_APP_BITMAP_DIR, NULL ); + + iAppIcon = AknsUtils::CreateGulIconL( + AknsUtils::SkinInstance(), + KAknsIIDQgnPropMceMmsTitle, + fileParse.FullName(), + EMbmMmsuiQgn_prop_mce_mms_title, + EMbmMmsuiQgn_prop_mce_mms_title_mask ); + SetTitleIconL(); + } + else if ( aType == KEikDynamicLayoutVariantSwitch && IsLaunched() ) + { + SetTitleIconL(); + } + } + +// --------------------------------------------------------- +// IsLaunched +// --------------------------------------------------------- +inline TBool CMmsViewerAppUi::IsLaunched( ) const + { + return ( iViewerFlags & ELaunchSuccessful ); + } + + +// --------------------------------------------------------- +// PrepareToExit +// --------------------------------------------------------- +void CMmsViewerAppUi::PrepareToExit( ) + { + CEikAppUi::PrepareToExit( ); + } + +// --------------------------------------------------------- +// ObjectByMediaControl +// --------------------------------------------------------- +CUniObject* CMmsViewerAppUi::ObjectByMediaControl( CMsgMediaControl& aControl ) + { + TInt controlId = aControl.ControlId( ); + if ( controlId == EMsgComponentIdImage + || controlId == EMsgComponentIdAudio + || controlId == EMsgComponentIdVideo +#ifdef RD_SVGT_IN_MESSAGING + || controlId == EMsgComponentIdSvg +#endif + ) + { + return ObjectByBaseControl( aControl ); + } + else + { + return NULL; + } + + } + +// --------------------------------------------------------- +// ObjectByBaseControl +// --------------------------------------------------------- +CUniObject* CMmsViewerAppUi::ObjectByBaseControl( CMsgBaseControl& aControl ) + { + TInt controlId = aControl.ControlId( ); + TUniRegion region( EUniRegionUnresolved ); + switch ( controlId ) + { + case EMsgComponentIdImage: + region = EUniRegionImage; + break; + case EMsgComponentIdAudio: + region = EUniRegionAudio; + break; + case EMsgComponentIdVideo: + region = EUniRegionImage; + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMsgComponentIdSvg: + region = EUniRegionImage; + break; +#endif + case EMsgComponentIdBody: + region = EUniRegionText; + break; + default: + break; + } + if ( region == EUniRegionUnresolved ) + { + return NULL; + } + + if ( iSmilModel ) + { + TInt countObjectsOnSlide( + iSmilModel->SlideObjectCount( Document( )->CurrentSlide( ) ) ); + for ( TInt i = 0; i < countObjectsOnSlide; i++ ) + { + CUniObject* object = iSmilModel->GetObject( + Document( )->CurrentSlide( ), region ); + if ( object ) + { + return object; + } + } + } + return NULL; + } + + +// --------------------------------------------------------- +// CMmsViewerAppUi::SetAndSaveDescriptionL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::CheckAndSetDescriptionL( ) + { + TMsvEntry tEntry = Document( )->Entry( ); + if( !tEntry.iDescription.Length( ) ) + { + // is it on current slide + CMsgBodyControl* bodyControl = static_cast + ( iView->ControlById( EMsgComponentIdBody ) ); + if ( bodyControl ) + { + SetAndSaveDescriptionL(bodyControl->TextContent( )); + } + else + { + // Continue searching from other slides + // Take first text attachment + CUniSmilModel* smilModel = Document( )->SmilModel( ); + if ( smilModel ) + { + // search for first text attachment + TInt slideCount = smilModel->SlideCount( ); + for (TInt slideI = 1; slideI < slideCount ; slideI++ ) + { + TInt objectCountOnSlide = smilModel->SlideObjectCount( slideI ); + for (TInt objectI = 0; objectI < objectCountOnSlide ; objectI++ ) + { + CUniObject* obj = smilModel->GetObjectByIndex( slideI, objectI ); + if ( obj + && obj->Region( ) == EUniRegionText ) + { + TUint attaCharset = obj->MimeInfo( )->Charset( ); + if ( !attaCharset ) + { + //assume US-ASCII - mandated by RFC 2046 + attaCharset = KMmsUsAscii; + } + + TUint charconvCharsetID = 0; + charconvCharsetID = Document( )->DataUtils()->MibIdToCharconvIdL( attaCharset ); + RFile file = Document( )->GetAttachmentFileL( *obj ); + CleanupClosePushL( file ); + + RFileReadStream stream( file ); + CleanupClosePushL( stream ); + + CPlainText::TImportExportParam param; + param.iForeignEncoding = charconvCharsetID; + param.iOrganisation = CPlainText::EOrganiseByParagraph; + + CPlainText::TImportExportResult result; + + CPlainText* plainText = CPlainText::NewL( ); + CleanupStack::PushL( plainText ); + + plainText->ImportTextL( 0, stream, param, result ); + SetAndSaveDescriptionL( *plainText ); + + CleanupStack::PopAndDestroy( 3, &file ); // plainText, file, stream + break; + } // else - no object or wrong type of object + } // for - objects of one slide + } // for - slides + }// else - no smil model + } // else - no body text on first slide + } // else - description exists + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::SetAndSaveDescriptionL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SetAndSaveDescriptionL(const CPlainText& aText) + { + TBuf description; + description.Zero( ); + aText.Extract( description, 0, KMmsMaxDescription ); + TInt length( description.Length( ) ); + while( length-- ) + { + + if ( description[length] == CEditableText::ETabCharacter + || description[length] == CEditableText::EPageBreak + || description[length] == CEditableText::ENonBreakingSpace + || description[length] == CEditableText::EHyphen + || description[length] == CEditableText::ENonBreakingHyphen + || description[length] == CEditableText::ELeftSingleQuote + || description[length] == CEditableText::ERightSingleQuote + || description[length] == CEditableText::ELeftDoubleQuote + || description[length] == CEditableText::ERightDoubleQuote + || description[length] == CEditableText::EBullet + || description[length] == CEditableText::EEllipsis + || description[length] == CEditableText::ELineBreak + || description[length] == CEditableText::EParagraphDelimiter + || description[length] == CEditableText::EPictureCharacter + || description[length] == CEditableText::EZeroWidthNoBreakSpace + || description[length] == CEditableText::EByteOrderMark + || description[length] == CEditableText::EReversedByteOrderMark + || description[length] == '\n' ) + { + description[length] = ' '; + } + } + description.Trim( ); + + if ( description.Length( ) > 0 ) + { + TMsvEntry tEntry = Document( )->Entry( ); + tEntry.iDescription.Set( description ); + Document( )->CurrentEntry( ).ChangeL( tEntry ); + } + } + + + +// --------------------------------------------------------- +// CMmsViewerAppUi::ViewImageL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ViewImageL( CMsgMediaControl& aMediaCtrl ) + { + CUniObject* launchObject = ObjectByMediaControl( aMediaCtrl ); + if ( !launchObject ) + { + return; + } + + if ( !iDocHandler ) + { + iDocHandler = CDocumentHandler::NewL( ); + iDocHandler->SetExitObserver( this ); + } + + if ( &aMediaCtrl == iImage && + ( reinterpret_cast< CMsgImageControl& >( aMediaCtrl ).IsAnimation() ) ) + { + aMediaCtrl.Stop( ); + } + + if ( launchObject->DrmInfo() ) + { + launchObject->DrmInfo()->ReleaseRights(); + } + + TDataType mimeDataType( launchObject->MimeType() ); + + RFile sharedFile = Document( )->GetAttachmentFileL( *launchObject ); + CleanupClosePushL( sharedFile ); + + CAiwGenericParamList* paramList = CAiwGenericParamList::NewLC(); + if ( !launchObject->IsSaved() ) + { + TAiwGenericParam genericParamAllowSave + ( EGenericParamAllowSave, ETrue); + paramList->AppendL( genericParamAllowSave ); + } + + TInt err( KErrNone ); + TRAP( err, err = iDocHandler->OpenFileEmbeddedL( sharedFile, + mimeDataType, + *paramList ) ); + LOGTEXT2(_L16("CMmsViewerAppUi::ViewImageL error %d"), err ); + CleanupStack::PopAndDestroy( 2, &sharedFile ); // + paramList + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleServerAppExit +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleServerAppExit(TInt /*aReason*/) + { + // Currently only image is possible + if ( iImage + && iImage->IsAnimation() ) + { + TRAP_IGNORE( iImage->PlayL( ) ); + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleConsumeRightsL +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::HandleConsumeRightsL( CMsgMediaControl& aMedia ) + { + TBool result( ETrue ); + + CUniObject* object = ObjectByMediaControl( aMedia); + TBuf defaultContent( ContentAccess::KDefaultContentObject( ) ); + if ( object + && object->DrmInfo( ) + && defaultContent == aMedia.UniqueContentId( ) ) + { + TInt err = object->DrmInfo( )->ConsumeRights( ); + switch ( err ) + { + case KErrNone: + break; + case DRMCommon::EGeneralError: + case DRMCommon::EUnknownMIME: + case DRMCommon::EVersionNotSupported: + case DRMCommon::ESessionError: + case DRMCommon::ENoRights: + case DRMCommon::ERightsDBCorrupted: + case DRMCommon::EUnsupported: + case DRMCommon::ERightsExpired: + case DRMCommon::EInvalidRights: + SetPendingNote( R_MMSVIEWER_DRM_ERROR, + object, + err ); + result = EFalse; + break; + default: + SetPendingNote(R_QTN_MMS_CANNOT_OPEN_CORRUPTED); + object->SetCorrupted( ETrue ); + result = EFalse; + break; + } + } + + if ( !result ) + { + iSlideLoader->UpdateControlIconL( aMedia, object ); + aMedia.DrawDeferred(); + ShowPendingNoteL( ); + } + return result; + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleImageNoRightsInLaunch +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleImageNoRightsInLaunch( ) + { + if ( iImage ) + { + CUniObject* object = ObjectByMediaControl( *iImage ); + if ( object + && object->DrmInfo( ) ) + { + TBool ignoreConsumed ( EFalse ); + TInt err = object->DrmInfo( )->EvaluateRights( ignoreConsumed ); + switch ( err ) + { + case KErrNone: + break; + case DRMCommon::EGeneralError: + case DRMCommon::EUnknownMIME: + case DRMCommon::EVersionNotSupported: + case DRMCommon::ESessionError: + case DRMCommon::ENoRights: + case DRMCommon::ERightsDBCorrupted: + case DRMCommon::EUnsupported: + case DRMCommon::ERightsExpired: + case DRMCommon::EInvalidRights: + SetPendingNote( R_MMSVIEWER_DRM_ERROR, + object, + err ); + break; + default: + break; + } + } + } + } + +// --------------------------------------------------------- +// CMmsViewerAppUi::UpdateMskL +// --------------------------------------------------------- +void CMmsViewerAppUi::UpdateMskL( ) + { + TInt resId = (-1); + if ( iView && iViewerState == ENormal ) + { + CMsgBaseControl* ctrl = iView->FocusedControl(); + if ( ctrl ) + { + // If entered here, some command must be set even empty + switch ( ctrl->ControlId() ) + { + case EMsgComponentIdAttachment: + resId = R_MMSVIEWER_MSK_BUTTON_OPEN_OBJECTS; + break; + case EMsgComponentIdImage: + if ( Document( )->SmilType( ) != EMmsSmil ) + { + resId = R_MMSVIEWER_MSK_BUTTON_PLAY_PRESENTATION; + } + else if ( MediaInitializedL( iImage ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_OPEN_IMAGE; + } + else + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + break; + case EMsgComponentIdAudio: + if ( MediaIsRunning( iAudio ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_STOP_AUDIO; + } + else if ( MediaInitializedL( iAudio ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_PLAY_AUDIO; + } + else + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + break; + case EMsgComponentIdVideo: + if ( MediaIsRunning( iVideo ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_STOP_VIDEO; + } + else if ( MediaInitializedL( iVideo ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_PLAY_VIDEO; + } + else + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMsgComponentIdSvg: + if ( MediaIsRunning( iSvgt ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_STOP_SVG; + } + else if ( MediaInitializedL( iSvgt ) ) + { + resId = R_MMSVIEWER_MSK_BUTTON_PLAY_SVG; + } + else + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + break; +#endif + default: + { + + if ( iWaitDialog + && ( iOpeningState == EOpeningMessage + || iOpeningState == EOpeningSlide ) ) + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + else + { + resId = R_MMSVIEWER_MSK_BUTTON_CONTEXT_MENU; + if ( resId != iMskId ) + { + MenuBar()->SetContextMenuTitleResourceId( + R_MMSVIEWER_SELECTMENU ); + } + } + break; + } + } + } + } + else if ( iView ) + { + resId = R_MMSVIEWER_MSK_NO_COMMAND_EMPTY_TEXT; + } + + if ( resId != iMskId + && resId != (-1) ) + { + const TInt KMskPosition = 3; + CEikButtonGroupContainer* cba = Cba(); + if ( cba ) + { + if( resId != 0 ) + { + cba->SetCommandL( KMskPosition, resId ); + } + else + { // nullify the command + cba->SetCommandL( KMskPosition, 0, KNullDesC( ) ); + } + cba->DrawDeferred( ); + iMskId = resId; + } + } + return; + } + +// ----------------------------------------------------------------------------- +// MediaHasNoDrmRights +// ----------------------------------------------------------------------------- +// +TInt CMmsViewerAppUi::MediaHasNoDrmRights(CMsgMediaControl* aMedia) + { + TInt result = KErrNone; + if ( aMedia ) + { + CUniObject* object = ObjectByMediaControl( *aMedia); + TBuf defaultContent( ContentAccess::KDefaultContentObject( ) ); + + TBool ignoreConsumed (EFalse ); + if ( object + && object->DrmInfo( ) ) + { + result = object->DrmInfo( )->EvaluateRights( ignoreConsumed ); + switch ( result ) + { + case DRMCommon::EGeneralError: + case DRMCommon::EUnknownMIME: + case DRMCommon::EVersionNotSupported: + case DRMCommon::ESessionError: + case DRMCommon::ENoRights: + case DRMCommon::ERightsDBCorrupted: + case DRMCommon::EUnsupported: + case DRMCommon::ERightsExpired: + case DRMCommon::EInvalidRights: + break; + default: + result = KErrNone; + break; + } + } + } + return result; + } + +// ----------------------------------------------------------------------------- +// handles the touch-ui related control events for next/previous message +// ----------------------------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +void CMmsViewerAppUi::HandleNaviDecoratorEventL( TInt aEventID ) + { + if ( AknLayoutUtils::PenEnabled() ) + { + if ( iNaviDecorator + && iNaviPane->Top( ) == iNaviDecorator ) + { + if( IsNextMessageAvailableL( aEventID == EAknNaviDecoratorEventRightTabArrow ) ) + { + /* no need for separate checks for right and left arrows + because IsNextMessageAvailableL() and NextMessageL + are called with the truth-value of the same comparison */ + NextMessageL( aEventID == EAknNaviDecoratorEventRightTabArrow ); + } + } + } + } +#endif // !RD_MSG_NAVIPANE_IMPROVEMENT +#endif // RD_SCALABLE_UI_V2 + +// ----------------------------------------------------------------------------- +// SendReadReportL +// ----------------------------------------------------------------------------- +// +void CMmsViewerAppUi::SendReadReportL( TMmsViewerOperationType aOperation, + TMmsViewerOperationEvent aEvent ) + { + // send read report + if ( aOperation == EMmsViewerOperationLaunch + && aEvent == EMmsViewerOperationComplete + && Document( )->LaunchFlags() & EMsgUnreadMessage ) + { + iSendReadReportOperation = new (ELeave ) CMmsViewerSendReadReportOperation( + *this, + *Document( ), + iCoeEnv->FsSession( ) ); + ActivateInputBlockerL( iSendReadReportOperation ); + iSendReadReportOperation->SendReadReportL( ); + } + } + +// ----------------------------------------------------------------------------- +// HandleControlEventL +// ----------------------------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +void CMmsViewerAppUi::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType ) +#else +void CMmsViewerAppUi::HandleControlEventL(CCoeControl* /*aControl*/, TCoeEvent /*aEventType*/) +#endif + { +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + if ( iVolumeDecorator + && iNaviPane->Top( ) == iVolumeDecorator + && aControl == iVolumeDecorator->DecoratedControl() + && aEventType >= MAknNavigationObserver::ENaviEventHandleNavigation + && aEventType <= MAknNavigationObserver::ENaviEventAlreadyRightmostItem ) + { + iViewerFlags |= EVolumeControlTriggered; + TRAP_IGNORE( ChangeVolumeL( + static_cast + ( iVolumeDecorator->DecoratedControl() )->Value( ), + EFalse ) ); + iViewerFlags &= ( ~EVolumeControlTriggered ); + } + } + +#endif + } + +// ----------------------------------------------------------------------------- +// GetNonStoppingWGIdsL +// ----------------------------------------------------------------------------- +// +void CMmsViewerAppUi::GetNonStoppingWgIds( ) + { + iMmsViewerWgId = iCoeEnv->RootWin().Identifier(); + CApaWindowGroupName::FindByAppUid( + KFastSwapAppUid, + iCoeEnv->WsSession(), + iFastSwapWgId ); + CApaWindowGroupName::FindByAppUid( + KAknNotifyServerAppUid, + iCoeEnv->WsSession(), + iAknNotifyServerWgId ); + CApaWindowGroupName::FindByAppUid( + KScreenSaverAppUid, + iCoeEnv->WsSession(), + iScreenSaverWgId ); + // start receivingn events + iCoeEnv->RootWin().EnableFocusChangeEvents(); + } + +// ----------------------------------------------------------------------------- +// ResolveCurrentWgIdL +// ----------------------------------------------------------------------------- +// +void CMmsViewerAppUi::ResolveCurrentWgIdL( ) + { + // magic constant + const TInt KSystemAppWgId( 4 ); + TInt windowGroupId = iEikonEnv->WsSession().GetFocusWindowGroup(); + +/*#ifdef USE_LOGGER + CApaWindowGroupName* winGroupInfo = CApaWindowGroupName::NewL(iCoeEnv->WsSession() ); + CleanupStack::PushL( winGroupInfo ); + winGroupInfo->ConstructFromWgIdL( windowGroupId ); + TUid uid = winGroupInfo->AppUid( ); + TPtrC caption = winGroupInfo->Caption( ); + + LOGTEXT2(_L16("HandleWsEventL EEventFocusLost winGroup: %d"), windowGroupId ); + LOGTEXT2(_L16("HandleWsEventL EEventFocusLost appUid: 0x%x"), uid ); + LOGTEXT2(_L16("HandleWsEventL EEventFocusLost caption: %S"), &caption ); + + CleanupStack::PopAndDestroy( winGroupInfo ); +#endif*/ + + // Stop only if temporary change e.g. a waiting note etc. + if ( ! ( windowGroupId == iFastSwapWgId + || windowGroupId == KSystemAppWgId + || windowGroupId == iAknNotifyServerWgId + || windowGroupId == iMmsViewerWgId + || windowGroupId == iScreenSaverWgId ) ) + { + iIsStopPlaybackWgId = ETrue; + } + } + +// --------------------------------------------------------- +// ActivateInputBlockerL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ActivateInputBlockerL( CActive* aActiveObjectToCancel ) + { + LOGTEXT(_L8("CMmsViewerAppUi::ActivateInputBlockerL")); + delete iInputBlocker; + iInputBlocker = NULL; + + iInputBlocker = CAknInputBlock::NewLC(); + CleanupStack::Pop( iInputBlocker ); + + if ( aActiveObjectToCancel ) + { + iInputBlocker->SetCancelActive( aActiveObjectToCancel ); + } + } + +// --------------------------------------------------------- +// DeactivateInputBlocker +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DeactivateInputBlocker() + { + if ( iInputBlocker ) + { + LOGTEXT(_L8("CMmsViewerAppUi::DeactivateInputBlockerL")); + iInputBlocker->SetCancelActive( NULL ); + delete iInputBlocker; + iInputBlocker = NULL; + } + } + +// --------------------------------------------------------- +// ResetOperationState +// --------------------------------------------------------- +// +void CMmsViewerAppUi::ResetOperationState() + { + // Operation by operation should be considered what is proper action + // in Cancel situation + DeactivateInputBlocker(); + + EndActiveWait(); + delete iWaitDialog; + iWaitDialog = NULL; + + delete iScreenClearer; + iScreenClearer = NULL; + + // Following takes place also in Cancel event to enable + // exit through HandleCommandL() + iViewerState = ENormal; + iOpeningState = EOpeningNone; + iViewerFlags |= ELaunchSuccessful; + } + +// --------------------------------------------------------- +// DoDelayedExit +// --------------------------------------------------------- +// +void CMmsViewerAppUi::DoDelayedExit( TInt aDelayTime ) + { + LOGTEXT(_L8("CMmsViewerAppUi::DoDelayedExit in ") ); + iIdle->Start( aDelayTime, + aDelayTime, + TCallBack( DelayedExitL, this )); + } + +// --------------------------------------------------------- +// DelayedExit +// --------------------------------------------------------- +// +TInt CMmsViewerAppUi::DelayedExitL( TAny* aThis ) + { + CMmsViewerAppUi* viewer = static_cast( aThis ); + viewer->DoMsgSaveExitL(); + return KErrNone; + } +// --------------------------------------------------------- +// IsVideoCall +// --------------------------------------------------------- +// + TBool CMmsViewerAppUi::IsVideoCall() + { + TInt callType; + + RProperty::Get( KPSUidCtsyCallInformation, + KCTsyCallType, + callType );// Ignore errors + + TBool videoCall = ( callType == EPSCTsyCallTypeH324Multimedia ); + + return videoCall; + } +// --------------------------------------------------------- +// DynInitToolbarL +// --------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +void CMmsViewerAppUi::DynInitToolbarL( TInt /*aResourceId*/, + CAknToolbar* /*aToolbar*/ ) + { + } +#endif +// --------------------------------------------------------- +// OfferToolbarEventL +// --------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +void CMmsViewerAppUi::OfferToolbarEventL( TInt aCommand ) + { + switch ( aCommand ) + { + case EMmsViewerToolbarReply: + if ( IsOwnMessage( ) ) + { + HandleCommandL( EMmsViewerReplyToAll ); + } + else + { + HandleCommandL( EMmsViewerReplyToSender ); + } + + break; + + case EMmsViewerToolbarForward: + HandleCommandL( EMmsViewerForward ); + break; + + case EMmsViewerToolbarDelete: + HandleCommandL( EMmsViewerDelete ); + break; + + default: + break; + } + } + +// --------------------------------------------------------- +// SetToolBarItemVisibilities +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SetToolBarItemVisibilities() + { + TBool replyDimming( EFalse ); + TBool forwardDimming( EFalse ); + TBool deleteDimming( EFalse ); + + if ( iToolbar ) + { + CEikButtonGroupContainer* cba = Cba(); + if ( cba + && !cba->ControlOrNull( EAknSoftkeyOptions ) ) + { + // dim every item + replyDimming = ETrue; + forwardDimming = ETrue; + deleteDimming = ETrue; + } + else + { + if ( IsOwnMessage( ) ) + { + if ( !ShowReplyToAll( ) + || Document( )->IsUpload( ) ) + { + replyDimming = ETrue; + } + } + else if ( !HasSender( ) ) + { + replyDimming = ETrue; + } + if ( iSmilModel->SlideCount( ) > iMaxForwardSlideCount ) + { + forwardDimming = ETrue; + } + } + iToolbar->SetItemDimmed( EMmsViewerToolbarReply, + replyDimming, + ETrue ); + iToolbar->SetItemDimmed( EMmsViewerToolbarForward, + forwardDimming, + ETrue ); + iToolbar->SetItemDimmed( EMmsViewerToolbarDelete, + deleteDimming, + ETrue ); + } + } +#endif + +// --------------------------------------------------------- +// AreControlsReadyAndWaitNoteDismissedL +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::AreControlsReadyAndWaitNoteDismissedL( ) + { + if ( + MediaInitializedL( iImage ) + && MediaInitializedL( iAudio ) + && MediaInitializedL( iVideo ) +#ifdef RD_SVGT_IN_MESSAGING + && MediaInitializedL( iSvgt ) +#endif + && !iWaitDialog ) + { + return ETrue; + } + return EFalse; + } + + +// --------------------------------------------------------- +// IsRightsConsumed +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::IsRightsConsumed( CUniObject& aObject ) const + { + TBool consumed( EFalse ); + if ( aObject.DrmInfo( ) ) + { + aObject.DrmInfo( )->EvaluateRights( consumed ); + } + LOGTEXT2(_L16("CMmsViewerAppUi::IsRightsConsumed consumed %d"), consumed ); + return consumed; + } + +// --------------------------------------------------------- +// IsRightsNow +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::IsRightsNow( CUniObject& aObject ) const + { + TBool rightsNow( EFalse ); + if ( aObject.DrmInfo( ) ) + { + TInt consumed( EFalse ); + // KErrNone: rights exist + rightsNow = !aObject.DrmInfo( )->EvaluateRights( consumed ); + + /*TBool rightsNow2( EFalse ); + rightsNow2 = aObject.DrmInfo( )->RightsValidL( ETrue ); + TInt j; + j++;*/ + } + LOGTEXT2(_L16("CMmsViewerAppUi::IsRightsNow rightsNow %d"), rightsNow ); + + + return rightsNow; + } + +// --------------------------------------------------------- +// IsDrmRightsWhenLoaded +// --------------------------------------------------------- +// +TBool CMmsViewerAppUi::IsDrmRightsWhenLoaded( CUniObject& aObject ) const + { + // Separate function just because of LOG traces + TBool rightsWhenLoaded = aObject.IsDrmRightsWhenLoaded(); + LOGTEXT2(_L16("CMmsViewerAppUi::IsDrmRightsWhenLoaded rightsWhenLoaded %d"), rightsWhenLoaded ); + return rightsWhenLoaded; + } + +// --------------------------------------------------------- +// HandleUniObjectEvent from MUniObjectObserver +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleUniObjectEvent( CUniObject& aUniObject, + TUniObjectEvent aUniEvent ) + { + LOGTEXT(_L8("CMmsViewerAppUi::HandleUniObjectEvent in ") ); + // SVG is different. Drm rights are not consumed by us at all but external viewer + CMsgMediaControl* control = MediaControlByObject( aUniObject ); + if ( aUniEvent == EUniObjectEventDrmRightsChanged + && control + && !( control == iVideo + && iViewerFlags & EInObjectsView ) + && aUniObject.DrmInfo( ) + && ( + ( IsDrmRightsWhenLoaded( aUniObject ) + && !IsRightsConsumed( aUniObject ) + && !IsRightsNow( aUniObject ) ) + || ( !IsDrmRightsWhenLoaded( aUniObject ) + && !IsRightsConsumed( aUniObject ) + && IsRightsNow( aUniObject ) ) + ) + ) + { +#ifdef RD_SVGT_IN_MESSAGING + if ( control == iSvgt ) + { + // SVG is different. DRM rights are not consumed ever by us but thumbnail may be visible + // Thus, if SVG thumbnail becomes ever visible, don't remove it + if ( IsDrmRightsWhenLoaded( aUniObject ) + && !IsRightsConsumed( aUniObject ) + && !IsRightsNow( aUniObject ) ) + { + return; + } + } +#endif + + // - Rights were initially when slide was loaded + // && - they were not consumed by us + // && - they were consumed by someone else + // or - Rights were not initially when slide was loaded + // && - they are not consumed by us + // && - now there are rights + if ( !iViewerFlags & EInObjectsView + && IsDisplayingDialog() ) + { + TKeyEvent keyEvent; + keyEvent.iCode = EKeyEscape; + keyEvent.iScanCode = EStdKeyEscape; + keyEvent.iModifiers = 0; + keyEvent.iRepeats = 0; + TRAP_IGNORE( iEikonEnv->SimulateKeyEventL(keyEvent,EEventKey) ); + } + TRAP_IGNORE( ReloadControlL( control, aUniObject ) ); + } + LOGTEXT(_L8("CMmsViewerAppUi::HandleUniObjectEvent out ") ); + } + +// --------------------------------------------------------- +// SimulateUniObjectEventL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SimulateUniObjectEventL( ) + { + iIdle->Cancel(); + TInt j = 4; + CMsgMediaControl* control = NULL; + if ( j == 1 + && iImage ) + control = iImage; + if ( j == 2 + && iAudio ) + control = iAudio; + if ( j == 3 + && iVideo ) + control = iVideo; +#ifdef RD_SVGT_IN_MESSAGING + if ( j == 4 + && iSvgt ) + control = iSvgt; +#endif + if ( control ) + { + CUniObject* uniObject = ObjectByBaseControl( *control ); + if ( uniObject ) + { + ReloadControlL( control, *uniObject ); + } + } + } + + +// --------------------------------------------------------- +// MediaControlByObject +// --------------------------------------------------------- +CMsgMediaControl* CMmsViewerAppUi::MediaControlByObject( CUniObject& aUniObject ) + { + CMsgMediaControl* control = NULL; + switch ( aUniObject.MediaType( ) ) + { + case EMsgMediaImage: + control = iImage; + break; + case EMsgMediaAudio: + control = iAudio; + break; + case EMsgMediaVideo: + control = iVideo; + break; +#ifdef RD_SVGT_IN_MESSAGING + case EMsgMediaSvg: + control = iSvgt; + break; +#endif + default: + break; + } + return control; + + } + + +// --------------------------------------------------------- +// SetTitleIconL +// --------------------------------------------------------- +// +void CMmsViewerAppUi::SetTitleIconL() + { + SetTitleIconSizeL( iAppIcon->Bitmap() ); + // Create duplicates of the icon to be used + CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap(); + CleanupStack::PushL( bitmap ); + + CFbsBitmap* bitmapMask = new( ELeave ) CFbsBitmap(); + CleanupStack::PushL( bitmapMask ); + + User::LeaveIfError( bitmap->Duplicate( iAppIcon->Bitmap()->Handle() ) ); + User::LeaveIfError( bitmapMask->Duplicate( iAppIcon->Mask()->Handle() ) ); + + iTitlePane->SetSmallPicture( bitmap, bitmapMask, ETrue ); + iTitlePane->DrawNow(); + + CleanupStack::Pop( bitmapMask ); + CleanupStack::Pop( bitmap ); + } +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleLongTapEventL +// Function for handling the long tap events +// --------------------------------------------------------- +// +void CMmsViewerAppUi::HandleLongTapEventL(const TPoint& aPenEventLocation, + const TPoint& aPenEventScreenLocation ) + { + CMsgBaseControl* ctrl = iView->FocusedControl(); // ctrl can be NULL. + if ( ctrl && + ( ctrl->ControlId() == EMsgComponentIdAudio || + ctrl->ControlId() == EMsgComponentIdImage || + ctrl->ControlId() == EMsgComponentIdVideo || + ctrl->ControlId() == EMsgComponentIdSvg )&& + ((Document()->SmilType()!=ETemplateSmil)&&(Document()->SmilType()!=E3GPPSmil) )) + { + TRect rect = ctrl->Rect(); + + + + if ((!iTapConsumed)&&rect.Contains(aPenEventLocation)) + { + if (iEmbeddedObjectStylusPopup) + { + delete iEmbeddedObjectStylusPopup; + iEmbeddedObjectStylusPopup = NULL; + } + iEmbeddedObjectStylusPopup = CAknStylusPopUpMenu::NewL(this,aPenEventLocation); + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC(reader,R_MMSVIEWER_EMBEDDED_OBJECT_STYLUS_MENU ); + iEmbeddedObjectStylusPopup->ConstructFromResourceL(reader); + CleanupStack::PopAndDestroy(); + iEmbeddedObjectStylusPopup->SetPosition(aPenEventLocation); + iEmbeddedObjectStylusPopup->ShowMenu(); + iTapConsumed = ETrue; + } + } + } +// --------------------------------------------------------- +// CMmsViewerAppUi::HandleSelectionKeyL +// Function for handling the selection key +// --------------------------------------------------------- +void CMmsViewerAppUi::HandleSelectionKeyL() + { + // Read current MSK resource to get a command id + // to execute. + TResourceReader reader; + iEikonEnv->CreateResourceReaderLC( + reader, iMskId ); + reader.ReadInt8(); // version + HandleCommandL( reader.ReadUint16() ); + CleanupStack::PopAndDestroy(); // resource buffer + } +// End of File +