diff -r d189ee25cf9d -r 3533d4323edc emailuis/emailui/src/FreestyleEmailDownloadInformationMediator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/emailui/src/FreestyleEmailDownloadInformationMediator.cpp Wed Sep 01 12:28:57 2010 +0100 @@ -0,0 +1,942 @@ +/* +* Copyright (c) 2005 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: Freestyle Email application attachment download info mediator +* +*/ + + +// INCLUDE FILES +#include "emailtrace.h" +#include +// +#include "cfsmailclient.h" +// +#include +#include + +#include "FreestyleEmailUiConstants.h" +#include "FreestyleEmailUiLiterals.h" +#include "FreestyleEmailUiUtilities.h" +#include "FreestyleEmailDownloadInformationMediator.h" +#include "freestyleemailcenrephandler.h" +#include "FreestyleEmailUiAppui.h" +#include "FSEmail.pan" + + +// ============================ MEMBER FUNCTIONS =============================== + +// ---------------------------------------------------- +// CFSEmailDownloadInfoMediator::CFSEmailDownloadInfoMediator + +// Default class constructor. +// ---------------------------------------------------- +// +CFSEmailDownloadInfoMediator::CFSEmailDownloadInfoMediator( CFSMailClient& aMailClient ) + : CActive( EPriorityNormal ), iMailClient(aMailClient), + iDownloadArray( KArrayGranularity, _FOFF(TDownload, iRequestId) ), iDownloadsStarted ( EFalse ), + iNotificationsInProgress( 0 ), iObserverDeleted( EFalse ) + { + FUNC_LOG; + CActiveScheduler::Add( this ); + } + +// ---------------------------------------------------- +// CFSEmailDownloadInfoMediator::ConstructL +// Second phase class constructor. +// ---------------------------------------------------- +// +void CFSEmailDownloadInfoMediator::ConstructL() + { + FUNC_LOG; + } + +// ---------------------------------------------------- +// CFSEmailDownloadInfoMediator::NewL +// Two-phased class constructor. +// Singleton +// ---------------------------------------------------- +// +CFSEmailDownloadInfoMediator* CFSEmailDownloadInfoMediator::NewL( CFSMailClient& aMailClient ) + { + FUNC_LOG; + + CFSEmailDownloadInfoMediator* singleton = NULL; + + // Check Thread Local Storage for instance pointer + singleton = static_cast( UserSvr::DllTls( KTlsHandleDownloadInfo ) ); + if ( !singleton ) + { + singleton = new ( ELeave ) CFSEmailDownloadInfoMediator( aMailClient ); + CleanupStack::PushL( singleton ); + singleton->ConstructL(); + CleanupStack::Pop( singleton ); + + // Store a pointer of a new instance in Thread Local Storage + TInt err = UserSvr::DllSetTls( KTlsHandleDownloadInfo, singleton ); + if ( err ) + { + delete singleton; + singleton = NULL; + User::Leave( err ); + } + } + + return singleton; + } + + +void CFSEmailDownloadInfoMediator::AddObserver( MFSEmailDownloadInformationObserver* aObserver, TFSMailMsgId aMessageId ) + { + FUNC_LOG; + TRequestObserver newObserver = { aObserver, aMessageId }; + //To avoid adding duplicate observers + for ( TInt i=0; i= 0 && idx < iDownloadArray.Count() ) + { + // save the progress info from status events + if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_Status ) + { + iDownloadArray[idx].iCounter = aEvent.iCounter; + iDownloadArray[idx].iMaxCount = aEvent.iMaxCount; + } + + // Make a local copy of the download object as the object may be + // removed from the array before we are finished + download = iDownloadArray[idx]; + + // In case of error, show a note. Note that these notes should not + // be displayed synchronously, since otherwise other events can + // occur that delete objects that are still in use waiting for this + // method to complete (see PDOO-7X93JP). + if ( aEvent.iError && aEvent.iError != KErrCancel ) + { + // Download failed, show error note + if ( aEvent.iError == KErrCouldNotConnect || + aEvent.iError == KErrConnectionTerminated ) + { // connection error + TFsEmailUiUtility::ShowErrorNoteL( + R_FREESTYLE_EMAIL_ERROR_GENERAL_CONNECTION_ERROR, + EFalse ); + } + else // other error + { + TFsEmailUiUtility::ShowErrorNoteL( + R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE, + EFalse ); + } + } + + // Remove download from array if it has been cancelled or failed + if ( aEvent.iProgressStatus == + TFSProgress::EFSStatus_RequestCancelled || aEvent.iError ) + { + iDownloadArray.Remove(idx); + } + // Mark download as completed if download just finished + else if ( aEvent.iProgressStatus == + TFSProgress::EFSStatus_RequestComplete ) + { + if ( !iDownloadArray[idx].iMaxCount ) + { + // Set max count to 1 if no single progress event has arrived + // before download is finished. + iDownloadArray[idx].iMaxCount = 1; + } + iDownloadArray[idx].iCounter = iDownloadArray[idx].iMaxCount; + } + + TInt completedDownloadsToNotify = 0; + + // Find and update the count array entry + TDownloadCount countObject( download.iPartData.iMessageId ); + GetAndUpdateDownloadCountL( countObject, aEvent ); + + // Notification may be given if all ongoing downloads from message + // have finished and there are some properly completed downloads + if ( download.iNotifyComplete && + countObject.iDownloadsCompletedCount && + countObject.iDownloadsCompletedCount == + countObject.iDownloadsStartedCount ) + { + completedDownloadsToNotify = countObject.iDownloadsCompletedCount; + } + + // if download is complete + if ( aEvent.iProgressStatus == + TFSProgress::EFSStatus_RequestComplete && !aEvent.iError ) + { + // if file was set to be saved after download + if ( download.iSaveFileName.CompareC( KNullDesC ) ) + { + CFSMailMessage* mailMessage = iMailClient.GetMessageByUidL( + download.iPartData.iMailBoxId, + download.iPartData.iFolderId, + download.iPartData.iMessageId, + EFSMsgDataEnvelope ); + CleanupStack::PushL( mailMessage ); + CFSMailMessagePart* attachment = mailMessage->ChildPartL( + download.iPartData.iMessagePartId ); + CleanupStack::PopAndDestroy( mailMessage ); + CleanupStack::PushL( attachment ); + if ( TFsEmailUiUtility::OkToSaveFileL( download.iSaveFileName, *attachment ) ) + { + attachment->CopyContentFileL( download.iSaveFileName ); + } + CleanupStack::PopAndDestroy( attachment ); + } + } + + // relay the event to observers + NotifyObserversL( aEvent, download.iPartData ); + + // moved completion note after notifying so that observers can + // clear menus etc. before note is displayed + // if download is complete + if ( aEvent.iProgressStatus == + TFSProgress::EFSStatus_RequestComplete && !aEvent.iError ) + { + // Notification of saved attachments may be given if all downloads of the given message has been completed. + if ( download.iNotifyComplete && countObject.iDownloadsCompletedCount && + countObject.iDownloadsCompletedCount == countObject.iDownloadsStartedCount && + countObject.iSaveRequestedCount > 0 ) + { + TFsEmailUiUtility::SetDownloadSave( ETrue ); + TFsEmailUiUtility::ShowFilesSavedToFolderNoteL( countObject.iDownloadsCompletedCount /*iSaveRequestedCount*/ ); // Fix: ESLX-84ACJ9 + } + // Show "Download completed" if necessary + else if ( CompletionNotesInUseL() && completedDownloadsToNotify ) + { + OpenAttachmentL( download.iPartData, completedDownloadsToNotify ); + } + else if ( download.iNotifyComplete && + countObject.iSaveRequestedCount == 0 ) + { + TFsEmailUiUtility::OpenAttachmentL( download.iPartData ); + } + } + // + } + } + +TBool CFSEmailDownloadInfoMediator::IsAnyAttachmentDownloads() + { + FUNC_LOG; + return iDownloadsStarted; + } + + +TBool CFSEmailDownloadInfoMediator::IsAnyAttachmentDownloads( TFSMailMsgId aMessageId ) + { + FUNC_LOG; + for ( TInt i=0; i attachments; + CleanupResetAndDestroyClosePushL( attachments ); + mailMessage->AttachmentListL( attachments ); + + for ( TInt i=0; iGetPartId() == iDownloadArray[i].iPartData.iMessagePartId ) + { + iDownloadArray[i].iMaxCount = attachments[j]->ContentSize(); + break; + } + } + } + } + } + + CleanupStack::PopAndDestroy( &attachments ); + CleanupStack::PopAndDestroy( mailMessage ); + } + +TBool CFSEmailDownloadInfoMediator::IsDownloadableL( TPartData aPart ) + { + FUNC_LOG; + TBool ret(EFalse); + // if part is downloading, no more checking is needed + if ( !IsDownloading( aPart.iMessagePartId ) ) + { + CFSMailMessage* mailMessage = iMailClient.GetMessageByUidL( + aPart.iMailBoxId, aPart.iFolderId, + aPart.iMessageId, EFSMsgDataEnvelope ); + if ( mailMessage ) + { + CleanupStack::PushL( mailMessage ); + CFSMailMessagePart* mailMessagePart = + mailMessage->ChildPartL( aPart.iMessagePartId ); + // if the file is fetched full + if ( mailMessagePart && + mailMessagePart->FetchLoadState() == EFSFull ) + { + ret = EFalse; + } + else + { + ret = ETrue; + } + delete mailMessagePart; + CleanupStack::PopAndDestroy( mailMessage ); + } + } + return ret; + } + + +void CFSEmailDownloadInfoMediator::Destroy() + { + FUNC_LOG; + CFSEmailDownloadInfoMediator* self = + static_cast( UserSvr::DllTls( KTlsHandleDownloadInfo ) ); + UserSvr::DllFreeTls( KTlsHandleDownloadInfo ); + delete self; + } + +void CFSEmailDownloadInfoMediator::StopObserving( MFSEmailDownloadInformationObserver* aObserver, TFSMailMsgId aMessageId ) + { + FUNC_LOG; + for (TInt i=iObserverArray.Count()-1; i>=0; i--) + { + if ( iObserverArray[i].iObserver == aObserver && iObserverArray[i].iMessageId == aMessageId ) + { + RemoveObserver(i); + } + } + } + +void CFSEmailDownloadInfoMediator::StopObserving( MFSEmailDownloadInformationObserver* aObserver ) + { + FUNC_LOG; + for ( TInt i=iObserverArray.Count()-1; i>=0; i-- ) + { + if ( iObserverArray[i].iObserver == aObserver ) + { + RemoveObserver(i); + } + } + for ( TInt i=iAllObserverArray.Count()-1; i>=0; i-- ) + { + if ( iAllObserverArray[i] == aObserver ) + { + iAllObserverArray.Remove(i); + } + } + } + +void CFSEmailDownloadInfoMediator::RemoveObserver( TInt aIdx ) + { + if ( iNotificationsInProgress == 0 ) + { + // If we're not currently iterating over the array, remove the entry + // immediately. + iObserverArray.Remove( aIdx ); + } + else + { + // We're currently iterating over the array: mark the entry as + // deleted and flag that we've done so. + iObserverArray[aIdx].iDeleted = ETrue; + iObserverDeleted = ETrue; + } + } + +void CFSEmailDownloadInfoMediator::DownloadL( TPartData aPart, TBool aCompleteNote ) + { + FUNC_LOG; + TFileName emptyFileName; + DownloadAndSaveL( aPart, emptyFileName, aCompleteNote ); + } + +void CFSEmailDownloadInfoMediator::DownloadAndSaveL( TPartData aPart, const TDesC& aSaveFileName, TBool aCompleteNote ) + { + FUNC_LOG; + // now there is at least one download started + iDownloadsStarted = ETrue; + TFsEmailUiUtility::SetSaveSelect( ETrue ); + // fetch message part + CFSMailMessage* mailMessage = iMailClient.GetMessageByUidL( aPart.iMailBoxId, aPart.iFolderId, aPart.iMessageId, EFSMsgDataEnvelope ); + CleanupStack::PushL( mailMessage ); + CFSMailMessagePart* messagePart = mailMessage->ChildPartL( aPart.iMessagePartId ); + CleanupStack::PopAndDestroy( mailMessage ); + + // Panic in udeb builds, the condition !messagePart should not be possible + ASSERT( messagePart ); + + // to be on the safer side only leave in urel builds + if ( !messagePart ) + { + User::Leave( KErrNotFound ); + } + + CleanupStack::PushL( messagePart ); + // start download and get request id + TInt requestId = messagePart->FetchMessagePartL( aPart.iMessagePartId, *this, 0 ); + + // store download information + TDownload newDownload( requestId, aPart, aSaveFileName, aCompleteNote ); + AppendDownloadToInternalArraysL( newDownload ); + CleanupStack::PopAndDestroy( messagePart ); + + // It may take some time before the first progress event is received from + // the protocol plug-in. This is true at least with the current Intellisync + // plug-in implementation. Send artificial "0% event" to the UI to ensure that + // the UI shows that the file is being downloaded. + TFSProgress zeroEvent = { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone }; + NotifyObserversL( zeroEvent, aPart ); + } + +void CFSEmailDownloadInfoMediator::CancelDownloadL( + TFSMailMsgId aMessagePartId ) + { + FUNC_LOG; + // Find the corresponding download object + TDownload downloadToCancel; + downloadToCancel.iPartData.iMessagePartId = aMessagePartId; + TInt idx = iDownloadArray.Find( downloadToCancel, + TIdentityRelation(EqualMessagePartId) ); + // Cancel if download object was found + if ( idx >= 0 && idx < iDownloadArray.Count() ) + { + iMailClient.CancelL( iDownloadArray[idx].iRequestId ); + } + } + +void CFSEmailDownloadInfoMediator::CancelAllDownloadsL( TFSMailMsgId aMailBoxId ) + { + // Cancel all downloads within mailbox indicated with aMailBoxId + for (TInt i=0 ; i < iDownloadArray.Count() ; i ++ ) + { + if ( iDownloadArray[i].iPartData.iMailBoxId == aMailBoxId ) + { + iMailClient.CancelL( iDownloadArray[i].iRequestId ); + } + } + } + +TBool CFSEmailDownloadInfoMediator::IsDownloading( + TFSMailMsgId aMessagePartId ) + { + FUNC_LOG; + TInt dlArrayCount = iDownloadArray.Count(); + for ( TInt i = 0; i < dlArrayCount; i++ ) + { + const TDownload& downloadObject = iDownloadArray[i]; + if ( downloadObject.iPartData.iMessagePartId == aMessagePartId ) + { + if ( downloadObject.iCounter < downloadObject.iMaxCount || + downloadObject.iMaxCount <= 0 ) + { + // Only return ETrue if the corresponding download entry is + // found and it's not yet finished. + return ETrue; + } + } + } + return EFalse; + } + +void CFSEmailDownloadInfoMediator::NotifyObserversIfAttachmentsDownloadedL( + TPartData aMessageId ) + { + FUNC_LOG; + CFSMailMessage* mailMessage = iMailClient.GetMessageByUidL( + aMessageId.iMailBoxId, + aMessageId.iFolderId, + aMessageId.iMessageId, + EFSMsgDataEnvelope ); + CleanupStack::PushL( mailMessage ); + + RPointerArray attachments; + CleanupResetAndDestroyClosePushL( attachments ); + mailMessage->AttachmentListL( attachments ); + + for ( TInt i=0 ; iFetchedContentSize(); + TInt totalSize = attachments[i]->ContentSize(); + + if ( fetched == totalSize ) + { + // download has happened => Download Manager should be available in menus + iDownloadsStarted = ETrue; + + // notify observers about completed attachment download + TFSProgress completeEvent = + { + TFSProgress::EFSStatus_RequestComplete, + fetched, + totalSize, + KErrNone + }; + aMessageId.iMessagePartId = attachments[i]->GetPartId(); + NotifyObserversL( completeEvent, aMessageId ); + } + } + + CleanupStack::PopAndDestroy( &attachments ); + CleanupStack::PopAndDestroy( mailMessage ); + } + +void CFSEmailDownloadInfoMediator::AppendDownloadToInternalArraysL( const TDownload& aNewDownload ) + { + FUNC_LOG; + // In case of some unexpected errors, it's possible that we have an existing download object + // with the same request ID as the new download. In that case, the original download has failed + // and needs to be removed. + TInt foundIdx = iDownloadArray.Find( aNewDownload ); + if ( foundIdx >= 0 ) + { + TFSProgress cancelEvent = { TFSProgress::EFSStatus_RequestCancelled, 0, 0, KErrUnknown }; + TDownload obsoleteDownload = iDownloadArray[foundIdx]; + TDownloadCount countObject( obsoleteDownload.iPartData.iMessageId ); + + iDownloadArray.Remove( foundIdx ); + GetAndUpdateDownloadCountL( countObject, cancelEvent ); + NotifyObserversL( cancelEvent, obsoleteDownload.iPartData ); + } + + // Add the download object to array now when we know that there's no duplicate IDs. + iDownloadArray.Append( aNewDownload ); + + // Add the download to the download count array + TDownloadCount newCountObject( aNewDownload.iPartData.iMessageId ); + TInt idx = iDownloadCountArray.Find( newCountObject, + TIdentityRelation(EqualMessageId) ); + if ( idx >= 0 && idx < iDownloadCountArray.Count() ) + { + // if there are already downloads going on on the same message + iDownloadCountArray[idx].iDownloadsStartedCount++; + if ( aNewDownload.iSaveFileName.CompareC( KNullDesC ) ) + { + iDownloadCountArray[idx].iSaveRequestedCount++; + } + } + else + { + newCountObject.iDownloadsStartedCount = 1; + if ( aNewDownload.iSaveFileName.CompareC( KNullDesC ) ) + { + newCountObject.iSaveRequestedCount=1; + } + iDownloadCountArray.Append( newCountObject ); + } + } + +TBool CFSEmailDownloadInfoMediator::CompletionNotesInUseL() const + { + FUNC_LOG; + // singleton, do not destroy + CFSEmailCRHandler* cenRepHandler = CFSEmailCRHandler::InstanceL(); + + return cenRepHandler->DownloadNotifications(); + } + +void CFSEmailDownloadInfoMediator::OpenAttachmentL( const TPartData& aPart, + const TInt aCompletedCount ) + { + iPopupLaunchData = aPart; + if (aCompletedCount > 1) + { + iPopupLaunchData.iMessagePartId.SetNullId(); + } + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + SetActive(); + } + +void CFSEmailDownloadInfoMediator::LaunchDownloadCompleteNoteL( + const TPartData& aPart, TInt aCompletedCount ) + { + FUNC_LOG; + + Cancel(); // deletes previous iGlobalMsgQuery + + iPopupLaunchData = aPart; + + // fetch message part + CFSMailMessage* mailMessage = iMailClient.GetMessageByUidL( + aPart.iMailBoxId, + aPart.iFolderId, + aPart.iMessageId, + EFSMsgDataEnvelope ); + + CleanupStack::PushL( mailMessage ); + + // From: + HBufC* from = StringLoader::LoadLC( + R_FSE_VIEWER_ATTACHMENTS_TEXT_FROM ); + + CFSMailAddress* senderData = mailMessage->GetSender(); // NOT OWNED + + TDesC& mailSender = senderData->GetDisplayName(); + + // Subject: + HBufC* mailSubject = + TFsEmailUiUtility::CreateSubjectTextLC( mailMessage ); + + HBufC* subj = StringLoader::LoadLC( + R_FSE_VIEWER_ATTACHMENTS_TEXT_SUBJECT ); + + // Attachment name or count + HBufC* attachmentText = NULL; + + CFSMailMessagePart* messagePart = + mailMessage->ChildPartL( aPart.iMessagePartId ); + + if ( messagePart ) + { + // create popup text + + if ( aCompletedCount == 1 ) + { + CleanupStack::PushL( messagePart ); + + attachmentText = messagePart->AttachmentNameL().AllocL(); + + CleanupStack::PopAndDestroy( messagePart ); + + CleanupStack::PushL( attachmentText ); + } + else if ( aCompletedCount > 1 ) + { + attachmentText = StringLoader::LoadLC( + R_FSE_VIEWER_ATTACHMENTS_DOWNLOADED, aCompletedCount ); + iPopupLaunchData.iMessagePartId.SetNullId(); + } + else + { + __ASSERT_DEBUG( EFalse, Panic(EFSEmailUiUnexpectedValue) ); + attachmentText = KNullDesC().AllocLC(); + } + + } + else + { + attachmentText = StringLoader::LoadLC( + R_FSE_VIEWER_ATTACHMENTS_DOWNLOADED, aCompletedCount ); + iPopupLaunchData.iMessagePartId.SetNullId(); + } + + // Combine the text parts into one descriptor + TInt textLength = from->Length() + + KSpace().Length() + + mailSender.Length() + + KLineFeed().Length() + + subj->Length() + + KSpace().Length() + + mailSubject->Length() + + KLineFeed().Length() + + attachmentText->Length(); + + HBufC* popupText = HBufC::NewL( textLength ); + TPtr textPtr = popupText->Des(); + + textPtr.Append( *from ); + textPtr.Append( KSpace ); + textPtr.Append( mailSender ); + textPtr.Append( KLineFeed ); + textPtr.Append( *subj ); + textPtr.Append( KSpace ); + textPtr.Append( *mailSubject ); + textPtr.Append( KLineFeed ); + textPtr.Append( *attachmentText ); + + CleanupStack::PopAndDestroy( attachmentText ); + CleanupStack::PopAndDestroy( subj ); + CleanupStack::PopAndDestroy( mailSubject ); + CleanupStack::PopAndDestroy( from ); + + CleanupStack::PopAndDestroy( mailMessage ); + + CleanupStack::PushL( popupText ); + + HBufC* popupHeader = StringLoader::LoadLC( + R_FSE_VIEWER_NOTE_ATTACHMENTS_DOWNLOAD_COMPLETE ); + + iGlobalMsgQuery = CAknGlobalMsgQuery::NewL(); + + iGlobalMsgQuery->ShowMsgQueryL( + iStatus, + *popupText, + R_AVKON_SOFTKEYS_OPEN_CLOSE, + *popupHeader, + KNullDesC ); + + CleanupStack::PopAndDestroy( popupHeader ); + + CleanupStack::PopAndDestroy( popupText ); + + SetActive(); + } + +void CFSEmailDownloadInfoMediator::NotifyObserversL( const TFSProgress& aEvent, const TPartData& aPart ) + { + FUNC_LOG; + + // notify observers of this particular message part + iNotificationsInProgress++; + TRAPD( error, NotifyPartObserversL( aEvent, aPart ) ); + if ( --iNotificationsInProgress == 0 ) + { + CleanUpObservers(); + } + if ( error ) + { + User::Leave( error ); + } + + // send response to every 'all observer' + for ( TInt i=iAllObserverArray.Count()-1; i>=0; i-- ) + { + iAllObserverArray[i]->RequestResponseL( aEvent, aPart ); + } + } + +void CFSEmailDownloadInfoMediator::NotifyPartObserversL( const TFSProgress& aEvent, const TPartData& aPart ) + { + FUNC_LOG; + // go through all observers + for ( TInt j=iObserverArray.Count()-1; j>=0; j-- ) + { + // if observer is observing this message + if ( !iObserverArray[j].iDeleted && iObserverArray[j].iMessageId == aPart.iMessageId ) + { + // send response to observer + iObserverArray[j].iObserver->RequestResponseL( aEvent, aPart ); + } + } + } + +void CFSEmailDownloadInfoMediator::CleanUpObservers() + { + FUNC_LOG; + // If one or more observers have been marked for deletion, go through + // the observer array and remove them. + if ( iObserverDeleted ) + { + for ( TInt j=iObserverArray.Count()-1; j>=0; j-- ) + { + if ( iObserverArray[j].iDeleted ) + { + iObserverArray.Remove(j); + } + } + iObserverDeleted = EFalse; + } + } + +void CFSEmailDownloadInfoMediator::RunL() + { + FUNC_LOG; + // no close button pressed + if (iStatus.Int() != EAknSoftkeyClose ) + { + // open attachment + if ( !iPopupLaunchData.iMessagePartId.IsNullId() ) + { + // Force FsEmailUI to foreground because global completion note may appear + // while some other application is active and our local error notes are not shown + // in that case. (This wouldn't be necessary in case of succesful file launching.) + TFsEmailUiUtility::BringFsEmailToForeground(); + TFsEmailUiUtility::OpenAttachmentL( iPopupLaunchData ); + } + } + } + +void CFSEmailDownloadInfoMediator::DoCancel() + { + } + +void CFSEmailDownloadInfoMediator::Cancel() + { + FUNC_LOG; + if ( iGlobalMsgQuery ) + { + iGlobalMsgQuery->CancelMsgQuery(); + delete iGlobalMsgQuery; + iGlobalMsgQuery = NULL; + } + if ( IsActive() ) + { + CActive::Cancel(); + } + } + +TInt CFSEmailDownloadInfoMediator::RunError( TInt /*aError*/ ) + { + return KErrNone; + } + +void CFSEmailDownloadInfoMediator::GetAndUpdateDownloadCountL( TDownloadCount& aCountObject, + const TFSProgress& aEvent ) + { + FUNC_LOG; + TInt idx = iDownloadCountArray.Find( aCountObject, + TIdentityRelation(EqualMessageId) ); + if ( idx >= 0 && idx < iDownloadCountArray.Count() ) + { + // Set started save requests, it does not change depending on the event received + aCountObject.iDownloadsStartedCount = iDownloadCountArray[idx].iDownloadsStartedCount; + + // If download completed succesfully, increase the completed downlods count + if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete && + !aEvent.iError ) + { + iDownloadCountArray[idx].iDownloadsCompletedCount++; + } + + // If download was cancelled or failed, decrease started downloads count + else if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled || + aEvent.iError ) + { + iDownloadCountArray[idx].iDownloadsStartedCount--; + } + else + { + // do nothing with other request status values + } + aCountObject = iDownloadCountArray[idx]; + + if ( aCountObject.iDownloadsCompletedCount == + aCountObject.iDownloadsStartedCount ) + { + // The count entry can be removed from the array when all ongoing + // downloads have been completed or cancelled. + iDownloadCountArray.Remove(idx); + + // Remove also all the connected download entries from the iDownloadArray. + for ( TInt i = iDownloadArray.Count()-1 ; i >=0 ; --i ) + { + if ( iDownloadArray[i].iPartData.iMessageId == aCountObject.iMessageId ) + { + iDownloadArray.Remove(i); + } + } + } + } + } + +TBool CFSEmailDownloadInfoMediator::EqualMessageId( const TDownloadCount& aFirst, const TDownloadCount& aSecond ) + { + return (aFirst.iMessageId == aSecond.iMessageId); + } + +TBool CFSEmailDownloadInfoMediator::EqualMessagePartId( const TDownload& aFirst, const TDownload& aSecond ) + { + return (aFirst.iPartData.iMessagePartId == aSecond.iPartData.iMessagePartId); + } +