email/mail/ViewerSrc/MsgMailViewerAttachmentsDlg.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/mail/ViewerSrc/MsgMailViewerAttachmentsDlg.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,701 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  This dialog is used for Attachment handling.
+*
+*/
+
+
+// INCLUDE FILES
+#include "MsgMailViewerAttachmentsDlg.h"
+#include "MsgMailViewerAppUi.h"
+#include "msgmailviewer.hrh"
+#include "MsgMailUIDs.h"    // Application Uid
+#include "MsgMailDRMHandler.h"
+#include "MailUtils.h"
+#include "MailLog.h"
+
+#include <CMailMessage.h>
+#include <CMessageData.h>
+
+#include <AiwGenericParam.h>
+#include <impicmds.h>
+#include <sendui.h>
+#include <SenduiMtmUids.h>  // Send UI MTM uid's
+#include <StringLoader.h>
+#include <eiklbo.h>
+
+#include <MuiuMsvUiServiceUtilities.h> // DiskSpaceBelow
+#include <MsgAttachmentModel.h>
+#include <MsgAttachmentInfo.h>
+#include <MsgEditorAppUi.hrh>   // EditorBase commands
+#include <MsgAttachmentModelObserver.h>
+#include <MsgEditorAppUi.rsg> // R_MEB_ATTACHMENTS_MENUPANE
+#include <MsgMailViewer.rsg>
+
+#include <hlplch.h>
+#include <csxhelp/mail.hlp.hrh>
+#include <featmgr.h>
+
+// CONSTANTS
+_LIT(KMessageMimeType, "message/rfc822");
+const TInt KMSKControlID(3);
+
+enum TStatusFlags
+	{
+    EObserverAdded = KBit0
+    };
+
+// ================= MEMBER FUNCTIONS =======================
+
+CMsgMailViewerAttachmentsDlg* CMsgMailViewerAttachmentsDlg::NewL(
+	TDesC& aTitle, CMsgAttachmentModel& aAttachmentModel,
+    CMsgMailViewerDocument& aDocument,
+    MMsgMailAttachmentDialogObserver& aDlgObserver )
+	{
+    CMsgMailViewerAttachmentsDlg* self =
+        new(ELeave) CMsgMailViewerAttachmentsDlg(
+        aTitle, aAttachmentModel, aDocument, aDlgObserver );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+    
+	CleanupStack::Pop( self );
+	return self;
+	}
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg
+// ----------------------------------------------------------------------------
+//
+CMsgMailViewerAttachmentsDlg::CMsgMailViewerAttachmentsDlg(
+    TDesC& aTitle, CMsgAttachmentModel& aAttachmentModel,
+    CMsgMailViewerDocument& aDocument,
+    MMsgMailAttachmentDialogObserver& aDlgObserver )
+    :CMsgViewAttachmentsDialog(aTitle,
+    R_VIEWER_ATTACHMENTS_MENU, aAttachmentModel),
+    iDocument(aDocument), iFlags(0), iDlgObserver(aDlgObserver) 
+    {
+    }
+
+CMsgMailViewerAttachmentsDlg::~CMsgMailViewerAttachmentsDlg()
+    {
+    LOG("CMsgMailViewerAttachmentsDlg: destructor");
+    
+    // report to observer
+    iDlgObserver.AttachmentDialogExit();
+    
+    if ((iFlags & EObserverAdded))
+    	{
+    	iDocument.Session().RemoveObserver(*this);
+    	}
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::NotifySizeChanged
+// -----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::NotifySizeChanged()
+    {
+    if(iListBox)
+        {
+        iListBox->SizeChanged();
+        }
+    else
+        {
+        LOG("CMsgMailViewerAttachmentsDlg::NotifySizeChanged: iListBox NULL");
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::HandleListBoxEventL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::HandleListBoxEventL(
+    CEikListBox* /*aListBox*/, TListBoxEvent aEventType )
+    {
+    LOG("CMsgMailViewerAttachmentsDlg::HandleListBoxEventL");
+    if ( !MenuShowing() )
+        {
+		if ( aEventType == EEventEnterKeyPressed ||
+		     aEventType == EEventItemDoubleClicked )
+		    {
+		    const TInt index(CurrentListItemIndex());
+		    if ( index != KErrNotFound )
+		        {
+		        UpdateMiddleSoftKeyL( index );
+		        DoFetchOrOpenL( index );
+		        }
+		    }
+		else if ( aEventType == EEventItemClicked )
+			{
+			const TInt index(CurrentListItemIndex());
+			if ( index != KErrNotFound )
+				{
+				UpdateMiddleSoftKeyL( index );
+				}
+		    }
+		}
+    }
+
+// ----------------------------------------------------------------------------
+// ConstructL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::ConstructL()
+    {
+    CMsgViewAttachmentsDialog::ConstructL(iDocument.CurrentEntry());
+
+    iDocument.Session().AddObserverL(*this);
+    iFlags |= EObserverAdded;
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::DynInitMenuPaneL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::DynInitMenuPaneL(
+    TInt aMenuId, CEikMenuPane* aMenuPane)
+    {
+    CMsgViewAttachmentsDialog::DynInitMenuPaneL( aMenuId, aMenuPane );
+    const TInt index(CurrentListItemIndex());
+
+    if (aMenuId == R_MEB_ATTACHMENTS_MENUPANE)
+        {
+        // this shouldn't happen...
+        if (index == KErrNotFound)
+            {
+            return;
+            }
+
+        CMsgAttachmentInfo& attaInfo =
+            iAttachmentModel.AttachmentInfoAt(index);
+
+        if (attaInfo.IsFetched())
+            {
+            aMenuPane->SetItemDimmed(EMsgViewAttachmentCmdOpen, EFalse);
+            aMenuPane->SetItemDimmed(
+                EMsgViewAttachmentCmdRemove,
+                !CanRemoveAttachment( attaInfo ) );
+
+            //Saving changed so that all files supported or unsupported
+            //can be saved.
+            //CDocumentHandler can still prevent saving,
+            //but shouldn't do so.
+            aMenuPane->SetItemDimmed(
+            	EMsgViewAttachmentCmdSave,
+            	! (iDocument.CanSaveFileL( attaInfo.DataType() )) );
+
+            // attachment is not banned type
+            if (!MailUtils::IsClosedMimeL(attaInfo.DataType().Des()))
+                {
+                // not a message type
+                if (!attaInfo.DataType().Des().Compare(KMessageMimeType) == 0)
+                    {
+                    // -> display send via menu
+                    TInt index = 0;
+                    aMenuPane->ItemAndPos(EMsgViewAttachmentCmdOpen, index);
+
+                    TSendingCapabilities capabilities(
+                        0, 0, TSendingCapabilities::ESupportsAttachments);
+                    iDocument.SendUiL().AddSendMenuItemL(
+                    	*aMenuPane,
+                    	index+3, 								// CSI: 47 # third command below attachments.
+                    	EMsgMailViewerFirstFreeCommandId,
+                    	capabilities );
+                    }
+                }
+
+            }
+        else
+            {
+            aMenuPane->SetItemDimmed(EMsgViewAttachmentCmdFetch, EFalse);
+            }
+        if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ))
+            {
+            aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue );
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::FetchRemoteAttachmentL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::FetchRemoteAttachmentL( TInt aIndex )
+    {
+    CMsvEntry& currEntry = iDocument.CurrentEntry();
+    CMsgAttachmentInfo& modelInfo = iAttachmentModel.AttachmentInfoAt(aIndex);
+	if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL(
+	    currEntry.Session(),
+	    modelInfo.Size()) )
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+	TInt status( MailUtils::EQueryAttachmentFetch );
+	if ( !iDocument.IsOnLineL() )
+		{
+		status |= MailUtils::EConnectionOffline;
+		}
+	if ( MailUtils::LargeAttachmentQueryL(
+			iAttachmentModel.AttachmentInfoAt(aIndex).Size(),
+			status ) )
+		{
+	 	iDocument.FetchAttachmentL( modelInfo.AttachmentId() );
+        // Now message is fetched?, we'll update datatype information in
+        // the HandleSessionEventL
+		}
+     }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::UpdateModelInfoL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::UpdateModelInfoL( TInt aIndex )
+    {
+    CMsgAttachmentInfo& modelInfo =
+        iAttachmentModel.AttachmentInfoAt( aIndex );
+    if ( modelInfo.IsFetched() )
+        {
+	    RFile attachmentHandle = iAttachmentModel.GetAttachmentFileL(
+		    aIndex );
+	    CleanupClosePushL( attachmentHandle );
+
+		TDataType dataType = iDocument.ResolveMimeType( attachmentHandle );
+	    
+	    if(dataType.Des().Length())
+	        {
+	        //Successful recognition.
+	        modelInfo.SetDataType(dataType);    
+	        }
+	    
+	    MsgMailDRMHandler* drmHandler = MsgMailDRMHandler::NewL();
+	    CleanupStack::PushL( drmHandler );
+	    CMsgAttachmentInfo::TDRMDataType  drmType =
+	        drmHandler->GetDRMDataTypeL( attachmentHandle );
+        modelInfo.SetDRMDataType( drmType );
+		CleanupStack::PopAndDestroy(2);							// CSI: 47 # drmHandler, handle
+        }
+    }
+
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::UpdateAttachmentsFetchFlags
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::UpdateAttachmentsFetchFlags()
+    {
+    //Update attachmentmodel to secure model is up to date.
+    for(TInt itemIndex=0; itemIndex<iAttachmentModel.NumberOfItems(); itemIndex++)
+        {
+        CMsgAttachmentInfo& attInfo =
+        iAttachmentModel.AttachmentInfoAt(itemIndex);
+
+        TMsvEntry entry;
+        TMsvId serviceId;
+
+        if ( iDocument.CurrentEntry().Session().GetEntry(
+        attInfo.AttachmentId(), serviceId, entry ) == KErrNone )
+            {
+            //Update is not done for message entries.
+            //This is done because for some reason we
+            //can't get file handle for this type of attachment.
+            //Also entry.Complete() flag doesn't work with them.
+            //This shouldn't be a problem because attached messages (= KUidMsvMessageEntry type)
+            //are fetched with original mail and updating of model info 
+            //isn't necessary.
+            if(entry.iType != KUidMsvMessageEntry)
+                {
+                LOG( "CMsgMailViewerAttachmentsDlg::EMsvEntriesChanged: FOUND" );
+                attInfo.SetFetched( entry.Complete() );
+                //Old UpdateModelInfoL call was removed because it caused
+                //Panic when exiting dialog too quicly.
+                //Reason for Panic was MIME resolving which takes lot of time
+                //and can return after dialog object is destroyed.
+                }
+            else
+                {
+                LOG("CMsgMailViewerAttachmentsDlg::UpdateAttachmentModelL: KUidMsvMessageEntry");
+                }
+            }
+        }
+        
+    //If there are attachments update the middle soft key
+    //according to the first attachment
+    if( iAttachmentModel.NumberOfItems() > 0 )
+	    {
+	    TRAP_IGNORE( UpdateMiddleSoftKeyL(CurrentListItemIndex()) );	
+	    }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::OfferKeyEventL
+// ----------------------------------------------------------------------------
+//
+TKeyResponse CMsgMailViewerAttachmentsDlg::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent, TEventCode aType)
+    {
+    // Consume send keys, so that they are not handled in the appui
+    if( aType == EEventKey && aKeyEvent.iCode == EKeyYes )
+        {
+        return EKeyWasConsumed;
+        }  
+    
+    TInt index( CurrentListItemIndex() );
+     if ( index != KErrNotFound && !MenuShowing() )
+        {
+        if ( aType == EEventKey )
+            {
+            if( aKeyEvent.iCode == EKeyOK )
+                {
+                DoFetchOrOpenL( index );
+                return EKeyWasConsumed;
+                }
+            else if( aKeyEvent.iCode == EKeyBackspace )
+                {
+                CMsgAttachmentInfo& attaInfo =
+                    iAttachmentModel.AttachmentInfoAt(index);
+                if ( CanRemoveAttachment( attaInfo ) )
+                    {
+                    ProcessCommandL(EMsgViewAttachmentCmdRemove);
+                    }
+                return EKeyWasConsumed;
+                }
+            }
+        else if ( aType == EEventKeyUp )
+            {
+            UpdateMiddleSoftKeyL( index );
+            }
+        }
+
+    return CMsgViewAttachmentsDialog::OfferKeyEventL(aKeyEvent, aType);
+    }
+
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::ProcessCommandL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::ProcessCommandL(TInt aCommandId)
+    {
+    MAIL_ALLOC_TEST( DoProcessCommandL( aCommandId ) );
+    }
+
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewAttachmentsDlg::GetHelpContext
+// This function is called when Help application is launched.
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::GetHelpContext(
+    TCoeHelpContext& aContext) const
+    {
+    // Uses editor's UID because there's only one help file!
+    aContext.iMajor = TUid::Uid( KUidMsgMailEditor );
+    aContext.iContext = KMAIL_HLP_ATTACHMENTS_VIEWER();
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewAttachmentsDlg::OpenAttachmentL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::OpenAttachmentL()
+    {
+    const TInt index(CurrentListItemIndex());
+    const CMsgAttachmentInfo& info = iAttachmentModel.AttachmentInfoAt(index);
+    const TMsvId id(info.AttachmentId());
+
+    if ( !iDocument.OpenMessageEntryL( id ) )
+        {
+        if ( info.IsSaved() )
+            {
+            SetOpenParamList( NULL );
+            }
+        else if( !OpenParamList() )
+             {
+             TAiwVariant allowSaveVariant( ETrue );
+             TAiwGenericParam genericParamAllowSave( EGenericParamAllowSave,
+                allowSaveVariant );
+             
+             CAiwGenericParamList* paramList = CAiwGenericParamList::NewLC();
+             paramList->AppendL( genericParamAllowSave );
+             SetOpenParamList( paramList );
+             CleanupStack::Pop( paramList );
+             }
+        CMsgViewAttachmentsDialog::ProcessCommandL(EMsgViewAttachmentCmdOpen);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::DoFetchOrOpenL
+// ----------------------------------------------------------------------------
+void CMsgMailViewerAttachmentsDlg::DoFetchOrOpenL( TInt aIndex )
+    {
+    if ( !iAttachmentModel.AttachmentInfoAt(aIndex).IsFetched() )
+        {
+        FetchRemoteAttachmentL( aIndex );
+        }
+    else
+        {
+        OpenAttachmentL();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::DoSendViaL
+// ----------------------------------------------------------------------------
+void CMsgMailViewerAttachmentsDlg::DoProcessCommandL( TInt aCommandId )
+    {
+    HideMenu();
+    const TInt index(CurrentListItemIndex());
+
+    switch (aCommandId)
+        {
+        // handle our own menu command.
+        case EMsgViewAttachmentCmdFetch:
+            FetchRemoteAttachmentL(index);
+            break;
+        case EMsgViewAttachmentCmdRemove:
+  	        PurgeAttachmentL(index);
+            break;
+        case EMsgMailViewerCmdAttachmentCmdExit:
+            TryExitL(EAknSoftkeyOk);
+            break;
+        case EMsgViewAttachmentCmdOpen:
+            OpenAttachmentL();
+            break;
+        case EAknCmdHelp:
+            // Launch help
+            HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(),
+                iEikonEnv->EikAppUi()->AppHelpContextL() );
+			break;
+        case EMsgMailViewerFirstFreeCommandId:
+        	DoSendViaL();
+        	break;
+        default:
+            // call parent class to process other commands.
+            CMsgViewAttachmentsDialog::ProcessCommandL(aCommandId);
+            break;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::DoSendViaL
+// ----------------------------------------------------------------------------
+void CMsgMailViewerAttachmentsDlg::DoSendViaL()
+    {
+	CMessageData* messageData = CMessageData::NewL();
+	CleanupStack::PushL(messageData);
+
+	RFile attachentHandle = iAttachmentModel.GetAttachmentFileL(
+		CurrentListItemIndex() );
+	CleanupClosePushL( attachentHandle );
+	messageData->AppendAttachmentHandleL( attachentHandle );
+    CleanupStack::PopAndDestroy(); // attachentHandle
+
+    TSendingCapabilities capabilities(
+    	0, 0, TSendingCapabilities::ESupportsAttachments);
+
+	// Three services to dim
+    CArrayFixFlat<TUid>* servicesToDim = new(ELeave) CArrayFixFlat<TUid>( 3 );		// CSI: 47 # See a comment above.
+    CleanupStack::PushL( servicesToDim );
+
+    servicesToDim->AppendL( KSenduiMtmMmsUid );
+    servicesToDim->AppendL( KSenduiMtmSmtpUid );
+
+    iDocument.SendUiL().ShowQueryAndSendL( messageData, capabilities, servicesToDim );
+
+    CleanupStack::PopAndDestroy(2);							// CSI: 47 # servicesToDim, messageData
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::PurgeAttachmentL
+// ----------------------------------------------------------------------------
+void CMsgMailViewerAttachmentsDlg::PurgeAttachmentL( TInt aIndex )
+    {
+   CMsgAttachmentInfo& attInfo =
+        iAttachmentModel.AttachmentInfoAt(aIndex);
+    TParsePtrC parser(attInfo.FileName());
+    HBufC* string = StringLoader::LoadLC(R_MAIL_VIEWER_REMOVE_ATTACHMENT,
+        parser.NameAndExt(), iEikonEnv);
+
+    if ( MailUtils::ConfirmationQueryL(*string) )
+        {
+		iDocument.RemoveAttachmentL( attInfo.AttachmentId() );
+        attInfo.SetFetched(EFalse);
+        UpdateIcon(aIndex);
+        }
+    CleanupStack::PopAndDestroy(); // string
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::CanRemoveAttachment
+// ----------------------------------------------------------------------------
+//
+TBool CMsgMailViewerAttachmentsDlg::CanRemoveAttachment(
+    CMsgAttachmentInfo& aInfo )
+    {
+    // POP3 entry or IMAP local entry does not support purge attachment
+    const CMsvEntry& messageEntry = iDocument.CurrentEntry();
+
+    return ( messageEntry.Entry().iMtm == KSenduiMtmImap4Uid &&
+        messageEntry.OwningService() != KMsvLocalServiceIndexEntryIdValue &&
+        aInfo.IsAttachedThisSession() && aInfo.IsFetched() );
+    }
+
+// ---------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::SetMiddleSoftKeyLabelL
+// ---------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::SetMiddleSoftKeyLabelL(
+    TInt aResourceId, TInt aCommandId )
+    {
+    HBufC* middleSKText = StringLoader::LoadLC( aResourceId );
+
+    ButtonGroupContainer().AddCommandToStackL(
+        KMSKControlID,
+        aCommandId,
+        *middleSKText );
+    CleanupStack::PopAndDestroy( middleSKText );
+    }
+
+// ---------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::UpdateMiddleSoftKeyL
+// ---------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::UpdateMiddleSoftKeyL( TInt aIndex )
+    {
+    ASSERT( aIndex >= 0 && aIndex < iAttachmentModel.NumberOfItems() );
+    CMsgAttachmentInfo& attInfo =
+        iAttachmentModel.AttachmentInfoAt( aIndex );
+
+    if ( attInfo.IsFetched() )
+        {
+        // switch command from "fetch" to "open"
+        ButtonGroupContainer().RemoveCommandFromStack(
+            KMSKControlID, EMsgViewAttachmentCmdFetch );
+        SetMiddleSoftKeyLabelL(
+            R_QTN_MSK_OPEN, EAknSoftkeyOpen );
+        }
+    else
+        {
+        // switch command from "open" to "fetch"
+        ButtonGroupContainer().RemoveCommandFromStack(
+            KMSKControlID, EAknSoftkeyOpen );
+        SetMiddleSoftKeyLabelL(
+            R_QTN_MSK_FETCH, EMsgViewAttachmentCmdFetch );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::HandleSessionEventL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::HandleSessionEventL(TMsvSessionEvent aEvent,
+            TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/)
+    {
+    if ( aEvent == EMsvEntriesChanged && aArg1 )
+        {
+        CMsvEntrySelection* changedEntries =
+            static_cast<CMsvEntrySelection*>( aArg1 );
+        UpdateChangedAttachmentsL( *changedEntries );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::UpdateChangedAttachmentsL
+// Update model and UI e.g. due to attachment fetching. We cannot update
+// attached messages but that is not a problem since they are automatically
+// fetched along with the parent message.
+// -----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::UpdateChangedAttachmentsL(
+    const CMsvEntrySelection& aChangedEntries )
+    {
+    TInt changedCount( aChangedEntries.Count() );
+    for ( TInt changedIndex( 0 ); changedIndex < changedCount; ++changedIndex )
+        {
+        TMsvId changedId( aChangedEntries[changedIndex] );
+        TInt attachmentCount( iAttachmentModel.NumberOfItems() );
+        for ( TInt attaIndex( 0 ); attaIndex < attachmentCount; ++attaIndex )
+            {
+            CMsgAttachmentInfo& attaInfo =
+                iAttachmentModel.AttachmentInfoAt( attaIndex );
+            if ( attaInfo.AttachmentId() == changedId )
+                {
+                TMsvEntry entry;
+                TMsvId serviceId;
+                if ( iDocument.CurrentEntry().Session().GetEntry(
+                    changedId, serviceId, entry ) == KErrNone &&
+                    entry.iType != KUidMsvMessageEntry )
+                    {
+                    attaInfo.SetFetched( entry.Complete() );
+                    UpdateModelInfoL( attaIndex );
+                    UpdateMiddleSoftKeyL( attaIndex );
+                    UpdateIcon( attaIndex );
+                    }
+                break; // continue with next changed entry
+                }
+            }
+        }    
+    }
+
+ // -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::OkToExitL
+// -----------------------------------------------------------------------------
+//
+TBool CMsgMailViewerAttachmentsDlg::OkToExitL(TInt aButtonId)
+    {
+    //Check if user has selected exit from menu
+    // -> whole application shall be closed.
+    if ( aButtonId == EAknSoftkeyOk )
+        {
+        if ( CMsgViewAttachmentsDialog::OkToExitL(aButtonId) )
+           {
+           CEikAppUi* appUi = iEikonEnv->EikAppUi();
+           static_cast<MEikCommandObserver*>(appUi)->ProcessCommandL(
+            EAknCmdExit );
+           return ETrue;
+           }
+        else
+           {
+           return EFalse;
+           }
+        }
+
+     else if ( aButtonId == EMsgViewAttachmentCmdFetch )
+        {
+        DoProcessCommandL( aButtonId );
+        return EFalse;
+        }
+
+    //Let base class decide if it ok to exit
+    return CMsgViewAttachmentsDialog::OkToExitL(aButtonId);
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsgMailViewerAttachmentsDlg::UpdateAttatchmentListL
+// Update attatchmentlist
+// -----------------------------------------------------------------------------
+//
+void CMsgMailViewerAttachmentsDlg::UpdateAttatchmentListL()
+	{
+	// Handles item addition
+	ItemAddedL();
+	}
+
+//  End of File
+
+
+