emailuis/emailui/src/FreestyleEmailUiAttachmentsListModel.cpp
changeset 0 8466d47a6819
child 3 a4d6f1ea0416
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/FreestyleEmailUiAttachmentsListModel.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,634 @@
+/*
+* Copyright (c) 2007 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:  Implements model for the attachment list view
+*
+*/
+
+
+// SYSTEM INCLUDEfS
+//<cmail>
+#include "emailtrace.h"
+#include "CFSMailClient.h"
+//</cmail>
+#include <StringLoader.h>
+#include <FreestyleEmailUi.rsg>
+
+// INTERNAL INCLUDES
+#include "FreestyleEmailUiAppui.h"
+#include "FreestyleEmailUiAttachmentsListModel.h"
+#include "FreestyleEmailUiUtilities.h"
+
+
+////////////////////////////////////
+// CFSEmailUiAttachmentsModelBase //
+////////////////////////////////////
+CFSEmailUiAttachmentsModelBase::CFSEmailUiAttachmentsModelBase( CFreestyleEmailUiAppUi& aAppUi )
+    : iAppUi( aAppUi )
+    {
+    FUNC_LOG;
+    
+    }
+    
+void CFSEmailUiAttachmentsModelBase::ConstructL()
+    {
+    FUNC_LOG;
+    }
+
+CFSEmailUiAttachmentsModelBase::~CFSEmailUiAttachmentsModelBase()
+    {
+    FUNC_LOG;
+    // iDownloadInfoMediator is singleton and destroyed by AppUi
+    }
+
+TBool CFSEmailUiAttachmentsModelBase::StartDownloadL( TFsTreeItemId aTreeId )
+	{
+	TAttachmentData& item = GetItemL( aTreeId );
+	return StartDownloadL( item );
+	}
+
+TBool CFSEmailUiAttachmentsModelBase::StartDownloadL( const TAttachmentData& aAttachment )
+    {
+    FUNC_LOG;
+    TBool retVal = EFalse;
+    if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsDownloadableL( aAttachment.partData ) )
+        {
+        iAppUi.DownloadInfoMediator()->DownloadL( aAttachment.partData );
+        retVal = ETrue;
+        }
+    return retVal;
+    }
+
+TBool CFSEmailUiAttachmentsModelBase::SaveAttachmentL(
+	TFsTreeItemId aTreeId, const TDesC& aFileName, TInt& aSavedCount )
+	{
+    FUNC_LOG;
+	TBool retVal = EFalse;
+	TAttachmentData* attData = GetItem( aTreeId );
+	if ( attData )
+	    {
+	    retVal = SaveAttachmentL( *attData, aFileName, aSavedCount );
+		}
+	return retVal;
+	}
+
+TBool CFSEmailUiAttachmentsModelBase::SaveAttachmentL(
+        const TAttachmentData& aAttachment, const TDesC& aFileName, TInt& aSavedCount )
+    {
+    FUNC_LOG;
+    TBool retVal = EFalse;
+    if ( iAppUi.DownloadInfoMediator() )
+        {
+        if ( aAttachment.downloadProgress != KComplete &&
+            !iAppUi.DownloadInfoMediator()->IsDownloading( aAttachment.partData.iMessagePartId ) )
+            {
+            iAppUi.DownloadInfoMediator()->DownloadAndSaveL( aAttachment.partData, aFileName );
+            retVal = ETrue;
+            }
+        else if ( aAttachment.downloadProgress == KComplete )
+            {
+            CFSMailMessage* mailMessage =
+                iAppUi.GetMailClient()->GetMessageByUidL(
+                    aAttachment.partData.iMailBoxId,
+                    aAttachment.partData.iFolderId,
+                    aAttachment.partData.iMessageId,
+                    EFSMsgDataEnvelope );
+            CleanupStack::PushL( mailMessage );
+                
+            CFSMailMessagePart* attachment = mailMessage->ChildPartL(
+                    aAttachment.partData.iMessagePartId ); 
+            CleanupStack::PushL( attachment );  
+            if ( TFsEmailUiUtility::OkToSaveFileL( aFileName, *attachment ) )       
+                {
+                attachment->CopyContentFileL( aFileName  ); 
+                aSavedCount++;              
+                }           
+            CleanupStack::PopAndDestroy( attachment );              
+            CleanupStack::PopAndDestroy( mailMessage );         
+            }
+        }
+    return retVal;
+    }
+
+void CFSEmailUiAttachmentsModelBase::CancelDownloadL( TFsTreeItemId aTreeId )
+	{
+    FUNC_LOG;
+	TAttachmentData& item = GetItemL( aTreeId );
+	CancelDownloadL( item );
+  	}
+
+void CFSEmailUiAttachmentsModelBase::CancelDownloadL( const TAttachmentData& aAttachment )
+    {
+    FUNC_LOG;
+    iAppUi.DownloadInfoMediator()->CancelDownloadL( aAttachment.partData.iMessagePartId );
+    }
+
+void CFSEmailUiAttachmentsModelBase::RemoveContentL( TFsTreeItemId aTreeId )
+    {
+    FUNC_LOG;
+    TAttachmentData& item = GetItemL( aTreeId );
+    RemoveContentL( item );
+  	}
+
+void CFSEmailUiAttachmentsModelBase::RemoveContentL( const TAttachmentData& aAttachment )
+    {
+    FUNC_LOG;
+    const TPartData& partData = aAttachment.partData;
+
+    CFSMailMessage* mailMessage = iAppUi.GetMailClient()->GetMessageByUidL(
+        partData.iMailBoxId,
+        partData.iFolderId,
+        partData.iMessageId,
+        EFSMsgDataEnvelope );
+    CleanupStack::PushL( mailMessage );
+
+    CFSMailMessagePart* attachmentPart = mailMessage->ChildPartL( partData.iMessagePartId );
+    CleanupStack::PushL( attachmentPart );
+    
+    // try to remove attachment contents from the plugin side
+    attachmentPart->RemoveContentL();
+    
+    // Reset download progress if the content was actually removed
+    if ( !IsCompletelyDownloadedL( aAttachment ) )
+        {
+        TAttachmentData& attachment = CONST_CAST( TAttachmentData&, aAttachment );
+        attachment.downloadProgress = KNone;
+        }
+    
+    CleanupStack::PopAndDestroy( attachmentPart );
+    CleanupStack::PopAndDestroy( mailMessage );
+    }
+
+TBool CFSEmailUiAttachmentsModelBase::IsDownloading(
+	const TAttachmentData& aAttachment )
+	{
+    FUNC_LOG;
+	TBool retVal = iAppUi.DownloadInfoMediator()->IsDownloading(
+		aAttachment.partData.iMessagePartId );
+    return retVal;
+	}
+
+TBool CFSEmailUiAttachmentsModelBase::IsCompletelyDownloadedL(
+	const TAttachmentData& aAttachment )
+    {
+    FUNC_LOG;
+    TBool completed = !IsDownloading( aAttachment ) &&
+                      !iAppUi.DownloadInfoMediator()->IsDownloadableL(
+                      		aAttachment.partData );
+    return completed;
+    }
+    
+TBool CFSEmailUiAttachmentsModelBase::IsMessage( const TAttachmentData& aAttachment ) const
+    {
+    FUNC_LOG;
+    TBool isMessage = (aAttachment.fileType == EMessageType);
+    return isMessage;
+    }
+
+TBool CFSEmailUiAttachmentsModelBase::IsThereAnyCurrentDownloads()
+	{
+    FUNC_LOG;
+  	TBool ret(EFalse);
+  	if ( iAppUi.DownloadInfoMediator() )
+  		{
+  		ret = iAppUi.DownloadInfoMediator()->IsAnyAttachmentDownloads();
+  		}
+	return ret;
+	}
+
+HBufC* CFSEmailUiAttachmentsModelBase::CreateSizeDescLC( TInt aSize )
+    {
+    FUNC_LOG;
+    HBufC* sizeDesc = TFsEmailUiUtility::CreateSizeDescLC( aSize );
+    HBufC* decoratedDesc = StringLoader::LoadL( R_FSE_VIEWER_ATTACHMENTS_LIST_SIZE, *sizeDesc );
+    CleanupStack::PopAndDestroy( sizeDesc );
+    CleanupStack::PushL( decoratedDesc );
+    return decoratedDesc;
+    }
+
+CFreestyleEmailUiAppUi& CFSEmailUiAttachmentsModelBase::AppUi()
+	{
+    FUNC_LOG;
+	return iAppUi;
+	}
+
+  	
+////////////////////////////////////
+// CFSEmailUiAttachmentsListModel //
+////////////////////////////////////
+//MODEL CLASS CONSTRUCTION
+CFSEmailUiAttachmentsListModel* CFSEmailUiAttachmentsListModel::NewL(
+    CFreestyleEmailUiAppUi& aAppUi, MFSEmailUiAttachmentsStatusObserver& aObserver )
+    {
+    FUNC_LOG;
+    CFSEmailUiAttachmentsListModel* self = CFSEmailUiAttachmentsListModel::NewLC( aAppUi, aObserver);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CFSEmailUiAttachmentsListModel* CFSEmailUiAttachmentsListModel::NewLC( CFreestyleEmailUiAppUi& aAppUi,
+                                                                       MFSEmailUiAttachmentsStatusObserver& aObserver )
+    {
+    FUNC_LOG;
+    CFSEmailUiAttachmentsListModel* self = new (ELeave) CFSEmailUiAttachmentsListModel( aAppUi, aObserver );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+void CFSEmailUiAttachmentsListModel::ConstructL()
+    {
+    FUNC_LOG;
+  	CFSEmailUiAttachmentsModelBase::ConstructL();
+    }
+ 
+CFSEmailUiAttachmentsListModel::CFSEmailUiAttachmentsListModel( CFreestyleEmailUiAppUi& aAppUi,
+                                                                MFSEmailUiAttachmentsStatusObserver& aObserver )
+	: CFSEmailUiAttachmentsModelBase( aAppUi ), iObserver( aObserver )
+    {
+    FUNC_LOG;
+    }
+	
+CFSEmailUiAttachmentsListModel::~CFSEmailUiAttachmentsListModel()
+    {
+    FUNC_LOG;
+    if ( iAppUi.DownloadInfoMediator() )
+        {
+        iAppUi.DownloadInfoMediator()->StopObserving( this );
+        }
+    iAttachments.Reset();
+    }
+
+TAttachmentData* CFSEmailUiAttachmentsListModel::GetItem( TFsTreeItemId aTreeId )
+    {
+    FUNC_LOG;
+    TBool found = EFalse;
+    TAttachmentData* returnValue = NULL;
+    const TInt attachmentCount = iAttachments.Count();
+    for ( TInt i = 0; i < attachmentCount && !found; i++ )
+        {
+        if ( iAttachments[i].treeId == aTreeId )
+            {
+            returnValue = &iAttachments[i];
+            found = ETrue;
+            }
+        }
+    return returnValue;
+    }
+
+TAttachmentData& CFSEmailUiAttachmentsListModel::GetItemL( TFsTreeItemId aTreeId )
+    {
+    FUNC_LOG;
+    TAttachmentData* returnValue = GetItem( aTreeId );
+    if ( !returnValue )
+        {
+        User::Leave( KErrNotFound );
+        }
+    return *returnValue;
+    }
+
+TPartData CFSEmailUiAttachmentsListModel::GetMessageL( TFsTreeItemId /*aTreeId*/ )
+    {
+    FUNC_LOG;
+    // All the items in the attachments list view belong to the same message
+    return iMessage;
+    }
+
+const RArray<TAttachmentData>& CFSEmailUiAttachmentsListModel::GetModel()
+	{
+	return iAttachments;
+  	}
+
+void CFSEmailUiAttachmentsListModel::SetNodeIdL( TInt aAttachmentIndex, TFsTreeItemId aTreeItemId )
+	{
+    FUNC_LOG;
+	if ( iAttachments.Count() > aAttachmentIndex )
+		{
+		iAttachments[aAttachmentIndex].treeId = aTreeItemId;
+		}
+	else
+		{
+		User::Leave ( KErrNotFound );
+		}
+	}
+
+void CFSEmailUiAttachmentsListModel::RequestResponseL(
+	const TFSProgress& aEvent, const TPartData& aPart )
+	{
+    FUNC_LOG;
+
+    TBool downloadCompletedAndListUpdated = EFalse;
+
+    if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestComplete )
+        {
+        // We may need to update the list here as POP protocol
+        // creates a new entry when redownloading an
+        // attachment (in POP case the whole mail is
+        // downloaded again). Thus, the list might not be 
+        // up-to-date at this point. Similar kind of handling
+        // is done in UI side.
+    	CFSMailMessage* mailMessage =
+    	    iAppUi.GetMailClient()->GetMessageByUidL(
+    		    aPart.iMailBoxId,
+    		    aPart.iFolderId,
+    		    aPart.iMessageId,
+    		    EFSMsgDataEnvelope );
+
+        CleanupStack::PushL( mailMessage );
+        
+    	RPointerArray<CFSMailMessagePart> mailParts;
+
+    	CleanupResetAndDestroyClosePushL( mailParts );
+
+    	mailMessage->AttachmentListL( mailParts );
+    	
+        TBool listNeedsUpdate = ETrue;
+
+    	TInt count = mailParts.Count();
+
+        for ( TInt i = 0; i < count && listNeedsUpdate; i++ )
+    	    {
+    	    TInt partId = mailParts[ i ]->GetPartId().Id();
+    	    
+    	    listNeedsUpdate = ( aPart.iMessagePartId.Id() != partId );
+    	    }
+
+    	CleanupStack::PopAndDestroy( 2, mailMessage );
+
+        if ( listNeedsUpdate )
+            {
+            UpdateListL( aPart );
+            
+            downloadCompletedAndListUpdated = ETrue;
+            }
+        }
+
+    if ( downloadCompletedAndListUpdated )
+        {
+        // Giving KErrNotFound causes a refresh to UI
+        iObserver.DownloadStatusChangedL( KErrNotFound );
+        }
+    else
+        {
+        TInt index = KErrNotFound;
+
+        TInt attaCount = iAttachments.Count();
+
+    	for ( TInt i = 0; i < attaCount && index == KErrNotFound; i++ )
+    		{
+    	   	if ( iAttachments[i].partData.iMessagePartId ==
+    	   	        aPart.iMessagePartId )
+    	   		{
+    	   		index = i;
+    	   		}
+    		}
+
+        if ( index != KErrNotFound )
+            {
+       		// Currently, it's not very well defined what should be the values
+       		// of each field of TFSProgressStatus in case the download is
+       		// completed or cancelled. For now, we make the assumption that
+       		// these values are correctly set for status events. In complete 
+       		// event we set the progress to 100% and in cancel event to 0%, 
+       		// regardless of the counter values. These may be subjects to
+       		// change.
+            if ( aEvent.iError )
+       		    {
+       		    iAttachments[index].downloadProgress = KNone;
+       		    }
+       		else if ( aEvent.iProgressStatus ==
+       		            TFSProgress::EFSStatus_Status )
+   		        {
+    	   		if ( aEvent.iMaxCount > 0 && aEvent.iCounter > 0 )
+    	   			{
+    				iAttachments[index].downloadProgress =
+    				    KComplete * aEvent.iCounter / aEvent.iMaxCount;
+    	   			}
+    	   		else
+    	   			{
+    	   			iAttachments[index].downloadProgress = KNone;
+    	   			}
+   		        }
+       		else if ( aEvent.iProgressStatus ==
+       		            TFSProgress::EFSStatus_RequestComplete )
+       		    {
+   		        if ( IsCompletelyDownloadedL( iAttachments[index] ) )
+   		            {
+   		            iAttachments[index].downloadProgress = KComplete;
+   		            }
+   		        }
+       		else if ( aEvent.iProgressStatus ==
+       		            TFSProgress::EFSStatus_RequestCancelled )
+   		        {
+   		        iAttachments[index].downloadProgress = KNone;
+   		        }
+
+    	    iObserver.DownloadStatusChangedL( index );
+            }
+        }
+	}
+
+void CFSEmailUiAttachmentsListModel::CancelAllDownloadsL()
+	{
+    FUNC_LOG;
+  	TInt attCount = iAttachments.Count();
+	for ( TInt i = 0; i < attCount; i++ )
+		{
+		if ( iAppUi.DownloadInfoMediator() && iAppUi.DownloadInfoMediator()->IsDownloading(
+			iAttachments[i].partData.iMessagePartId ) )
+			{
+	    	iAppUi.DownloadInfoMediator()->CancelDownloadL(
+	    		iAttachments[i].partData.iMessagePartId );
+			}
+		}
+	}
+	
+TBool CFSEmailUiAttachmentsListModel::IsThereAnyMessageAttachments() const
+    {
+    FUNC_LOG;
+    TBool msgFound = EFalse;
+    TInt attCount = iAttachments.Count();
+    for ( TInt i = 0 ; i < attCount && !msgFound ; i++ )
+        {
+        msgFound = IsMessage( iAttachments[i] );
+        }
+    return msgFound;
+    }
+
+void CFSEmailUiAttachmentsListModel::UpdateListL( CFSMailMessage* aEmbeddedMessage )
+	{
+    FUNC_LOG;
+	iAttachments.Reset();
+
+	CFSMailMessage* mailMessage = aEmbeddedMessage;
+    
+	RPointerArray<CFSMailMessagePart> mailParts;
+	CleanupResetAndDestroyClosePushL( mailParts );
+	mailMessage->AttachmentListL( mailParts );
+	
+	TInt mailPartsCount = mailParts.Count();
+	for ( TInt i = 0; i < mailPartsCount; i++ )
+		{
+        TFileType fileType = TFsEmailUiUtility::GetFileType(
+        	mailParts[i]->AttachmentNameL(),
+        	mailParts[i]->GetContentType() );
+		TPartData partData(	aEmbeddedMessage->GetMailBoxId(),
+                            aEmbeddedMessage->GetFolderId(),
+                            aEmbeddedMessage->GetMessageId(),
+			                mailParts[i]->GetPartId() );
+		TAttachmentData attachment = 
+			{
+			mailParts[i]->ContentSize(),
+			0,
+			fileType,
+			mailParts[i]->AttachmentNameL(),
+			KFsTreeNoneID,
+			partData
+			};
+		attachment.downloadProgress = KComplete;
+		iAttachments.Append( attachment );
+		}
+	CleanupStack::PopAndDestroy( &mailParts );
+	}
+	
+void CFSEmailUiAttachmentsListModel::UpdateListL( TPartData aMessage )
+	{
+    FUNC_LOG;
+	iAttachments.Reset();
+	
+	iMessage = aMessage;
+	iAppUi.DownloadInfoMediator()->StopObserving( this );
+	iAppUi.DownloadInfoMediator()->AddObserver( this, iMessage.iMessageId );
+	CFSMailMessage* mailMessage = iAppUi.GetMailClient()->GetMessageByUidL(
+		iMessage.iMailBoxId,
+		iMessage.iFolderId,
+		iMessage.iMessageId,
+		EFSMsgDataEnvelope );
+    CleanupStack::PushL( mailMessage );
+    
+	RPointerArray<CFSMailMessagePart> mailParts;
+	CleanupResetAndDestroyClosePushL( mailParts );
+	mailMessage->AttachmentListL( mailParts );
+	
+	
+    CFSMailMessagePart* calendarPart = 
+        mailMessage->FindBodyPartL( KFSMailContentTypeTextCalendar );
+    CleanupStack::PushL( calendarPart );
+
+	TInt mailPartsCount = mailParts.Count();
+	for ( TInt i = 0; i < mailPartsCount; i++ )
+		{
+        CFSMailMessagePart* part = mailParts[i];
+		
+        TFileType fileType = TFsEmailUiUtility::GetFileType(
+        	part->AttachmentNameL(),
+        	part->GetContentType() );
+		TPartData partData(	iMessage.iMailBoxId,
+			                iMessage.iFolderId,
+			                iMessage.iMessageId,
+			                part->GetPartId() );
+		
+		TAttachmentData attachment = 
+			{
+			part->ContentSize(),
+			0,
+			fileType,
+			part->AttachmentNameL(),
+			KFsTreeNoneID,
+			partData
+			};
+
+        // figure out and set download progress
+		TUint downloadProgress;
+		if ( IsCompletelyDownloadedL ( attachment ) )
+		    {
+		    downloadProgress = KComplete;
+		    }
+		else if ( part->ContentSize() > 0 )
+			{
+			downloadProgress = KComplete *
+							   mailParts[i]->FetchedContentSize() /
+							   mailParts[i]->ContentSize();
+			}
+		else
+			{
+			downloadProgress = KNone;
+			}
+		attachment.downloadProgress = downloadProgress;
+		
+    	// If MR,do not add ICS file to  attachment list
+		if (! ( mailMessage->IsFlagSet( EFSMsgFlag_CalendarMsg ) 
+		     && calendarPart
+		     && part->GetPartId() == calendarPart->GetPartId() ) )
+		    {
+    		iAttachments.Append( attachment );
+		    }
+		
+		}
+    CleanupStack::PopAndDestroy( calendarPart );
+	CleanupStack::PopAndDestroy( &mailParts );
+	CleanupStack::PopAndDestroy( mailMessage );
+  	}
+	
+TBool CFSEmailUiAttachmentsListModel::SaveAllAttachmentsL(
+	const TDesC& aFileName )
+	{
+    FUNC_LOG;
+	TBool retVal = EFalse;
+	TInt attCount = iAttachments.Count();
+    TInt savedCount( 0 );
+	for ( TInt i = 0; i < attCount; i++ )
+		{
+		TBool downloadStarted = SaveAttachmentL( iAttachments[i], aFileName, savedCount );
+		retVal = downloadStarted || retVal;
+		}
+	if ( savedCount )
+	    {
+	    // <cmail>
+	    TFsEmailUiUtility::ShowFilesSavedToFolderNoteL( savedCount ); 	    
+	    }
+	
+	return retVal;
+	}
+
+TBool CFSEmailUiAttachmentsListModel::DownloadAllAttachmentsL()
+	{
+    FUNC_LOG;
+  	TBool retVal = EFalse;
+  	TInt attCount = iAttachments.Count();
+	for ( TInt i = 0; i < attCount; i++ )
+		{
+		TBool downloadStarted = StartDownloadL( iAttachments[i] );
+		retVal = downloadStarted || retVal;
+		}
+  	return retVal;
+	}
+
+HBufC* CFSEmailUiAttachmentsListModel::CreateMailSubjectTextLC() const
+    {
+    FUNC_LOG;
+	CFSMailMessage* mailMessage = iAppUi.GetMailClient()->GetMessageByUidL(
+		iMessage.iMailBoxId,
+		iMessage.iFolderId,
+		iMessage.iMessageId,
+		EFSMsgDataEnvelope );
+    CleanupStack::PushL( mailMessage );
+    
+    HBufC* subjectText = TFsEmailUiUtility::CreateSubjectTextLC( mailMessage );
+	CleanupStack::Pop( subjectText );
+    CleanupStack::PopAndDestroy( mailMessage );
+    CleanupStack::PushL( subjectText );
+    
+    return subjectText;
+    }
+