diff -r a3a1ae9acec6 -r da5135c61bad meetingrequest/mrcmailremoteattachmentplugin/src/cmrcmailremoteattachmentplugindownloader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrcmailremoteattachmentplugin/src/cmrcmailremoteattachmentplugindownloader.cpp Wed Mar 31 21:08:33 2010 +0300 @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2007-2009 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: + * + */ + +#include "cmrcmailremoteattachmentplugindownloader.h" +#include "mcalremoteattachmentoperationobserver.h" +#include "ccalremoteattachment.h" +#include "esmrhelper.h" +#include "cfsmailclient.h" +#include "cfsmailmessage.h" + +#include + +#include "emailtrace.h" + +// Unnamed namespace for local definitions +namespace { // codescanner::namespace + +// Preferred byte count definition +const TInt KPreferredByteCount(0); + +// Percentage for progress calculation +const TInt KPercentage( 100 ); + +// Literal for temporary path +_LIT( KTempPath, "temp\\" ); + +} + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader( + CFSMailClient& aMailClient, + MCalRemoteAttachmentOperationObserver& aObserver ) +: CActive( EPriorityStandard ), + iMailClient( aMailClient ), + iObserver( aObserver ) + { + CActiveScheduler::Add( this ); + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +CMRCmailRemoteAttachmentDownloader::~CMRCmailRemoteAttachmentDownloader() + { + FUNC_LOG; + + if( IsActive() ) + { + Cancel(); + } + else + { + DoCancel(); + } + delete iMailMessage; + delete iUri; + iAttachmentFile.Close(); + delete iRemoteAttachment; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +CMRCmailRemoteAttachmentDownloader* + CMRCmailRemoteAttachmentDownloader::NewL( + CFSMailClient& aMailClient, + MCalRemoteAttachmentOperationObserver& aObserver, + const TDesC& aUri ) + { + FUNC_LOG; + CMRCmailRemoteAttachmentDownloader* self = + new (ELeave) CMRCmailRemoteAttachmentDownloader( + aMailClient, + aObserver ); + + CleanupStack::PushL( self ); + self->ConstructL( aUri ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::ConstructL( + const TDesC& aUri ) + { + FUNC_LOG; + iUri = aUri.AllocL(); + + TInt error = iMailIdParser.Parse( *iUri ); + User::LeaveIfError( error ); + + // Fetch message structure and construct attachment information + iMailMessage = iMailClient.GetMessageByUidL( + iMailIdParser.iMailboxUid, + iMailIdParser.iFolderUid, + iMailIdParser.iMessageUid, + EFSMsgDataStructure ); + + CFSMailMessagePart* attachment = + iMailMessage->ChildPartL( iMailIdParser.iMessagepartUid ); + CleanupStack::PushL( attachment ); + + TPtrC attachmentName( attachment->AttachmentNameL() ); + TInt attachmentSize( attachment->ContentSize() ); + + MCalRemoteAttachment::TCalRemoteAttachmentState attachmentState( + MCalRemoteAttachment::EAttachmentStateNotDownloaded ); + + if ( EFSFull == attachment->FetchLoadState() ) + { + attachmentState = MCalRemoteAttachment::EAttachmentStateDownloaded; + } + + iRemoteAttachment = CCalRemoteAttachment::NewL( + aUri, + attachmentName, + attachmentSize, + attachmentState ); + + CleanupStack::PopAndDestroy( attachment ); + + // Trigger asynchronous request + IssueRequest(); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::DoCancel +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::DoCancel() + { + FUNC_LOG; + + TRAP_IGNORE( DoCancelL() ); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::RunL +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::RunL() + { + FUNC_LOG; + + // We first check whether attachment is already downloaded to device or not + CFSMailMessagePart* attachment = + iMailMessage->ChildPartL( iMailIdParser.iMessagepartUid ); + CleanupStack::PushL( attachment ); + + if ( EFSFull == attachment->FetchLoadState() ) + { + // Attachment is fecthed to device --> Trigger completion + NotifyCompletionL( *attachment ); + } + else + { + // Attachment is not fetched --> Start fetching attachment + iFSMailOperationId = + attachment->FetchMessagePartL( + iMailIdParser.iMessagepartUid, + *this, + KPreferredByteCount ); + } + + CleanupStack::PopAndDestroy( attachment ); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::RunError +// --------------------------------------------------------------------------- +// +TInt CMRCmailRemoteAttachmentDownloader::RunError( TInt aError ) + { + FUNC_LOG; + + NotifyError( aError ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +TInt CMRCmailRemoteAttachmentDownloader::Progress() const + { + FUNC_LOG; + + TInt progress( 0 ); + TRAP_IGNORE( progress = ProgressL() ); + return progress; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +const MCalRemoteAttachment& + CMRCmailRemoteAttachmentDownloader::AttachmentInformation() const + { + FUNC_LOG; + return *iRemoteAttachment; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::RequestResponseL( + TFSProgress aEvent, + TInt aRequestId ) + { + FUNC_LOG; + + // Make sure that correct notification is received from mail framework + ASSERT( aRequestId == iFSMailOperationId ); + + if ( aRequestId == iFSMailOperationId ) + { + // Fetching message structure + switch ( aEvent.iProgressStatus ) + { + case TFSProgress::EFSStatus_RequestComplete: + { + // Fetch attachment part and notify completion + CFSMailMessagePart* attachment = + iMailMessage->ChildPartL( iMailIdParser.iMessagepartUid ); + CleanupStack::PushL( attachment ); + + NotifyCompletionL( *attachment ); + + CleanupStack::PopAndDestroy( attachment ); + } + break; + + case TFSProgress::EFSStatus_Status: + { + // Notify progress about downloading + TInt progress = ( KPercentage * aEvent.iCounter ) / aEvent.iMaxCount; + iObserver.Progress( this, progress ); + } + break; + + case TFSProgress::EFSStatus_RequestCancelled: + { + // Error occured during fetch operation + NotifyError( KErrCancel ); + } + break; + default: + break; + } + } + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::IssueRequest() + { + FUNC_LOG; + + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::CMRCmailRemoteAttachmentDownloader +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::NotifyCompletionL( + CFSMailMessagePart& aAttachment ) + { + FUNC_LOG; + + // Make sure that file server can share files between processes + RFs& fs = CCoeEnv::Static()->FsSession(); + fs.ShareProtected(); + + // Construct filename for attachment + TFileName fileName( KTempPath ); + fileName.Append( iRemoteAttachment->AttachmentLabel() ); + User::LeaveIfError( + ESMRHelper::CreateAndAppendOthersDirToFileName( fileName ) ); + + // Copy attachment from mail storage to file system + aAttachment.CopyContentFileL( fileName ); + + // Open file handle to attachment + User::LeaveIfError( iAttachmentFile.Open( + fs, + fileName, + EFileRead | EFileShareReadersOnly ) ); + + // Notify observer about completion + iRemoteAttachment->SetAttachmentState( + MCalRemoteAttachment::EAttachmentStateDownloaded ); + + iObserver.OperationCompleted( this, iAttachmentFile ); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::NotifyError +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::NotifyError( TInt aError ) + { + FUNC_LOG; + iObserver.OperationError( this, aError ); + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::ProgressL +// --------------------------------------------------------------------------- +// +TInt CMRCmailRemoteAttachmentDownloader::ProgressL() const + { + FUNC_LOG; + + TInt progress( 0 ); + + CFSMailMessagePart* attachment = + iMailMessage->ChildPartL( iMailIdParser.iMessagepartUid ); + CleanupStack::PushL( attachment ); + + TInt fetchedContent( attachment->FetchedContentSize() ); + TInt contentSize( attachment->ContentSize() ); + progress = ( KPercentage * fetchedContent ) / contentSize; + + CleanupStack::PopAndDestroy( attachment ); + + return progress; + } + +// --------------------------------------------------------------------------- +// CMRCmailRemoteAttachmentDownloader::DoCancelL +// --------------------------------------------------------------------------- +// +void CMRCmailRemoteAttachmentDownloader::DoCancelL() + { + FUNC_LOG; + + CFSMailMessagePart* attachment = + iMailMessage->ChildPartL( iMailIdParser.iMessagepartUid ); + CleanupStack::PushL( attachment ); + + if ( EFSFull != attachment->FetchLoadState() ) + { + iMailClient.CancelL( iFSMailOperationId ); + } + + CleanupStack::PopAndDestroy( attachment ); + } + +// EOF