diff -r 000000000000 -r 72b543305e3a mobilemessaging/mmsui/notviewersrc/NotViewerAppUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobilemessaging/mmsui/notviewersrc/NotViewerAppUi.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,3298 @@ +/* +* Copyright (c) 2004 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 CNotViewerAppUi class methods. +* +*/ + + + +#include // FeatureManager +#include +#include +#include // CRichText +#include // CEikRichTextEditor +#include // StringLoader (load and format strings from resources) + +#include // link against centralrepository.lib +#include +#include // for Central Repository keys +#include + +#include // Global Fep enums (ELatin, ENumber) + +// Base editor stuff +#include // CMsgBodyControl +#include // CMsgEditorView +#include // CMsgAddressControl +#include // CMsgAttachmentUtils +#include // CMsgEditorAppUiExtension + +// Help +#include +#include // For HlpLauncher + +// Phone +#include // Common phone number validity checker + +// Contacts +#include // KNullContactId + +// MUIU stuff +#include // Call back to sender +#include + +#include // CMuiuOperationWait +#include // CAknInputBlock +#include // CMsvProgressReporterOperation +#include + +// AKN Stuff +#include // Apac, layout, etc +#include // AknsUtils +#include // CAknInformationNote +#include // LAF +#include + +// Client MTM Stuff +#include // CMmsClientMtm +#include // EMtmUiFlagEditorPreferEmbedded +#include // TMmsGenUtils +#include // TMmsMsvEntry +#include // function id of MessageInfo + +// Send As Stuff +#include // SendUI (for Reply via SMS) +#include // MTM Uids +#include + +// Find item +#include // Find item stuff +#include // +#include // +#include +#include + +#ifdef RD_SCALABLE_UI_V2 +#include +#endif + +#include // CAknNavigationControlContainer +#include // CAknNavigationDecorator +#include // CAknTabGroup +#include +#include +#include +#include + +#include // Bitmap identifiers +#include // KDC_APP_BITMAP_DIR +#include "MmsMtmConst.h" +#include "NotMtmUi.h" // Notification MTM UI +#include "NotMtmUiData.h" // Notification MTM UI Data +#include "NotViewerAppUi.h" +#include "NotViewerDocument.h" +#include "NotViewer.hrh" +#include +#include +#include "MmsSettingsHandler.h" +#include +#include + +// CONSTANTS +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +const TUint KNaviGranularity = 2; +const TInt KIconDefaultColor = 0; +#endif +_LIT( KMmsUiMbmFile, "mmsui.mbm" ); + +const TInt KDateSize = 30; +const TInt KMaxDetailsLength = 64; // Copy max this many chars to TMsvEntry iDetails +const TInt KReplyToSenderSize = 2048; +// Exit time when using CIdle to close the application +const TInt KDelayedExitDelay = 2500000; + +// --------------------------------------------------------- +// CNotViewerAppUi +// --------------------------------------------------------- +// +CNotViewerAppUi::CNotViewerAppUi() : + iIdle( NULL ), + iAbsorber( NULL ), + iOperation( NULL ), + iSenderType( EMuiuAddressTypeNone ), + iFlags(0), + iMsgId( 0 ) + { + } + +// --------------------------------------------------------- +// ~CNotViewerAppUi +// --------------------------------------------------------- +// +CNotViewerAppUi::~CNotViewerAppUi() + { + FeatureManager::UnInitializeLib(); + delete iOperation; + if ( iView + && !( iFlags & ENotViewerIsNotification ) ) + { // FR mode + if ( !( iMtm->Entry( ).Entry( ).ReadOnly( ) ) ) + { // FR in edit mode + CMsgAddressControl* to = + static_cast( iView->ControlById( EMsgComponentIdTo ) ); + if ( to ) + { // Lets save the current input mode to shared data + TInt inputMode = to->Editor().AknEditorCurrentInputMode(); + iMuiuSettRepository->Set( KMuiuToInputMode, inputMode ); + } + } + } + if ( iNotifyHandler ) + { + iNotifyHandler->StopListening(); + } + delete iNotifyHandler; + delete iCUiRepository; + delete iMuiuSettRepository; + + delete iIdle; + delete iAbsorber; + delete iSendUi; + delete iFindItemMenu; +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT + delete iNaviDecorator; +#endif + delete iMsgVoIPExtension; + delete iAlias; + delete iAddressHandler; + delete iSettingsHandler; + delete iAppIcon; + } + +// --------------------------------------------------------- +// ConstructL +// --------------------------------------------------------- +// +void CNotViewerAppUi::ConstructL() + { + LOGTEXT(_L8("NotViewerAppUi: Construct start")); + CMsgEditorAppUi::ConstructL(); // Constructor of the base class + + // Disable task swapper from options menu during launch + MenuBar()->SetMenuType( CEikMenuBar::EMenuOptionsNoTaskSwapper ); + + FeatureManager::InitializeLibL(); + + if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + iFlags |= ENotViewerFlagsHelp; + } + + // KFeatureIdMmsNonDestructiveForward has been deprecated + // Check of TMsvEntry::iMtmData2 & KMmsStoredInMMBox replaces it. + // MMSEngine sets KMmsStoredInMMBox for received notifications + + if ( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) ) + { + iFlags |= ENotViewerOffline; + } + if ( FeatureManager::FeatureSupported( KFeatureIdAudioMessaging ) ) + { + iFlags |= ENotViewerAudioMessaging; + } + + iMtm = &(Document()->Mtm()); + if ( !iMtm ) + { + User::Leave( KErrBadHandle ); + } + + iSettingsHandler = CMmsSettingsHandler::NewL( *iMtm ); + +#ifndef RD_SCALABLE_UI_V2 + iView = CMsgEditorView::NewL( *this, CMsgEditorView::EMsgReadOnly ); +#endif + + iNaviPane = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + iTitlePane = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) ); + iSendUi = CSendUi::NewL(); + + TInt highlight = 0; + iMuiuSettRepository = CRepository::NewL( KCRUidMuiuSettings ); + + iCUiRepository = CRepository::NewL( KCRUidCommonUi ); + iCUiRepository->Get( KCuiAutomaticHighlight, highlight ); + iNotifyHandler = CCenRepNotifyHandler::NewL( *this, + *iCUiRepository, + CCenRepNotifyHandler::EIntKey, + KCuiAutomaticHighlight ); + iNotifyHandler->StartListeningL(); + + if ( highlight == 0 ) + { // Disable autofind if it's disable in Shared Data + iFlags &= ~ENotViewerAutoFind; + } + else + { + iFlags |= ENotViewerAutoFind; + } + + // No other reply types as mms is not possible + TInt features( 0 ); + CRepository* repository = CRepository::NewL( KCRUidMuiuVariation ); + repository->Get( KMuiuUniEditorFeatures, features ); + if ( features & KUniEditorFeatureIdRestrictedReplyMms ) + { + iFlags |= ENotViewerRestrictedReply; + } + delete repository; + + LOGTEXT2(_L("CNotViewerAppUi::ConstructL: iFlags 0x%x"), iFlags ); + + iFindItemMenu = CFindItemMenu::NewL( EFindItemMenuPlaceHolder ); + iFindItemMenu->AttachItemFinderMenuL(0); + + if( !iEikonEnv->StartedAsServerApp( ) ) + { + Document()->PrepareToLaunchL( this ); + } + + MenuBar()->SetContextMenuTitleResourceId( R_NOTVIEWER_SELECTIONMENUBAR ); + + // 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 ); + + ApplyFormat(iLabelFormat, iLabelMask, ETrue); + ApplyFormat(iValueFormat, iValueMask, EFalse); + LOGTEXT(_L8("NotViewerAppUi: Construct end")); + } + +// --------------------------------------------------------- +// LaunchViewL +// --------------------------------------------------------- +// +void CNotViewerAppUi::LaunchViewL() + { + LOGTEXT(_L8("NotViewerAppUi: LaunchViewL start")); + + TRAPD( err, iMtm->LoadMessageL() ); + + if ( err ) + { + if ( err != KErrNoMemory ) + { + User::Leave( KErrCorrupt ); + } + User::Leave( err ); + } + + GetTypeL( ); // Updates the iFlag + + SetTitleIconL(); + +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + // iToolbar should have been assigned already in HandleForegroundEventL() + // If it failed, + // - catch it here + // - but it means also that some of functionality cannot be fulfilled + if ( !iToolbar ) + { + iToolbar = CurrentFixedToolbar(); + if ( iToolbar ) + { + iToolbar->SetToolbarObserver( this ); + } + } + } + + if ( iToolbar + && iToolbar->IsToolbarDisabled() ) + { + iToolbar->DisableToolbarL( EFalse ); + iToolbar->SetToolbarVisibility( ETrue, EFalse ); + } + // Creation of CMsgEditorView must be after toolbar is set visible otherwise layout things can go wrong. + // This has been moved here from ConstructL(). For that reason couple of 'if ( iView &&' checks has been added + // at locations which could use CMsgEditorView very early at startup + iView = CMsgEditorView::NewL( *this, CMsgEditorView::EMsgReadOnly ); + +#endif + + // Editors must not exit due to End key. Flag is set by GetTypeL(); + if ( ! ( iFlags & ENotViewerIsNotification ) ) + { + SetCloseWithEndKey( EFalse ); + } + + iMsgId = iMtm->Entry( ).Entry( ).Id( ); + + TInt focusedControl = 0; + + if( iFlags & ENotViewerIsNotification ) + { // We are in the notification mode + focusedControl = EMsgComponentIdFrom; + iView->AddControlFromResourceL( + R_NOTVIEWER_FROM, + EMsgAddressControl, + EMsgAppendControl, + EMsgHeader ); + } + else + { // we are in the forward request mode + focusedControl = EMsgComponentIdTo; + iView->AddControlFromResourceL( + R_NOTVIEWER_TO, + EMsgAddressControl, + EMsgAppendControl, + EMsgHeader ); + CMsgAddressControl* to = AddressControl( ); + + // Remove the auto highlight in FR mode + iFlags &= ~ENotViewerAutoFind; + + TMsvEntry msvEntry = iMtm->Entry( ).Entry( ); + + if( msvEntry.ReadOnly( ) ) // Sent + { + to->SetReadOnly( ETrue ); + } + else // Unsent: To-control must not be read only + { + to->SetReadOnly( EFalse ); + TInt inputMode = ENumber; + + if ( iMuiuSettRepository->Get( KMuiuToInputMode, inputMode ) ) + { + inputMode = ENumber; + } + to->Editor( ).SetAknEditorCurrentInputMode( inputMode ); + } + UpdateTitlePaneL( ); // Updates the "Forward Request" to Title pane + } + + // Adds the text in message body here + if( iFlags & ENotViewerIsNotification ) + { // We are in the Viewer so lets add from field + const TPtrC sender = iMtm->Sender(); + const TPtrC details = iMtm->Entry().Entry().iDetails; + if ( sender.Length() ) + { + iSenderType = MsvUiServiceUtilitiesInternal::ResolveAddressTypeL( + TMmsGenUtils::PureAddress( sender ), + CommonPhoneParser::ESMSNumber ); + + if ( iSenderType != EMuiuAddressTypePhoneNumber ) + { + //We trust on that there won't be illegal addresses + //in received messages + iSenderType = EMuiuAddressTypeEmail; + if ( iFindItemMenu ) + { + iFindItemMenu->SetSenderDescriptorType( CItemFinder::EEmailAddress ); + } + } + CMsgAddressControl* fromControl = AddressControl( ); + + //Check if MMS engine has put an alias into iDetails field + if ( sender.Compare( details ) != 0 ) + { + TPtrC alias = KNullDesC(); + if ( details.Length() && !iAlias ) + { + iAlias = details.AllocL( ); + alias.Set( *iAlias ); + } + + // Resolve whether this is remote alias. Local alias takes precedence + TPtrC tempAlias( TMmsGenUtils::Alias( sender ) ); + if ( iAlias + && tempAlias.Length() + && !tempAlias.CompareF( *iAlias ) ) + + { + iRemoteAlias = ETrue; + } + + MVPbkContactLink* link = NULL; + fromControl->AddRecipientL( alias, + TMmsGenUtils::PureAddress( sender ), + ETrue, + link ); + } + else + { + MVPbkContactLink* link = NULL; + fromControl->AddRecipientL( TMmsGenUtils::Alias( sender ), + TMmsGenUtils::PureAddress( sender ), + ETrue, + link ); + } + } + else + { + // Leave the address control empty + // This should not happen, though + } + } + else + { + const CMsvRecipientList& addresses = iMtm->AddresseeList(); + + TInt count = addresses.Count(); + CMsgAddressControl* toControl = AddressControl( ); + + if ( count > 0 ) + { + CMsgRecipientList* recipientList = CMsgRecipientList::NewL(); + CleanupStack::PushL( recipientList ); + + for ( TInt i = 0; i < count; i++) + { + CMsgRecipientItem* recipient = CMsgRecipientItem::NewLC( + TMmsGenUtils::Alias( addresses[i] ), + TMmsGenUtils::PureAddress( addresses[i] ) ); + recipient->SetVerified( ETrue ); + recipientList->AppendL( recipient ); + CleanupStack::Pop(); + recipient = NULL; + } + toControl->AddRecipientsL( *recipientList ); + CleanupStack::PopAndDestroy(); + } + if ( !iMtm->Entry().Entry().ReadOnly( ) ) + { // Address handler is created only when we have unsent Forward Request + iAddressHandler = CUniAddressHandler::NewL( Document()->Mtm(), *toControl, *iCoeEnv ); + } + } + + // Add the body field stuff + if( iFlags & ENotViewerIsNotification ) + { // We are in the Viewer so lets add message field, too + AddMessageFieldL( ); + } + AddSubjectFieldL( ); + AddTextFieldL( ); + AddSizeFieldL( ); + if( iFlags & ENotViewerIsNotification ) + { // We are in the Viewer so lets add expiry field, too + AddExpiryFieldL( ); + } + AddClassFieldL( ); + AddPriorityFieldL( ); + + if( iFlags & ENotViewerIsNotification ) + { // We are in the Viewer so Find stuff too + SetFindModeL( iFlags & ENotViewerAutoFind ); + + } + else + { + if ( iView->ItemFinder() ) + { + iView->ItemFinder()->SetFindModeL( + CItemFinder::ENoneSelected ); + } + } + + iView->ExecuteL( ClientRect(), focusedControl ); + InitNavipaneL( ); + + // Enable task swapper to options menu after launch has been completed. + MenuBar()->SetMenuType( CEikMenuBar::EMenuOptions ); + + + LOGTEXT(_L8("NotViewerAppUi: LaunchViewL end")); + } + +// --------------------------------------------------------- +// DynInitMenuPaneL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DynInitMenuPaneL(TInt aMenuId, CEikMenuPane* aMenuPane ) + { + if ( aMenuPane ) + { + TInt amountOfItems( aMenuPane->NumberOfItemsInPane() ); + if ( !Document( )->IsLaunched( ) ) + { + if ( amountOfItems ) + { + aMenuPane->DeleteBetweenMenuItems( 0, amountOfItems - 1 ); + } + return; + } + switch ( aMenuId ) + { + case R_NOTVIEWER_OPTIONSMENU: + { + DynInitOptionsMenuL( aMenuPane ); + break; + } + case R_NOTVIEWER_REPLY_SUBMENU: + { + DynInitReplyMenuL( aMenuPane ); + break; + } + case R_NOTVIEWER_SELECTIONMENU: + { + DynInitContextMenuL( aMenuPane ); + break; + } + case R_NOTVIEWER_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: + { + // this does nothing if we're not, so this is safe + iFindItemMenu->UpdateItemFinderMenuL( aMenuId, aMenuPane ); + break; + } + } + } + } + +// --------------------------------------------------------- +// DynInitOptionsMenuL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DynInitOptionsMenuL( CEikMenuPane* aMenuPane ) + { + LOGTEXT(_L8("NotViewerAppUi: DynInitOptionsMenuL start")); + if( !(iFlags & ENotViewerFlagsHelp ) ) + { + aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue ); + } + if ( iFlags & ENotViewerIsNotification ) + { // Notification mode + if ( iView ) + { + 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, + EFindItemMenuPlaceHolder, + iMtm->Sender(), + iAlias && !iRemoteAlias ? ETrue : EFalse, //"Is sender known" + EFalse ); + } + + aMenuPane->SetItemDimmed( ENotViewerSend, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerAddRecipient, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerCheckNames, ETrue ); + + CNotViewerDocument* doc = Document( ); + + CNotMtmUiData* uiData = &doc->MtmUiDataL( ); + + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + // Note: OperationSupportedL returns 0 if operation is supported, + // otherwise it returns some kind of error code + + if( uiData->OperationSupportedL( KMtmUiFunctionFetchMMS, entry ) ) + { + aMenuPane->SetItemDimmed( ENotViewerRetrieve, ETrue ); + } + + if( uiData->OperationSupportedL( KMtmUiFunctionDeleteMessage, entry ) ) + { + aMenuPane->SetItemDimmed( ENotViewerDelete, ETrue ); + } + + if( uiData->OperationSupportedL( KMtmUiFunctionForward, entry ) ) + { + aMenuPane->SetItemDimmed( ENotViewerForward, ETrue ); + } + + if( iMtm->Sender().Length()==0 ) + { + aMenuPane->SetItemDimmed( ENotViewerReplyMenu, ETrue ); + } + + } + else + { // ForwReq mode + aMenuPane->SetItemDimmed( EFindItemMenuPlaceHolder, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerRetrieve, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerForward, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerReplyMenu, ETrue ); + if ( iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { // Sent ForwReq + aMenuPane->SetItemDimmed( ENotViewerMessageDetails, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerSend, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerAddRecipient, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerCheckNames, ETrue ); + } + else + { + // This is not needed when we are in edit mode + // Send is always visible + aMenuPane->SetItemDimmed( ENotViewerDelete, ETrue ); + // Lets check if we need Send or not + if ( iView ) + { + CMsgAddressControl* toCtrl = + static_cast( iView->ControlById( EMsgComponentIdTo ) ); + if ( toCtrl && toCtrl->GetRecipientsL()->Count() < 1 ) + { + // To field empty -> cannot send. + aMenuPane->SetItemDimmed( ENotViewerCheckNames, ETrue ); + } + } + } + } + LOGTEXT(_L8("NotViewerAppUi: DynInitOptionsMenuL end")); + } + +// --------------------------------------------------------- +// DynInitReplyMenuL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DynInitReplyMenuL( CEikMenuPane* aMenuPane ) + { + if( iSenderType == EMuiuAddressTypeNone ) + { // If sender type is email, disable SMS + aMenuPane->SetItemDimmed( ENotViewerReplyViaMessage, ETrue ); + } + + if ( ! ( iFlags & ENotViewerAudioMessaging ) + || iFlags & ENotViewerRestrictedReply + || iSenderType == EMuiuAddressTypeNone ) + { + aMenuPane->SetItemDimmed( ENotViewerReplyViaAudio, ETrue ); + } + + if ( iSenderType != EMuiuAddressTypeEmail || + iFlags & ENotViewerRestrictedReply || + MsvUiServiceUtilitiesInternal::DefaultServiceForMTML( + Document()->Session(), + KSenduiMtmSmtpUid, + ETrue ) + == KMsvUnknownServiceIndexEntryId ) + { + // "Reply via e-mail" feature + aMenuPane->SetItemDimmed( ENotViewerReplyViaMail, ETrue ); + } + } + +// --------------------------------------------------------- +// DynInitContextMenuL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DynInitContextMenuL( CEikMenuPane* aMenuPane ) + { + LOGTEXT(_L8("NotViewerAppUi: DynInitContextMenuL start")); + if ( iFlags & ENotViewerIsNotification ) + { // Notification + if ( iView ) + { + 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, + iMtm->Sender(), + iAlias && !iRemoteAlias ? ETrue : EFalse, //"Is sender known" + ETrue ); + } + + if( iSenderType == EMuiuAddressTypeNone ) + { // If sender type is none, disable Reply menu + aMenuPane->SetItemDimmed( ENotViewerReplyMenu, ETrue ); + } + aMenuPane->SetItemDimmed( ENotViewerSend, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerAddRecipient, ETrue ); + + CNotViewerDocument* doc = Document( ); + + CNotMtmUiData* uiData = &doc->MtmUiDataL( ); + + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + // Note: OperationSupportedL returns 0 if operation is supported, + // otherwise it returns some kind of error code + + if( uiData->OperationSupportedL( KMtmUiFunctionFetchMMS, entry ) ) + { + aMenuPane->SetItemDimmed( ENotViewerRetrieve, ETrue ); + } + } + else + { // ForwReq + aMenuPane->SetItemDimmed( ENotViewerRetrieve, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerReplyMenu, ETrue ); + aMenuPane->SetItemDimmed( EFindItemContextMenuPlaceHolder, ETrue ); + if ( iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + aMenuPane->SetItemDimmed( ENotViewerSend, ETrue ); + aMenuPane->SetItemDimmed( ENotViewerAddRecipient, ETrue ); + } + // else - send key is always available + } + LOGTEXT(_L8("NotViewerAppUi: DynInitContextMenuL end")); + } + +// --------------------------------------------------------- +// HandleKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CNotViewerAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) + { + LOGTEXT(_L8("NotViewerAppUi: HandleKeyEventL start")); + if ( !Document()->IsLaunched() || !iView ) + { + return EKeyWasNotConsumed; + } + if ( aType != EEventKey ) + { + return EKeyWasNotConsumed; + } + TMsvEntry msvEntry = iMtm->Entry( ).Entry( ); + + switch ( aKeyEvent.iCode ) + { + case EKeyBackspace: + { + if ( msvEntry.ReadOnly( ) || iFlags & ENotViewerIsNotification ) + { // We have either a notification or sent FR open + CNotViewerDocument* doc = Document( ); + CNotMtmUiData* uiData = &doc->MtmUiDataL( ); + TMsvEntry entry = iMtm->Entry( ).Entry( ); + if( !uiData->OperationSupportedL( KMtmUiFunctionDeleteMessage, entry ) ) + { + DeleteNotificationL( ); + } + // We can consume this because Delete is the only possible function here + return EKeyWasConsumed; + } + // else we need to be able to delete characters in To field + break; + } + case EKeyRightArrow: + { + if ( msvEntry.ReadOnly( ) || iFlags & ENotViewerIsNotification ) + { // We have either a notification or sent FR open + if( iNaviDecorator + && IsNextMessageAvailableL( ETrue ) ) + { + NextMessageL( ETrue ); + } + // We can consume this because Next msg is the only possible function here + return EKeyWasConsumed; + } + // else we need to be able to move inside To field + break; + } + case EKeyLeftArrow: + { + if ( msvEntry.ReadOnly( ) || iFlags & ENotViewerIsNotification ) + { // We have either a notification or sent FR open + if( iNaviDecorator + && IsNextMessageAvailableL( EFalse ) ) + { + NextMessageL( EFalse ); + } + // We can consume this because Next msg is the only possible function here + return EKeyWasConsumed; + } + // else we need to be able to move inside To field + break; + } + + case EKeyDevice3: //Selection key + case EKeyEnter: //Enter Key + { + if ( DoSelectionKeyL( ) ) + { + return EKeyWasConsumed; + } + break; //Lint e527 + } + case EKeyYes: //Send key + { + DoHandleSendKeyL( ); + return EKeyWasConsumed; + } + default: + break; + } + return iView->OfferKeyEventL( aKeyEvent, aType ); + } + +// --------------------------------------------------------- +// HandleCommandL +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleCommandL( TInt aCommand ) + { + LOGTEXT(_L8("NotViewerAppUi: HandleCommandL start")); + if ( aCommand != EEikCmdExit && + ! Document()->IsLaunched() ) + { + return; + } + if ( iFindItemMenu && iFindItemMenu->CommandIsValidL( aCommand ) ) + { + iFindItemMenu->HandleItemFinderCommandL( aCommand ); + return; + } + switch ( aCommand ) + { + case ENotViewerRetrieve: + { + FetchL( ); + break; + } + case ENotViewerForward: + { + DoForwardL( ); + break; + } + case ENotViewerSend: + { + DoHandleSendKeyL( ); + break; + } + case ENotViewerReplyViaMessage: + case ENotViewerReplyViaAudio: + case ENotViewerReplyViaMail: + { + UniReplyL( aCommand ); + break; + } + case ENotViewerAddRecipient: + { + AddRecipientL( ); + break; + } + case ENotViewerCheckNames: + { + CheckNamesL( ); + break; + } + case ENotViewerDelete: + { + DeleteNotificationL( ); + break; + } + case ENotViewerMessageDetails: + { + MessageDetailsL( ); + break; + } + case EMsgDispSizeAutomatic: + case EMsgDispSizeLarge: + case EMsgDispSizeNormal: + case EMsgDispSizeSmall: + HandleLocalZoomChangeL( (TMsgCommonCommands)aCommand ); + break; + case EAknCmdHelp: + { + LaunchHelpL( ); + break; + } + case EEikCmdExit: + iExitMode = MApaEmbeddedDocObserver::TExitMode(CMsgEmbeddedEditorWatchingOperation::EMsgExternalExit); + // Let it flow thru.. + case EAknSoftkeyBack: + case EAknSoftkeyClose: + case EAknSoftkeyCancel: + // system exit + Exit( aCommand ); + break; + default: + break; + } + LOGTEXT(_L8("NotViewerAppUi: HandleCommandL end")); + } + +// --------------------------------------------------------- +// DoSelectionKeyL +// --------------------------------------------------------- +TBool CNotViewerAppUi::DoSelectionKeyL() + { + if ( iView ) + { + CMsgBaseControl* ctrl = iView->FocusedControl(); + + if ( ctrl ) + { + switch ( FocusedControlId() ) + { + case EMsgComponentIdTo: + { + if( iFlags & ENotViewerIsNotification ) + { // We have a notification, we should handle recipients + CMsgAddressControl* to = AddressControl( ); + // Check is there any recipients in address ctrl + TBool modified = EFalse; + if ( to->GetRecipientsL()->Count() ) + { + // Recipients found. Verify addresses. + if ( !VerifyAddressesL( modified ) ) + { + // Illegal address found. + modified = ETrue; + } + } + if ( !modified )//else + { + // Nothing changed on the UI. Open PhoneBook. + AddRecipientL(); + } + break; // break only if notification + } + else // If we are in Forward Request, it's ok to go down to menubar + { + return EFalse; + } + } + case EMsgComponentIdFrom: + case EMsgComponentIdBody: + { + MenuBar()->SetMenuTitleResourceId( R_NOTVIEWER_SELECTIONMENUBAR ); + MenuBar()->SetMenuType(CEikMenuBar::EMenuContext); + TRAPD( err, MenuBar()->TryDisplayMenuBarL() ); + MenuBar()->SetMenuTitleResourceId( R_NOTVIEWER_MENU ); + MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions); + User::LeaveIfError( err ); + } + break; + + default: + break; + } + } + } + return ETrue; + } + +// --------------------------------------------------------- +// DoHandleSendKeyL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DoHandleSendKeyL() + { + if( iFlags & ENotViewerIsNotification ) + { // We have a notification, we should call to sender + CallToNumberL( ); + } + else if ( !iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { // We are not-readonly Forward Request -> Send is possible + + // Disable dialer + iAvkonAppUi->SetKeyEventFlags( + CAknAppUiBase::EDisableSendKeyShort | + CAknAppUiBase::EDisableSendKeyLong ); + + // CallCreationKey: Send message if recipients. + // Otherwise fetch recipients + CMsgAddressControl* to = AddressControl(); + + if ( to->GetRecipientsL()->Count() > 0 ) + { + // has addresses -> Send + SendL(); + } + else + { + AddRecipientL(); + } + } + } + +// --------------------------------------------------------- +// FetchL +// --------------------------------------------------------- +// +void CNotViewerAppUi::FetchL( ) + { + LOGTEXT(_L8("NotViewerAppUi: Fetch start")); + if( !(iFlags & ENotViewerIsNotification) ) + { // We are in forward request + return; + } + + if( iFlags & ENotViewerOffline + && MsvUiServiceUtilitiesInternal::IsPhoneOfflineL() ) + { // We are in offline at the moment -> Infonote & exit + ShowInformationNoteL( R_NOTVIEWER_OFFLINE_NOT_POSSIBLE, EFalse ); + DoDelayedExitL( KDelayedExitDelay ); + return; + } + + if( !CheckAPSettingsL( ) ) + { + return; + } + TTime currentTime; + currentTime.HomeTime( ); + TTime expiryTime = iMtm->ExpiryDate( ); + TLocale locale; + expiryTime += locale.UniversalTimeOffset(); + if (locale.QueryHomeHasDaylightSavingOn()) + { + TTimeIntervalHours daylightSaving(1); + expiryTime += daylightSaving; + } + + if( currentTime > expiryTime ) + { // Message is expired + if ( !ShowConfirmationQueryL( R_NOTVIEWER_QUEST_MSG_EXPIRED ) ) + { // User did not want to fetch expired message + return; + } + } + + CAknInputBlock* abs = CAknInputBlock::NewLC( ); + + ShowInformationNoteL( R_NOTVIEWER_RETRIEVING_MESSAGE, EFalse ); + + TMsvId entryId = iMtm->Entry( ).Entry( ).Id( ); + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + + CMsvEntrySelection* sel = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( sel ); + sel->AppendL( entryId ); + + CMsvOperation* op = iMtm->FetchMessagesL( *sel, wait->iStatus ); + + if( !op ) + { + CleanupStack::PopAndDestroy( sel ); // selection + CleanupStack::PopAndDestroy( wait ); // wait + CleanupStack::PopAndDestroy( abs ); // abs + return; + } + + CleanupStack::PushL( op ); + wait->Start(); + + // Lets ignore the return value of wait + + CleanupStack::PopAndDestroy( op ); // op + CleanupStack::PopAndDestroy( sel ); // selection + CleanupStack::PopAndDestroy( wait ); // wait + CleanupStack::PopAndDestroy( abs ); // abs + LOGTEXT(_L8("NotViewerAppUi: Fetch end")); + // Let information note time to exit + DoDelayedExitL( KDelayedExitDelay ); + } + +// --------------------------------------------------------- +// DoForwardL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DoForwardL( ) + { + LOGTEXT(_L8("NotViewerAppUi: ForwardL start")); + if( !(iFlags & ENotViewerIsNotification) ) + { // We are in forward request + return; + } + + // Lets check the disk space + if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL( + Document()->Session( ), + KReplyToSenderSize ) ) + { + User::Leave( KErrDiskFull ); + } + + if( !CheckAPSettingsL( ) ) + { + return; + } + + TTime currentTime; + currentTime.HomeTime( ); + TTime expiryTime = iMtm->ExpiryDate( ); + TLocale locale; + expiryTime += locale.UniversalTimeOffset(); + if (locale.QueryHomeHasDaylightSavingOn()) + { + TTimeIntervalHours daylightSaving(1); + expiryTime += daylightSaving; + } + + if( currentTime > expiryTime ) + { // Message is expired + if ( !ShowConfirmationQueryL( R_NOTVIEWER_QUEST_MSG_EXPIRED ) ) + { + // User did not want to forward expired message + return; + } + } + TMsvEntry entry = iMtm->Entry( ).Entry( ); + if( ! ( entry.iMtmData2 & KMmsStoredInMMBox ) ) + { // Query, if multiple forward is not possible + if ( !ShowConfirmationQueryL( R_NOTVIEWER_QUEST_FORWARD_NOTIF ) ) + { + // User did not want forward message, as it cannot not be fetched to the phone after that + return; + } + } + + TRAPD ( error, + { + ForwardL( Document()->DefaultMsgFolder() ); //Draft + } ); //end TRAP + if ( error ) + { + User::Leave( error ); + } + iMtm->Entry( ).SetEntryL( iMsgId ); + TRAP_IGNORE( iMtm->LoadMessageL( ) ); + EntryChangedL( ); + LOGTEXT(_L8("NotViewerAppUi: ForwardL end")); + } + +// --------------------------------------------------------- +// SendL +// --------------------------------------------------------- +// +void CNotViewerAppUi::SendL( ) + { + LOGTEXT(_L8("NotViewerAppUi: SendL start")); + if( iFlags & ENotViewerIsNotification ) + { // We are in notification + return; + } + TBool dummy; + if ( !VerifyAddressesL( dummy ) ) + { + return; + } + + // For eating key presses + CAknInputBlock* abs = CAknInputBlock::NewLC( ); + + DoSaveL( ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + CMsvOperation* op = iMtm->SendL( wait->iStatus ); + + if( !op ) + { + CleanupStack::PopAndDestroy( wait ); + CleanupStack::PopAndDestroy( abs ); + return; + } + + CleanupStack::PushL( op ); + wait->Start(); + + // Let's ignore the return value of wait + + CleanupStack::PopAndDestroy( 2 ); // op, wait + + CleanupStack::PopAndDestroy( abs ); + if( iFlags & ENotViewerOffline + && MsvUiServiceUtilitiesInternal::IsPhoneOfflineL() ) + { // We are in offline at the moment -> Infonote + ShowInformationNoteL( R_NOTVIEWER_SAVED_OUTBOX, EFalse ); + DoDelayedExitL( KDelayedExitDelay ); + LOGTEXT(_L8("NotViewerAppUi: Offline SendL end")); + return; + } + + LOGTEXT(_L8("NotViewerAppUi: SendL end")); + Exit( EAknSoftkeyBack ); + } + +// --------------------------------------------------------- +// UniReplyL +// --------------------------------------------------------- +// +void CNotViewerAppUi::UniReplyL( TInt aCommand ) + { + LOGTEXT(_L8("NotViewerAppUi: ReplyL start")); + if( !(iFlags & ENotViewerIsNotification) ) + { // We are in forward request + return; + } + + // Lets check the disk space + if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL( + Document()->Session( ), + KReplyToSenderSize ) ) + { + User::Leave( KErrDiskFull ); + } + + CMessageData* msgData = CMessageData::NewLC(); + + const TPtrC sender = iMtm->Sender(); + + if ( sender != KNullDesC() ) + { + TMsvEntry entry = iMtm->Entry().Entry(); + + if ( sender.Compare( entry.iDetails ) ) + { + msgData->AppendToAddressL( TMmsGenUtils::PureAddress( sender ), *iAlias ); + } + else + { + msgData->AppendToAddressL( TMmsGenUtils::PureAddress( sender ), + TMmsGenUtils::Alias( sender ) ); + } + } + + // audio message has not subject field + if( aCommand != ENotViewerReplyViaAudio ) + { + 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 ); + } + + + TUid mtmUid = KSenduiMtmUniMessageUid; + switch ( aCommand ) + { + case ENotViewerReplyViaAudio: + mtmUid = KSenduiMtmAudioMessageUid; + break; + case ENotViewerReplyViaMail: + mtmUid = KSenduiMtmSmtpUid; + break; + case ENotViewerReplyViaMessage: + default: + if( iFlags & ENotViewerRestrictedReply ) + { + mtmUid = KSenduiMtmMmsUid; + } + break; + } + + // And do the sending + TInt error; + TRAP ( error, + { + iSendUi->CreateAndSendMessageL( + mtmUid, + msgData); + } ); //TRAP + + CleanupStack::PopAndDestroy( msgData ); // msgData + + if ( error ) + { + iMtm->Entry( ).SetEntryL( iMsgId ); + TRAP_IGNORE( iMtm->LoadMessageL() ); + EntryChangedL( ); + LOGTEXT(_L8("NotViewerAppUi: Reply end error")); + User::Leave( error ); + } + else + { + LOGTEXT(_L8("NotViewerAppUi: Reply end success")); + if (!(iEditorBaseFeatures & EStayInViewerAfterReply)) + { + Exit( EAknSoftkeyBack ); + } + } + } + +// --------------------------------------------------------- +// DeleteNotificationL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DeleteNotificationL() + { + LOGTEXT(_L8("NotViewerAppUi: Delete start")); + __ASSERT_DEBUG( iOperation == NULL, Panic( ENotViewerOperationNotFinished ) ); + CMsgEditorDocument* doc = Document( ); + CNotMtmUi* uiMtm = static_cast( &doc->MtmUi( ) ); + + + if( iFlags & ENotViewerIsNotification ) + { // This is a notification -> lets see if we have options + LOGTEXT(_L8("NotViewerAppUi: Delete: We r dealing with a notification")); + + TBool inboxNotification = EFalse; + + if( iMtm->Entry().Entry().Parent() == KMsvGlobalInBoxIndexEntryId ) + {// Are we in Inbox now + inboxNotification = ETrue; + LOGTEXT(_L8("NotViewerAppUi: Delete: in Inbox")); + } + + if( inboxNotification && uiMtm->DeleteQueryRequiredByMtm( ) && !AlreadyDeletedFromServer( ) ) + { // We are in Inbox, delete options supported and not deleted from server + LOGTEXT(_L8("NotViewerAppUi: Delete: Lets show the delete options")); + TInt index = 0; + + CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog( &index ); + dlg->PrepareLC( R_NOTVIEWER_DELETE_FROM_QUERY ); + + // Populate list query array + CDesCArrayFlat *array = new(ELeave) CDesCArrayFlat(2); + CleanupStack::PushL(array); + HBufC* buf = StringLoader::LoadLC( R_NOTVIEWER_DELETE_QUERY_REMOTEONLY ); + array->AppendL( *buf ); + CleanupStack::PopAndDestroy(); //buf + buf = StringLoader::LoadLC( R_NOTVIEWER_DELETE_QUERY_BOTHLOCALANDREMOTE ); + array->AppendL( *buf ); + CleanupStack::PopAndDestroy(); //buf + dlg->SetItemTextArray( array ); + CleanupStack::Pop(); //array + + LOGTEXT(_L8("NotViewerAppUi: Delete: Next asks the delete options")); + TInt queryOk = dlg->RunLD(); + if( queryOk ) + { + /* list query approved, index is usable to see what list item was selected */ + if( index == 0 ) + { + iFlags &= ~ENotViewerDeleteBoth; + LOGTEXT(_L8("NotViewerAppUi: Delete: Just the server")); + } + else + { // If action withe server was selected, keep it in mind + iFlags |= ENotViewerDeleteBoth; + LOGTEXT(_L8("NotViewerAppUi: Delete: Both ones")); + } + // The deletion process starts a bit later + } + else + { + // list query was cancelled -> just return + LOGTEXT(_L8("NotViewerAppUi: Delete: Query cancelled")); + return; + } + } + else + { // In this case we need just a query "Delete message?" + LOGTEXT(_L8("NotViewerAppUi: Delete: Show just Delete message?")); + if( ShowConfirmationQueryL( R_NOTVIEWER_QUEST_DELETE_MESSAGE ) ) + { // Delete message confirmed + LOGTEXT(_L8("NotViewerAppUi: Delete: Answered Yes")); + if( inboxNotification ) + { + // We are in Inbox, so it means we delete just the local one + LOGTEXT(_L8("NotViewerAppUi: Delete: Inbox notification again")); + CAknInputBlock* abs = CAknInputBlock::NewLC( ); + + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + selection->AppendL( iMtm->Entry().EntryId() ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + + LOGTEXT(_L8("NotViewerAppUi: Delete: Inbox locl deletion starts")); + CMsvOperation* deleteop = iMtm->DeleteNotificationL( + *selection, + EMmsDeleteNotificationOnly, + wait->iStatus ); + + LOGTEXT(_L8("NotViewerAppUi: Delete: and goes on..")); + if( !deleteop ) // Check this just in case + { + CleanupStack::PopAndDestroy( wait ); + CleanupStack::PopAndDestroy( selection ); + CleanupStack::PopAndDestroy( abs ); + LOGTEXT(_L8("NotViewerAppUi: Delete: NULL returned")); + return; + } + + CleanupStack::PushL( deleteop ); + wait->Start(); + + if( wait->iStatus != KErrNone ) + { + LOGTEXT(_L8("NotViewerAppUi: Delete: Wait->iStatus != KErrNone ")); + CleanupStack::PopAndDestroy( 3 ); // op, wait, sel + CleanupStack::PopAndDestroy( abs ); + return; + } + + // -> no error, we can exit the viewer + CleanupStack::PopAndDestroy( 3 ); // op, wait, sel + CleanupStack::PopAndDestroy( abs ); + // This was the local deletion so lets just exit from here + LOGTEXT(_L8("NotViewerAppUi: Delete: Local delete succesfull - exit")); + Exit( EAknSoftkeyBack ); + } + else + { + // else we are in MMBoxFolder and we can continue + // there we always need action with server and local + LOGTEXT(_L8("NotViewerAppUi: Delete: We have mmbox notification")); + iFlags |= ENotViewerDeleteBoth; + } + } + else + { // Answer was NO. + return; + } + } + // OK, now we are either in Inbox and chose some action related to server + // or we are in MMBoxView and wanted to delete a message in there.. + + if( !CheckAPSettingsL( ) ) + { // Are the settings OK + return; + } + LOGTEXT(_L8("NotViewerAppUi: Delete: AP Checked")); + // Just in case to make sure after checking settings + iMtm->Entry( ).SetEntryL( iMsgId ); + iMtm->LoadMessageL( ); + + if( iFlags & ENotViewerOffline + && MsvUiServiceUtilitiesInternal::IsPhoneOfflineL() ) + { // We are in offline at the moment -> Infonote and return + ShowInformationNoteL( R_NOTVIEWER_OFFLINE_NOT_POSSIBLE, EFalse ); + return; + } + LOGTEXT(_L8("NotViewerAppUi: Delete: Not Offline")); + + // OK, lets go on with the deletion process + CAknInputBlock* abs = CAknInputBlock::NewLC( ); + + CMsvSingleOpWatcher* singleOpWatcher=CMsvSingleOpWatcher::NewL(*this); + CleanupStack::PushL(singleOpWatcher); + + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + selection->AppendL( iMtm->Entry().EntryId() ); + + CMsvProgressReporterOperation* reporter = + CMsvProgressReporterOperation::NewL( + doc->Session(), + singleOpWatcher->iStatus, + EMbmAvkonQgn_note_erased ); + CleanupStack::PushL(reporter); + + LOGTEXT(_L8("NotViewerAppUi: Delete: Call unscheduled delete")); + CMsvOperation* deleteop = iMtm->UnscheduledDeleteNotificationL( + *selection, + EMmsDeleteMMBoxOnly, + reporter->RequestStatus() ); + LOGTEXT(_L8("NotViewerAppUi: Delete: End of call")); + reporter->SetProgressDecoder( *this ); + reporter->SetOperationL( deleteop ); // Takes immediate ownership + CleanupStack::Pop( reporter ); //reporter + CleanupStack::PopAndDestroy( selection); // selection ownership moved to reporter? + CleanupStack::Pop( singleOpWatcher ); + + iOperation = singleOpWatcher; + LOGTEXT(_L8("NotViewerAppUi: Delete: Set operation")); + iOperation->SetOperation( reporter ); + + CleanupStack::PopAndDestroy( abs ); + } + else if( !iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { // New Forward Request: It's not been saved -> just Exit + if( ShowConfirmationQueryL( R_NOTVIEWER_QUEST_DELETE_MESSAGE ) ) + { + Exit( EAknSoftkeyBack ); + } + } + else + { // We have an open Sent Forward Request open + if( ShowConfirmationQueryL( R_NOTVIEWER_QUEST_DELETE_MESSAGE ) ) + { + DeleteAndExitL( ); + } + } + LOGTEXT(_L8("NotViewerAppUi: Delete: End")); + } + +// --------------------------------------------------------- +// CallToNumberL +// --------------------------------------------------------- +// +void CNotViewerAppUi::CallToNumberL() + { + if( !(iFlags & ENotViewerIsNotification) ) + { // We are in forward request + return; + } + if ( !iMsgVoIPExtension ) + { + iMsgVoIPExtension = CMsgVoIPExtension::NewL(); + } + + TPtrC senderAddr = KNullDesC( ); + TPtrC senderAlias = KNullDesC( ); + TPtrC focusedAddr = KNullDesC( ); + TBool dialerDisabled = EFalse; + + senderAddr.Set( TMmsGenUtils::PureAddress( iMtm->Sender() ) ); + if ( iAlias ) + { + senderAlias.Set( *iAlias ); + } + + if ( FocusedControlId( ) == EMsgComponentIdBody + && iView + && iView->ItemFinder( ) ) + { + const CItemFinder::CFindItemExt& item = + iView->ItemFinder( )->CurrentItemExt( ); + if ( item.iItemDescriptor + && ( item.iItemType == CItemFinder::EPhoneNumber + || item.iItemType == CItemFinder::EEmailAddress ) ) + { + if ( item.iItemType == CItemFinder::EPhoneNumber ) + { + // Disable dialer + iAvkonAppUi->SetKeyEventFlags( + CAknAppUiBase::EDisableSendKeyShort | + CAknAppUiBase::EDisableSendKeyLong ); + dialerDisabled = ETrue; + } + focusedAddr.Set( *(item.iItemDescriptor) ); + } + } + + if ( FocusedControlId( ) == EMsgComponentIdFrom && + senderAddr.Length() && + iSenderType == EMuiuAddressTypePhoneNumber ) + { + // Disable dialer + iAvkonAppUi->SetKeyEventFlags( + CAknAppUiBase::EDisableSendKeyShort | + CAknAppUiBase::EDisableSendKeyLong ); + dialerDisabled = ETrue; + } + // Only when dialer is disabled try placing the call + if ( dialerDisabled ) + { + MsvUiServiceUtilitiesInternal::InternetOrVoiceCallServiceL( + *iMsgVoIPExtension, + senderAddr, + senderAlias, + focusedAddr, + ETrue, + iEikonEnv ); + } + } + + +// --------------------------------------------------------- +// MessageDetailsL +// --------------------------------------------------------- +// +void CNotViewerAppUi::MessageDetailsL( ) + { + LOGTEXT(_L8("NotViewerAppUi: Details start")); + //These are not used! They just have to be there. + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + TBuf8<1> param; + param.Zero(); + + CAknInputBlock::NewLC( ); + + CMsvSingleOpWatcher* watch = CMsvSingleOpWatcher::NewLC( *Document() ); + + CMsgEditorDocument* doc = Document( ); + + CMsgAddressControl* cntrl = AddressControl( ); + + if ( !cntrl ) + { + return; + } + + CNotMtmUi* uiMtm = static_cast( &doc->MtmUi( ) ); + + if ( !(iFlags & ENotViewerIsNotification) ) + { + // Need to save only if addresses are changed. + if ( cntrl && cntrl->IsModified() ) + { + iAddressHandler->CopyAddressesToMtmL( EMsvRecipientTo ); + iMtm->SaveMessageL(); + } + } + + CMsvOperation* op = uiMtm->InvokeAsyncFunctionL( + KMtmUiFunctionMessageInfo, + *selection, + watch->iStatus, + param ); + CleanupStack::Pop(); // watch + Document()->AddSingleOperationL( op, watch ); + + CleanupStack::PopAndDestroy( 2 ); // selection, CAknInputBlock + LOGTEXT(_L8("NotViewerAppUi: Details end")); + } + +// --------------------------------------------------------- +// AddRecipientL +// --------------------------------------------------------- +// +void CNotViewerAppUi::AddRecipientL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddRecipient start")); + if( iFlags & ENotViewerIsNotification ) + { // We are in notification + return; + } + + TBool invalid = EFalse; + + TBool addressesAdded = iAddressHandler->AddRecipientL( invalid ); + + if ( addressesAdded ) + { + + Document()->SetHeaderModified( ETrue ); + + CMsgAddressControl* to = NULL; + to = AddressControl( ); + + if ( iView->FocusedControl() != to ) + { + // Focus was not in address control -> Move it + iView->SetFocus( EMsgComponentIdTo ); + } + } + LOGTEXT(_L8("NotViewerAppUi: AddRecipient end")); + } + + +// --------------------------------------------------------- +// CheckNamesL +// --------------------------------------------------------- +// +void CNotViewerAppUi::CheckNamesL( ) + { + LOGTEXT(_L8("NotViewerAppUi: CheckNamesL start")); + if( iFlags & ENotViewerIsNotification ) + { // We are in notification + return; + } + TBool dummy; + VerifyAddressesL( dummy ); + } + +// --------------------------------------------------------- +// VerifyAddressesL +// --------------------------------------------------------- +// +TBool CNotViewerAppUi::VerifyAddressesL( TBool& aModified ) + { + LOGTEXT(_L8("NotViewerAppUi: VerifyAddresses start")); + if( iFlags & ENotViewerIsNotification ) + { // We are in notification + return EFalse; + } + aModified = EFalse; + TBool retVal = iAddressHandler->VerifyAddressesL( aModified ); + if ( aModified ) + { + Document()->SetHeaderModified( ETrue ); + } + LOGTEXT(_L8("NotViewerAppUi: VerifyAddressesL end")); + return retVal; + } + + +// --------------------------------------------------------- +// RichText +// --------------------------------------------------------- +// +CRichText& CNotViewerAppUi::RichText() const + { + CMsgBaseControl* baseControl = iView->ControlById( + EMsgComponentIdBody ); + CMsgBodyControl* bodyControl = STATIC_CAST( + CMsgBodyControl*, + baseControl ); + return bodyControl->TextContent( ); + } + +// --------------------------------------------------------- +// DoSaveL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DoSaveL( ) + { + LOGTEXT(_L8("NotViewerAppUi: DoSaveL start")); + iMtm = &(Document()->Mtm()); + if( !(iFlags & ENotViewerIsNotification) && !iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + iAddressHandler->CopyAddressesToMtmL( EMsvRecipientTo ); + + iMtm->SaveMessageL(); + + TMmsMsvEntry tEntry = static_cast( Document()->Entry() ); + + TBuf detailsBuf; + iAddressHandler->MakeDetailsL( detailsBuf ); + tEntry.iDetails.Set( detailsBuf ); + if ( !tEntry.EditorOriented() ) + { + tEntry.SetEditorOriented( ETrue ); + } + tEntry.iDate.UniversalTime(); + + if ( !tEntry.Visible() ) + { + // Save from close or exit save. + // Message should be visible after save + tEntry.SetVisible( ETrue ); + tEntry.SetInPreparation( EFalse ); + } + Document()->CurrentEntry().ChangeL( tEntry ); + + Document()->SetHeaderModified( EFalse ); + } + LOGTEXT(_L8("NotViewerAppUi: DoSaveL end")); + } + +// --------------------------------------------------------- +// DoMsgSaveExitL +// --------------------------------------------------------- +// +void CNotViewerAppUi::DoMsgSaveExitL( ) + { + LOGTEXT(_L8("NotViewerAppUi: DoMsgSaveExitL")); + Exit( EAknSoftkeyBack ); + } + +// --------------------------------------------------------- +// HandleEntryDeletedL +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleEntryDeletedL() + { + LOGTEXT(_L8("NotViewerAppUi: HandleEntryDeletedL")); + Exit( EAknSoftkeyBack ); + } + +// --------------------------------------------------------- +// HandleEntryChangeL +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleEntryChangeL() + { // Call EntryChangedL to update the status + LOGTEXT(_L8("NotViewerAppUi: HandleEntryChangeL start")); + if( !( iFlags & ENotViewerIsNotification ) ) + { // We are not in notification mode -> entry change can be ignored + return; + } + iMtm->Entry( ).SetEntryL( iMsgId ); + TRAP_IGNORE( iMtm->LoadMessageL() ); + EntryChangedL( ); + LOGTEXT(_L8("NotViewerAppUi: HandleEntryChangeL end")); + } + +// --------------------------------------------------------- +// AddItemL +// --------------------------------------------------------- +// +void CNotViewerAppUi::AddItemL(const TDesC& aLabel, const TDesC& aValue ) + { + if ( aLabel.Length() > 0 ) + { + AppendTextL( aLabel , iLabelFormat, iLabelMask ); + } + + if ( aValue.Length() > 0 ) + { + AppendTextL( aValue , iValueFormat, iValueMask ); + } + } + +// --------------------------------------------------------- +// ApplyFormat +// --------------------------------------------------------- +// +void CNotViewerAppUi::ApplyFormat(TCharFormat& aFormat, TCharFormatMask& aMask, TBool aIsLabel) + { + TRect mainPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane ); + TAknLayoutText textLayout; + + if( aIsLabel ) + { // Font for headings + textLayout.LayoutText( + mainPane, + AppLayout::Smart_Messages_Line_1( 0 ) ); + } + else + { // Font for data + textLayout.LayoutText( + mainPane, + AppLayout::Smart_Messages_Line_2( 0 ) ); + } + + aFormat.iFontSpec = textLayout.Font( )->FontSpecInTwips(); + aMask.ClearAll(); + aMask.SetAttrib(EAttFontStrokeWeight); + // If following line in use, it disables text zooming + //aMask.SetAttrib(EAttFontHeight); + aMask.SetAttrib(EAttFontTypeface); + } + +// --------------------------------------------------------- +// AppendTextL +// --------------------------------------------------------- +// +void CNotViewerAppUi::AppendTextL( const TDesC& aText, + const TCharFormat& aFormat, + const TCharFormatMask& aMask ) + { + // Create the modifiable descriptor + HBufC* buf = HBufC::NewLC( aText.Length() ); + TPtr modifiedText = buf->Des(); + modifiedText = aText; + TInt pos(0); + + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( modifiedText ); + + /* + We have three cases, where specific character(s) must be + converted to the CRichText understandable linebreak character + (CEditableText::ELineBreak). + 1) Text contains ascii code linefeed (LF) character 0x0A, which + is converted to linebreak. + 2) Text contains ascii code carrier return (CR) character 0x0D + 3) Text contains both CR and LF characters particularly in this order. + These two characters must be converted to one linebreak. + */ + + TUint LF(0x0A); // Linefeed character in ascii set + TUint CR(0x0D); // Carriage return character in ascii set + + // Case 2 and 3 + while ( ( pos = modifiedText.Locate( CR ) ) != KErrNotFound ) // Locate CR + { + if ( pos + 1 < modifiedText.Length() && LF == modifiedText[pos + 1] ) // Is the next LF? + { + modifiedText.Delete( pos + 1, 1 ); // Delete if LF + } + modifiedText[pos] = CEditableText::ELineBreak; // Replace CR with linebreak + } + + // Case 1 + while ( ( pos = modifiedText.Locate( LF ) ) != KErrNotFound ) // Locate LF + { + modifiedText[pos] = CEditableText::ELineBreak; // Replace LF with linebreak + } + + // Append the modified text to the richtext. + CRichText& rich = RichText(); + + TInt documentPos = rich.DocumentLength(); + + // Every time when text is added, the cursor is left at the end of the line. + // When the new text is added we must first add linebreak and then the text + // linebreak is not added if the text is first item. + if ( iFlags & ENotViewerIsNotFirstItem ) + { + //Append the linebreak to the end of the richtext. + rich.InsertL(documentPos, CEditableText::ELineBreak); + + } + else + { + iFlags |= ENotViewerIsNotFirstItem; + } + + documentPos = rich.DocumentLength(); + rich.SetInsertCharFormatL(aFormat, aMask, documentPos); + rich.InsertL( documentPos, *buf ); + rich.CancelInsertCharFormat(); + + CleanupStack::PopAndDestroy( buf ); + } + +// --------------------------------------------------------- +// CNotViewerAppUi::FocusedControlId +// --------------------------------------------------------- +// +TInt CNotViewerAppUi::FocusedControlId() + { + TInt ret = EMsgComponentIdNull; + if ( iView && iView->FocusedControl() ) + { + ret = iView->FocusedControl()->ControlId(); + } + return ret; + } + +// --------------------------------------------------------- +// Document +// --------------------------------------------------------- +// +CNotViewerDocument* CNotViewerAppUi::Document() const + { + return static_cast( CMsgEditorAppUi::Document() ); + } + +// --------------------------------------------------------- +// LaunchHelpL +// --------------------------------------------------------- +// +void CNotViewerAppUi::LaunchHelpL() + { + LOGTEXT(_L8("NotViewerAppUi: LaunchHelp")); + if ( iFlags & ENotViewerFlagsHelp ) + { + CArrayFix* helpContext = AppHelpContextL(); + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), helpContext ); + } + } + +// --------------------------------------------------------- +// HelpContextL +// --------------------------------------------------------- +// +CArrayFix* CNotViewerAppUi::HelpContextL() const + { + if ( iFlags & ENotViewerFlagsHelp ) + { + CArrayFix* r = new ( ELeave ) CArrayFixFlat(1); + CleanupStack::PushL( r ); + + if ( iFlags & ENotViewerIsNotification ) + { // Notification mode + r->AppendL( TCoeHelpContext( KUidMmsViewer, KMMS_HLP_NOTIFICATION_VIEWER() ) ); + } + else + { + if ( iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + r->AppendL( TCoeHelpContext( KUidMmsViewer, KMMS_HLP_NOTIFICATION_VIEWER() ) ); + } + else + { + r->AppendL( TCoeHelpContext( KUidMmsViewer, KMMS_HLP_MMS_FWD_REQUEST() ) ); + } + } + CleanupStack::Pop( r ); + return r; + } + return NULL; + } + +// ------------------------------------------------------------- +// AddMessageFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddMessageFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddMessageField start")); + TInt resourceId = 0; + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + CTextResolver* resolver = CTextResolver::NewLC(); + const TDesC& error = resolver->ResolveErrorString( entry.iError, CTextResolver::ECtxNoCtxNoSeparator ); + + switch( iMsgStatus ) + { + case ENotViewerStatusFailed: + resourceId = R_NOTVIEWER_INFO_FAILED; + break; + case ENotViewerStatusExpired: + resourceId = R_NOTVIEWER_INFO_EXPIRED; + break; + case ENotViewerStatusForwarding: + resourceId = R_NOTVIEWER_INFO_FORWARDING; + break; + case ENotViewerStatusForwarded: + resourceId = R_NOTVIEWER_INFO_FORWARDED; + break; + case ENotViewerStatusNull: + case ENotViewerStatusWaiting: + default: + resourceId = R_NOTVIEWER_INFO_WAITING; + break; + } + HBufC* message = StringLoader::LoadLC( resourceId ); + AddItemL( message->Des( ), error ); + CleanupStack::PopAndDestroy( 2 ); //message, resolver + LOGTEXT(_L8("NotViewerAppUi: AddMessageField end")); + } +// ------------------------------------------------------------- +// AddSubjectFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddSubjectFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddSubject start")); + TPtrC subject = iMtm->SubjectL( ); + if( subject.Length( ) > 0 ) + { + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_SUBJECT ); + AddItemL( label->Des( ), subject ); + CleanupStack::PopAndDestroy( label ); + } + LOGTEXT(_L8("NotViewerAppUi: AddSubject end")); + } + +// ------------------------------------------------------------- +// AddTextFieldL +// ------------------------------------------------------------- +// +void CNotViewerAppUi::AddTextFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddText start")); + TPtrC text = iMtm->GetExtendedText( ); + if( text.Length( ) > 0 ) + { + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_TEXT ); + AddItemL( label->Des( ), text ); + CleanupStack::PopAndDestroy( label ); + } + LOGTEXT(_L8("NotViewerAppUi: AddText end")); + } + +// ------------------------------------------------------------- +// AddExpiryFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddExpiryFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddExpiry start")); + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_EXPIRES ); + TTime messageDate = iMtm->ExpiryDate( ); + + TLocale locale; + messageDate += locale.UniversalTimeOffset(); + if (locale.QueryHomeHasDaylightSavingOn()) + { + TTimeIntervalHours daylightSaving(1); + messageDate += daylightSaving; + } + + HBufC* dateFormat = StringLoader::LoadLC( R_QTN_DATE_USUAL_WITH_ZERO, iCoeEnv ); + TBuf dateString; + messageDate.FormatL( dateString, *dateFormat ); + CleanupStack::PopAndDestroy(); //dateFormat + + dateFormat = StringLoader::LoadLC( R_QTN_TIME_USUAL_WITH_ZERO, iCoeEnv ); + TBuf timeString; + messageDate.FormatL( timeString, *dateFormat ); + CleanupStack::PopAndDestroy(); //dateFormat + + CDesC16ArrayFlat* array = new(ELeave) CDesC16ArrayFlat( 2 ); + CleanupStack::PushL( array ); + array->AppendL( timeString ); + array->AppendL( dateString ); + HBufC* expiryString = + StringLoader::LoadLC( R_NOTVIEWER_VALUE_EXPIRES, *array, iCoeEnv ); + AddItemL( label->Des( ), expiryString->Des( ) ); + CleanupStack::PopAndDestroy( expiryString ); + CleanupStack::PopAndDestroy( array ); + CleanupStack::PopAndDestroy( label ); + LOGTEXT(_L8("NotViewerAppUi: AddExpiry end")); + } + +// ------------------------------------------------------------- +// AddSizeFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddSizeFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddSize start")); + TInt size = iMtm->MessageTransferSize( ); + + TInt maxSize = static_cast( iMtm->MmsSettings().MaximumReceiveSize( ) ); + if( maxSize > 0 ) + { + if( size > maxSize ) + { + size = maxSize; + } + } + + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_SIZE ); + + TBuf<20> sizeString; + + MsgAttachmentUtils::FileSizeToStringL( sizeString, size, ETrue ); + + sizeString.Trim(); + + AddItemL( label->Des( ), sizeString ); + CleanupStack::PopAndDestroy( label ); + LOGTEXT(_L8("NotViewerAppUi: AddSize end")); + } + +// ------------------------------------------------------------- +// AddClassFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddClassFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddClass start")); + TInt msgClass = iMtm->MessageClass( ); + TInt resourceId; + switch( msgClass ) + { + case EMmsClassPersonal: + { + resourceId = R_NOTVIEWER_VALUE_CLASS_PERSONAL; + break; + } + case EMmsClassAdvertisement: + { + resourceId = R_NOTVIEWER_VALUE_CLASS_ADVERTISEMENT; + break; + } + case EMmsClassInformational: + { + resourceId = R_NOTVIEWER_VALUE_CLASS_INFORMATIVE; + break; + } + default: + { // In case no class is returned (0), don't add the field + return; + } + } + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_CLASS ); + HBufC* value = StringLoader::LoadLC( resourceId ); + AddItemL( label->Des( ), value->Des( ) ); + CleanupStack::PopAndDestroy( value ); + CleanupStack::PopAndDestroy( label ); + LOGTEXT(_L8("NotViewerAppUi: AddClass end")); + } + +// ------------------------------------------------------------- +// AddPriorityFieldL +// ------------------------------------------------------------- +void CNotViewerAppUi::AddPriorityFieldL( ) + { + LOGTEXT(_L8("NotViewerAppUi: AddPriority start")); + TInt msgPri = iMtm->MessagePriority( ); + TInt resourceId; + switch( msgPri ) + { + case EMmsPriorityLow: + { + resourceId = R_NOTVIEWER_VALUE_PRIORITY_LOW; + break; + } + case EMmsPriorityHigh: + { + resourceId = R_NOTVIEWER_VALUE_PRIORITY_HIGH; + break; + } + case EMmsPriorityNormal: + { + resourceId = R_NOTVIEWER_VALUE_PRIORITY_NORMAL; + break; + } + default: + { // In case no priority is returned (0), don't add the field + return; + } + } + HBufC* label = StringLoader::LoadLC( R_NOTVIEWER_LABEL_PRIORITY ); + HBufC* value = StringLoader::LoadLC( resourceId ); + AddItemL( label->Des( ), value->Des( ) ); + CleanupStack::PopAndDestroy( value ); + CleanupStack::PopAndDestroy( label ); + LOGTEXT(_L8("NotViewerAppUi: AddPriority end")); + } + +// --------------------------------------------------------- +// CNotViewerAppUi::ShowConfirmationQueryL +// --------------------------------------------------------- +// +TInt CNotViewerAppUi::ShowConfirmationQueryL( TInt aResourceId ) const + { + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + HBufC* prompt = StringLoader::LoadLC( aResourceId, iCoeEnv ); + TInt retVal = dlg->ExecuteLD( R_NOTVIEWER_CONFIRMATION_QUERY, *prompt ); + CleanupStack::PopAndDestroy( prompt ); + return retVal; + } + +// --------------------------------------------------------- +// CNotViewerAppUi::ShowInformationNoteL +// --------------------------------------------------------- +// +void CNotViewerAppUi::ShowInformationNoteL( TInt aResourceID, TBool aWaiting ) + { + HBufC* string = NULL; + string = StringLoader::LoadLC( aResourceID, iCoeEnv ); + + CAknInformationNote* note = new ( ELeave ) + CAknInformationNote( aWaiting ); + note->ExecuteLD( *string ); + + CleanupStack::PopAndDestroy(); //string + } + +// --------------------------------------------------------- +// CNotViewerAppUi::AddressControl +// --------------------------------------------------------- +// +CMsgAddressControl* CNotViewerAppUi::AddressControl( ) + { + TInt controlType = 0; + if( iFlags & ENotViewerIsNotification ) + { // We are in notification mode + controlType = EMsgComponentIdFrom; + } + else + { // we are in the ForwReq mode + controlType = EMsgComponentIdTo; + } + return static_cast( iView->ControlById( controlType ) ); + } + +// --------------------------------------------------------- +// CNotViewerAppUi::EntryChangedL +// --------------------------------------------------------- +// +void CNotViewerAppUi::EntryChangedL( ) + { + LOGTEXT(_L8("NotViewerAppUi: EntryChangedL start")); + if ( !Document()->IsLaunched() ) + { + return; + } + + TNotViewerStatus status = MessageStatus( ); + if( iMsgStatus != status ) + { + iMsgStatus = status; + + iFlags &= ~ENotViewerIsNotFirstItem; + + CMsgBaseControl* control = iView->RemoveControlL( EMsgComponentIdBody ); + delete control; + + CMsgBodyControl* bodyC = CMsgBodyControl::NewL(iView); + iView->AddControlL(bodyC, EMsgComponentIdBody, EMsgAppendControl, EMsgBody); + + AddMessageFieldL( ); + AddSubjectFieldL( ); + AddTextFieldL( ); + AddSizeFieldL( ); + if( iFlags & ENotViewerIsNotification ) + { // We are in the Viewer so lets add expiry, too + AddExpiryFieldL( ); + } + AddClassFieldL( ); + AddPriorityFieldL( ); + + // without this editor control does not become properly visible + bodyC->Editor( ).NotifyNewDocumentL( ); + } + + // update toolbar + if( iToolbar ) //check to be provided for non-touch devices. + { + CNotViewerDocument* doc = Document( ); + CNotMtmUiData* uiData = &doc->MtmUiDataL( ); + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + if( iFlags & ENotViewerIsNotification ) + { + // return value 0=> OK, !=0 => NOK + if( uiData->OperationSupportedL( KMtmUiFunctionFetchMMS, entry ) ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarRetrieve, + ETrue, + ETrue ); + } + else + { + iToolbar->SetItemDimmed( ENotViewerToolbarRetrieve, + EFalse, + ETrue ); + } + } + } + + LOGTEXT(_L8("NotViewerAppUi: EntryChangedL end")); + } + +// --------------------------------------------------------- +// CNotViewerAppUi::UpdateTitlePaneL +// --------------------------------------------------------- +// +void CNotViewerAppUi::UpdateTitlePaneL( ) + { + LOGTEXT(_L8("NotViewerAppUi: UpdateTitle")); + HBufC* str = StringLoader::LoadLC( R_NOTVIEWER_TITLE_FWD_RQST, iCoeEnv ); + CAknTitlePane* title = static_cast + ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) ); + title->SetTextL( str->Des( ) ); + CleanupStack::PopAndDestroy(); //str + if( !iMtm->Entry( ).Entry( ).ReadOnly() ) + { // We have a new unsent FR, change CBA too + Cba()->SetCommandSetL( R_NOTVIEWER_SOFTKEYS_FORWARD_OPTIONS_CANCEL__CONTEXTOPTIONS ); + Cba()->DrawNow(); + } + } + +// --------------------------------------------------------- +// CNotViewerAppUi::MessageStatus +// --------------------------------------------------------- +// +TNotViewerStatus CNotViewerAppUi::MessageStatus( ) const + { + TNotViewerStatus status = ENotViewerStatusNull; + TTime currentTime; + currentTime.HomeTime( ); + TTime expiryTime = iMtm->ExpiryDate( ); + TLocale locale; + expiryTime += locale.UniversalTimeOffset(); + if (locale.QueryHomeHasDaylightSavingOn()) + { + TTimeIntervalHours daylightSaving(1); + expiryTime += daylightSaving; + } + + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd ) // Notification + { + if( !( entry.iMtmData2 & KMmsOperationForward ) + && ( entry.iMtmData2 & KMmsOperationFetch ) + && !( entry.iMtmData2 & KMmsOperationOngoing ) // It's !ongoing + && ( entry.iMtmData2 & KMmsOperationFinished ) // It's finished + && ( entry.iMtmData2 & KMmsOperationResult || + entry.iError ) ) // There's error code + { // Fetch has been failed + status = ENotViewerStatusFailed; + } + else if( currentTime > expiryTime ) + { + status = ENotViewerStatusExpired; + } + else if( ( entry.iMtmData2 & KMmsOperationForward ) // It's forward + && !( entry.iMtmData2 & KMmsOperationFetch ) // It's not delete + && ( entry.iMtmData2 & KMmsOperationOngoing ) // It's ongoing + && !( entry.iMtmData2 & KMmsOperationFinished ) ) // It's not finished + { // Message is being forwarded + status = ENotViewerStatusForwarding; + } + else if( ( entry.iMtmData2 & KMmsOperationForward ) // It's forward + && !( entry.iMtmData2 & KMmsOperationFetch ) // It's not delete + && !( entry.iMtmData2 & KMmsOperationOngoing ) // It's !ongoing + && ( entry.iMtmData2 & KMmsOperationFinished ) // It's finished + && !( entry.iMtmData2 & KMmsOperationResult ) ) // There was no error + { // Message has been forwarded + status = ENotViewerStatusForwarded; + } + else + { // Normal waiting state + status = ENotViewerStatusWaiting; + } + } + + return status; + } + +// --------------------------------------------------------- +// CNotViewerAppUi::GetTypeL +// --------------------------------------------------------- +// +void CNotViewerAppUi::GetTypeL( ) + { + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd ) // Notification + { + iFlags |= ENotViewerIsNotification; + } + else if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageForwardReq ) // Forward Request + { + iFlags &= ~ENotViewerIsNotification; + } + else + { + User::Leave( KErrNotSupported); // Unsupported msg type + } + iMsgStatus = MessageStatus( ); + } + +// --------------------------------------------------------- +// CNotViewerAppUi::HandleNotifyInt +// +// Notification from central repository +// +// There is no need to check aId as we are listening events +// only from one key +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleNotifyInt( TUint32 /*aId*/, TInt aNewValue ) + { + LOGTEXT(_L8("NotViewerAppUi: HandleNotifyInt")); + if( iFlags & ENotViewerIsNotification ) + { + if ( aNewValue == 0 ) + { + iFlags &= ~ENotViewerAutoFind; + } + else + { + iFlags |= ENotViewerAutoFind; + } + TRAP_IGNORE( SetFindModeL( iFlags & ENotViewerAutoFind ) ); + } + } + +// --------------------------------------------------------- +// CNotViewerAppUi::HandleNotifyGeneric +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleNotifyGeneric( TUint32 /*aId*/ ) + { + //Nothing. + } + +// --------------------------------------------------------- +// CNotViewerAppUi::HandleNotifyError +// --------------------------------------------------------- +// +void CNotViewerAppUi::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. +// + +// --------------------------------------------------------- +// CNotViewerAppUi::SetFindModeL +// --------------------------------------------------------- +// +void CNotViewerAppUi::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 ); + } + } + } + +// ---------------------------------------------------- +// CNotViewerAppUi::OpCompleted +// ---------------------------------------------------- +// +void CNotViewerAppUi::OpCompleted( + CMsvSingleOpWatcher& aOpWatcher, + TInt aCompletionCode ) + { + LOGTEXT(_L8("NotViewerAppUi: OpCompleted start")); + CMsvOperation* op=&aOpWatcher.Operation(); + + if( iOperation ) + { + if( iOperation->Operation( ).Id( ) == op->Id( ) ) + { + delete iOperation; + iOperation = NULL; + } + else + { + // This should never happen ie. unrecognised operation completed + return; + } + } + else + { + // This should never happen ie. unrecognised operation completed + return; + } + + if ( aCompletionCode == KErrCancel ) + { + LOGTEXT(_L8("NotViewerAppUi: OpCompleted end3")); + return; + } + + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + if( ( entry.iMtmData2 & KMmsOperationFetch ) // Fetch + forward + && ( entry.iMtmData2 & KMmsOperationForward ) // == DELETE! + && ( entry.iMtmData2 & KMmsOperationFinished ) // It's finished + && ( entry.iMtmData2 & KMmsOperationResult ) ) // Error code + { + // Error note here! + TRAP_IGNORE( ShowInformationNoteL( R_NOTVIEWER_REMOTE_DELETE_FAILED, EFalse ) ); + // Ignore err + } + else + { + LOGTEXT(_L8("NotViewerAppUi: OpCompleted: First delete successful")); + // If also local chosen, call that and exit + // else show completed note + if( iFlags & ENotViewerDeleteBoth ) + { // Deletion was succesfull, but also local delete still needed + TRAPD( err, DoDeleteOpCompletedL( ) ); + if( err ) + { // We may not leave as we are in non-leaving function + delete iAbsorber; + iAbsorber = NULL; + } + LOGTEXT(_L8("NotViewerAppUi: OpCompleted end2")); + return; + } + else + { + // MMBox Deletion was succesfull + TRAP_IGNORE( ShowInformationNoteL( R_NOTVIEWER_REMOTE_DELETED, EFalse ) ); + // Ignore err + } + } + LOGTEXT(_L8("NotViewerAppUi: OpCompleted end")); + } + +// ---------------------------------------------------- +// CNotViewerAppUi::DoDeleteOpCompletedL +// ---------------------------------------------------- +// +void CNotViewerAppUi::DoDeleteOpCompletedL( ) + { + LOGTEXT(_L8("NotViewerAppUi: DoDeleteOpCompletedL start")); + iAbsorber = CAknInputBlock::NewLC( ); + CleanupStack::Pop(); // Pop the absorber + + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + selection->AppendL( iMtm->Entry().EntryId() ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + + CMsvOperation* deleteop = iMtm->DeleteNotificationL( + *selection, + EMmsDeleteNotificationOnly, + wait->iStatus ); + + if( !deleteop ) // Check this just in case + { + CleanupStack::PopAndDestroy( 2 ); // wait, sel + return; + } + + CleanupStack::PushL( deleteop ); + wait->Start(); + + if( wait->iStatus != KErrNone ) + { + CleanupStack::PopAndDestroy( 3 ); // op, wait, sel + return; + } + + // -> no error, we can exit the viewer + CleanupStack::PopAndDestroy( 3 ); // op, wait, sel + + DoDelayedExitL( 0 ); + LOGTEXT(_L8("NotViewerAppUi: DoDeleteOpCompleted end")); + return; + } + +//-------------------------------- +// DecodeProgress +//-------------------------------- +TInt CNotViewerAppUi::DecodeProgress( + const TDesC8& /*aProgress*/, + TBuf& aReturnString, + TInt& aTotalEntryCount, + TInt& aEntriesDone, + TInt& aCurrentEntrySize, + TInt& aCurrentBytesTrans, + TBool /*aInternal*/ ) + { + aCurrentEntrySize = 0; + aCurrentBytesTrans = 0; + aEntriesDone = 0; + aTotalEntryCount = 0; + StringLoader::Load( aReturnString, + R_NOTVIEWER_WAIT_DELETING_REMOTE, + iCoeEnv ); + return KErrNone; + } + +// --------------------------------------------------------- +// CNotViewerAppUi::HandleIteratorEventL +// --------------------------------------------------------- +// +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +void CNotViewerAppUi::HandleIteratorEventL( TMessageIteratorEvent aEvent ) + { + LOGTEXT(_L8("NotViewerAppUi: HandleIteratorEventL")); + if (aEvent == EFolderCountChanged) + { + InitNavipaneL(); + } + } +#endif + +// --------------------------------------------------------- +// CNotViewerAppUi::InitNavipaneL +// --------------------------------------------------------- +// +void CNotViewerAppUi::InitNavipaneL() + { + LOGTEXT(_L8("NotViewerAppUi: InitNavipaneL start")); +#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 ); + } + + iNaviPane->PushL( *iNaviDecorator ); +#else + TMsvEntry msvEntry = iMtm->Entry( ).Entry( ); + + if( msvEntry.ReadOnly( ) || iFlags & ENotViewerIsNotification ) + // If message is readonly or it is a notification -> + // we need msg ordinal number and scroll arrows visible + { + 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_NOTVIEWER_ORDINAL_NUMBER, *array, iCoeEnv ); + CreateTabGroupL( *buf ); + CleanupStack::PopAndDestroy( 2 ); //buf, array + + iNaviDecorator->MakeScrollButtonVisible( ETrue ); + + //NaviButtons are dimmed by default + if ( IsNextMessageAvailableL( ETrue ) ) + { + iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, EFalse ); + } + if ( IsNextMessageAvailableL( EFalse ) ) + { + iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, EFalse ); + } + } + else // Unsent FR: Make navipane null + { + CreateTabGroupL( KNullDesC ); + } + iNaviPane->PushL( *iNaviDecorator ); // Make it visible +#endif // RD_MSG_NAVIPANE_IMPROVEMENT + LOGTEXT(_L8("NotViewerAppUi: InitNavipaneL end")); + } + +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +// --------------------------------------------------------- +// CNotViewerAppUi::CreateTabGroupL +// --------------------------------------------------------- +// +void CNotViewerAppUi::CreateTabGroupL( const TDesC& aText ) + { + //Delete (possibly) existing navi decorator + delete iNaviDecorator; + iNaviDecorator = NULL; + + //Create TabGroup + iNaviDecorator = iNaviPane->CreateTabGroupL(); + CAknTabGroup* tabGroup = static_cast + ( iNaviDecorator->DecoratedControl() ); + + + 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() ); + + CFbsBitmap* bitmapPriority = NULL; + CFbsBitmap* maskPriority = NULL; + + // Create message priority bitmap + if ( iMtm->MessagePriority() == EMmsPriorityHigh || + iMtm->MessagePriority() == EMmsPriorityLow ) + { + // Set path of bitmap file + TParse fileParse; + fileParse.Set( KMmsUiMbmFile, &KDC_APP_BITMAP_DIR, 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 ); + CleanupStack::Pop( bitmapPriority ); + } + else + { + if ( tabGroup->TabCount() == 0 ) + { + tabGroup->AddTabL( 0, aText ); + } + else + { + tabGroup->ReplaceTabL( 0, aText ); + } + } + + tabGroup->SetActiveTabById( 0 ); + tabGroup->SetTabFixedWidthL( KTabWidthWithOneTab ); + } +#endif // !RD_MSG_NAVIPANE_IMPROVEMENT + +// --------------------------------------------------------- +// CNotViewerAppUi::AlreadyDeletedFromServer +// --------------------------------------------------------- +// +TBool CNotViewerAppUi::AlreadyDeletedFromServer( ) + { + TBool resp = EFalse; + TMsvEntry entry = iMtm->Entry( ).Entry( ); + if( ( entry.iMtmData2 & KMmsOperationFetch ) // Fetch + forward + && ( entry.iMtmData2 & KMmsOperationForward ) // == DELETE! + && ( entry.iMtmData2 & KMmsOperationFinished ) // It's finished + && !( entry.iMtmData2 & KMmsOperationResult ) ) // No error code + { // Message fetch has been failed + resp = ETrue; + } + return resp; + } + +// --------------------------------------------------------- +// CNotViewerAppUi::CheckAPSettingsL +// --------------------------------------------------------- +// +TBool CNotViewerAppUi::CheckAPSettingsL( ) + { + LOGTEXT(_L8("NotViewerAppUi: CheckAPSettingsL start")); + CMsgEditorDocument* doc = Document( ); + + CNotMtmUi* uiMtm = static_cast( &doc->MtmUi( ) ); + + CMmsSettingsDialog::TMmsExitCode exitCode = CMmsSettingsDialog::EMmsExternalInterrupt; + + if ( iToolbar ) //check to be provided for non-touch devices. + { + iToolbar->HideItemsAndDrawOnlyBackground( ETrue ); // Hide the toolbar before settings dialog is launched + } + // Enable Dialer as MMS Settings dialog may be launched + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + if( !uiMtm->CheckSettingsL( exitCode ) ) + { + + // Refresh the settings because they were changed + iSettingsHandler->RefreshSettingsL( ); + TInt32 ap = iSettingsHandler->MmsSettings( )->AccessPoint( 0 ); + + //settings saved + if( !( exitCode==CMmsSettingsDialog::EMmsBack && uiMtm->ApExistsL( ap ) ) ) + { // Settings NOK + if ( iToolbar ) //check to be provided for non-touch devices. + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); // Show the toolbar + } + return EFalse; + } + //Settings now OK + } + if ( iToolbar ) //check to be provided for non-touch devices. + { + iToolbar->HideItemsAndDrawOnlyBackground( EFalse ); // Show the toolbar + } + if( exitCode==CMmsSettingsDialog::EMmsExit ) + { + // Exit was called + Exit( ); + } + + LOGTEXT(_L8("NotViewerAppUi: CheckAPSettingsL end")); + return ETrue; + } + +// --------------------------------------------------------- +// DoDelayedExitL +// --------------------------------------------------------- +void CNotViewerAppUi::DoDelayedExitL( const TInt aDelay ) + { + delete iIdle; + iIdle = 0; + iIdle = CPeriodic::NewL( EPriorityNormal - 1 ); + iIdle->Start( aDelay, + aDelay, + TCallBack( DelayedExit, this ) ); + } + +// --------------------------------------------------------- +// DelayedExit +// --------------------------------------------------------- +TInt CNotViewerAppUi::DelayedExit( TAny* aThis ) + { + CNotViewerAppUi* editor = static_cast( aThis ); + TRAP_IGNORE( editor->DoInternalExitL() ); + CAknEnv::RunAppShutter( ); + return KErrNone; + } + +// --------------------------------------------------------- +// DoExternalExitL +// --------------------------------------------------------- +void CNotViewerAppUi::DoInternalExitL() + { + delete iAbsorber; // Remove absorber now just in case + iAbsorber = NULL; + Exit( EAknSoftkeyBack ); + } + +// --------------------------------------------------------- +// EditorObserver +// --------------------------------------------------------- +void CNotViewerAppUi::EditorObserver(TMsgEditorObserverFunc aFunc, TAny* aArg1, TAny* aArg2, TAny* aArg3) + { + TRAP_IGNORE(DoEditorObserverL(aFunc,aArg1,aArg2,aArg3 ) ); + } + +// --------------------------------------------------------- +// EditorObserver +// --------------------------------------------------------- +void CNotViewerAppUi::DoEditorObserverL(TMsgEditorObserverFunc aFunc, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/) + { + switch ( aFunc ) + { + case EMsgButtonEvent: + { + if( !( iFlags & ENotViewerIsNotification ) && !iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + CMsgAddressControl* addrControl = AddressControl( ); + if( addrControl == static_cast( aArg1 ) ) + { + TBool modified = EFalse; + if ( addrControl->GetRecipientsL()->Count() ) + { + // Recipients found. Verify addresses. + if ( !VerifyAddressesL( modified ) ) + { + // Illegal address found. + modified = ETrue; + } + } + if ( !modified )//else + { + // Nothing changed on the UI. Open PhoneBook. + AddRecipientL(); + } + } + } + } + break; + case EMsgHandleFocusChange: + case EMsgControlPointerEvent: + { + // Enable Dialer + iAvkonAppUi->SetKeyEventFlags( 0x00 ); + break; + } + default: + break; + } + } + +// ----------------------------------------------------------------------------- +// handles the touch-ui related control events for next/previous message +// ----------------------------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +#ifndef RD_MSG_NAVIPANE_IMPROVEMENT +void CNotViewerAppUi::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 +#endif + +// --------------------------------------------------------- +// DynInitToolbarL +// --------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +void CNotViewerAppUi::DynInitToolbarL( TInt /*aResourceId*/, + CAknToolbar* aToolbar ) + { + if ( iToolbar + && iToolbar == aToolbar ) + { + // Dimming buttons follow + CNotViewerDocument* doc = Document( ); + CNotMtmUiData* uiData = &doc->MtmUiDataL( ); + TMsvEntry entry = iMtm->Entry( ).Entry( ); + + if( iFlags & ENotViewerIsNotification ) + { + // Hide always Send and Add + iToolbar->HideItem( ENotViewerToolbarSend, + ETrue, + EFalse ); + iToolbar->HideItem( ENotViewerToolbarAdd, + ETrue, + EFalse ); + + if( uiData->OperationSupportedL( KMtmUiFunctionFetchMMS, entry ) ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarRetrieve, + ETrue, + EFalse ); + } + if( iMtm->Sender().Length()==0 ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarReply, + ETrue, + EFalse ); + } + if( uiData->OperationSupportedL( KMtmUiFunctionDeleteMessage, entry ) ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarDelete, + ETrue, + EFalse ); + } + } + else + { + // Hide always Retrieve and Reply + iToolbar->HideItem( ENotViewerToolbarRetrieve, + ETrue, + EFalse ); + iToolbar->HideItem( ENotViewerToolbarReply, + ETrue, + EFalse ); + + if( !iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarDelete, + ETrue, + EFalse ); + } + if( iMtm->Entry( ).Entry( ).ReadOnly( ) ) + { + iToolbar->SetItemDimmed( ENotViewerToolbarSend, + ETrue, + EFalse ); + iToolbar->SetItemDimmed( ENotViewerToolbarAdd, + ETrue, + EFalse ); + } + } + + } + } +#endif + + +// --------------------------------------------------------- +// OfferToolbarEventL +// --------------------------------------------------------- +// +#ifdef RD_SCALABLE_UI_V2 +void CNotViewerAppUi::OfferToolbarEventL( TInt aCommand ) + { + switch ( aCommand ) + { + case ENotViewerToolbarRetrieve: + HandleCommandL( ENotViewerRetrieve ); + break; + + case ENotViewerToolbarReply: + HandleCommandL( ENotViewerReplyViaMessage ); + break; + + case ENotViewerToolbarSend: + HandleCommandL( ENotViewerSend ); + break; + + case ENotViewerToolbarAdd: + HandleCommandL( ENotViewerAddRecipient ); + break; + + case ENotViewerToolbarDelete: + HandleCommandL( ENotViewerDelete ); + break; + + default: + break; + } + } + +// --------------------------------------------------------- +// OperationOngoing +// --------------------------------------------------------- +// +TBool CNotViewerAppUi::OperationOngoing( const TMsvEntry& aEntry ) const + { + return ( aEntry.iMtmData2 & KMmsOperationOngoing + && !( aEntry.iMtmData2 & KMmsOperationFinished ) ); + } + +// --------------------------------------------------------- +// OperationFinished +// --------------------------------------------------------- +// +TBool CNotViewerAppUi::OperationFinished( const TMsvEntry& aEntry ) const + { + return ( aEntry.iMtmData2 & KMmsOperationFinished + && !( aEntry.iMtmData2 & KMmsOperationOngoing ) ); + } + +// --------------------------------------------------------- +// HandleForegroundEventL +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleForegroundEventL(TBool aForeground) + { + if ( AknLayoutUtils::PenEnabled() ) + { + if ( !iToolbar ) + { + iToolbar = CurrentFixedToolbar(); + if ( iToolbar ) + { + iToolbar->SetToolbarObserver( this ); + iToolbar->DisableToolbarL( ETrue ); + } + } + } + CMsgEditorAppUi::HandleForegroundEventL( aForeground ); + } +#endif + +// --------------------------------------------------------- +// HandleResourceChangeL +// --------------------------------------------------------- +// +void CNotViewerAppUi::HandleResourceChangeL(TInt aType) + { + // Base class call must be first + CMsgEditorAppUi::HandleResourceChangeL(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 ) + { + SetTitleIconL(); + } + } + +// --------------------------------------------------------- +// SetTitleIconL +// --------------------------------------------------------- +// +void CNotViewerAppUi::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 ); + }