emailuis/emailui/src/FreestyleEmailUiDownloadManagerModel.cpp
changeset 0 8466d47a6819
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/FreestyleEmailUiDownloadManagerModel.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,449 @@
+/*
+* 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 "FreestyleEmailUiDownloadManagerModel.h"
+#include "FreestyleEmailDownloadInformationMediator.h"
+#include "FreestyleEmailUiUtilities.h"
+
+
+//MODEL CLASS CONSTRUCTION
+CFSEmailUiDownloadManagerModel* CFSEmailUiDownloadManagerModel::NewL( CFreestyleEmailUiAppUi& aAppUi,
+                                                                      MFSEmailUiAttachmentsStatusObserver& aObserver )
+    {
+    FUNC_LOG;
+    CFSEmailUiDownloadManagerModel* self = CFSEmailUiDownloadManagerModel::NewLC( aAppUi, aObserver );
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CFSEmailUiDownloadManagerModel* CFSEmailUiDownloadManagerModel::NewLC( CFreestyleEmailUiAppUi& aAppUi,
+                                                                       MFSEmailUiAttachmentsStatusObserver& aObserver )
+    {
+    FUNC_LOG;
+    CFSEmailUiDownloadManagerModel* self = new (ELeave) CFSEmailUiDownloadManagerModel( aAppUi, aObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+void CFSEmailUiDownloadManagerModel::ConstructL()
+    {
+    FUNC_LOG;
+   	CFSEmailUiAttachmentsModelBase::ConstructL();
+	iMailClient = AppUi().GetMailClient();
+	if ( iAppUi.DownloadInfoMediator() )
+		{
+		iAppUi.DownloadInfoMediator()->AddObserver( this );		
+		}
+    }
+ 
+CFSEmailUiDownloadManagerModel::CFSEmailUiDownloadManagerModel( CFreestyleEmailUiAppUi& aAppUi,
+                                                                MFSEmailUiAttachmentsStatusObserver& aObserver ) 
+	: CFSEmailUiAttachmentsModelBase( aAppUi ), iObserver( aObserver )
+    {
+    FUNC_LOG;
+    }
+	
+CFSEmailUiDownloadManagerModel::~CFSEmailUiDownloadManagerModel()
+    {
+    FUNC_LOG;
+    for (TInt i=0; i<iMails.Count(); i++)
+        {
+        iMails[i].mailAttachments.Close();
+        delete iMails[i].mailSubject;
+        }
+    iMails.Close();
+    if ( iAppUi.DownloadInfoMediator() )
+        {
+        iAppUi.DownloadInfoMediator()->StopObserving( this );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns attachment data for specified tree item, or NULL if not found.
+// ---------------------------------------------------------------------------
+//
+TAttachmentData* CFSEmailUiDownloadManagerModel::GetItem( TFsTreeItemId aTreeId )
+    {
+    FUNC_LOG;
+    const TInt mailCount = iMails.Count();
+    for ( TInt i = 0; i < mailCount; i++ )
+        {
+        const TInt attachmentCount = iMails[i].mailAttachments.Count();
+        for ( TInt j = 0; j < attachmentCount; j++)
+            {
+            if ( iMails[i].mailAttachments[j].treeId == aTreeId )
+                {
+                return &iMails[i].mailAttachments[j];
+                }
+            }
+        }
+
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns attachment data for specified tree item
+// ---------------------------------------------------------------------------
+//
+TAttachmentData& CFSEmailUiDownloadManagerModel::GetItemL( TFsTreeItemId aTreeId )
+	{
+    FUNC_LOG;
+	TAttachmentData* returnValue = GetItem( aTreeId );
+	if ( !returnValue )
+		{
+		User::Leave( KErrNotFound );
+		}
+	return *returnValue;
+	}
+
+TPartData CFSEmailUiDownloadManagerModel::GetMessageL( TFsTreeItemId aTreeId )
+    {
+    FUNC_LOG;
+	TPartData returnValue;
+	TBool found = EFalse;
+	
+	for ( TInt i=0 ; i<iMails.Count() && !found ; i++ )
+		{
+		if ( iMails[i].treeId == aTreeId )
+		    {
+		    returnValue = iMails[i].partData;
+		    found = ETrue;
+		    }
+		else
+		    {
+    		for ( TInt j=0 ; j<iMails[i].mailAttachments.Count() && !found ; j++ )
+    	   		{
+    	   		if ( iMails[i].mailAttachments[j].treeId == aTreeId )
+    	   			{
+    	   			returnValue = iMails[i].partData;
+    	   			found = ETrue;
+    	   			}
+    			}
+		    }
+		}
+	
+	if ( !found )
+		{
+		User::Leave( KErrNotFound );
+		}
+	return returnValue;
+    }
+
+	
+TBool CFSEmailUiDownloadManagerModel::RemoveItem( TFsTreeItemId aTreeId )
+	{
+    FUNC_LOG;
+	TBool found = EFalse;
+	for ( TInt i=0 ; !found && i<iMails.Count() ; i++ )
+		{
+		for ( TInt j=0 ; !found && j<iMails[i].mailAttachments.Count() ; j++ )
+			{
+			if ( iMails[i].mailAttachments[j].treeId == aTreeId )
+				{
+			   	iMails[i].mailAttachments.Remove(j);
+			   	if ( iMails[i].mailAttachments.Count() == 0 )
+			   		{
+			   		iMails.Remove(i);			   		
+			   		}
+			   	found = ETrue;
+				}
+			}
+	   	}
+	return found;
+	}
+
+void CFSEmailUiDownloadManagerModel::SetItemIdL(TUint aMailIndex, TUint aAttachmentIndex, TFsTreeItemId aTreeId)
+	{
+    FUNC_LOG;
+	if ( iMails.Count()>aMailIndex && iMails[aMailIndex].mailAttachments.Count() > aAttachmentIndex )
+		{
+		iMails[aMailIndex].mailAttachments[aAttachmentIndex].treeId = aTreeId;
+		}
+	else
+		{
+		User::Leave ( KErrNotFound );
+		}
+	}
+
+const RArray<TMessageData>& CFSEmailUiDownloadManagerModel::GetModel()
+	{
+	return iMails;
+	}
+
+TInt CFSEmailUiDownloadManagerModel::AttachmentCount() const
+    {
+    FUNC_LOG;
+    TInt count = 0;
+    
+    for ( TInt i=0 ; i<iMails.Count() ; ++i )
+        {
+        count += iMails[i].mailAttachments.Count();
+        }
+        
+    return count;
+    }
+	
+void CFSEmailUiDownloadManagerModel::RequestResponseL( const TFSProgress& aEvent, const TPartData& aPart )
+	{
+    FUNC_LOG;
+	TBool attachmentFound = EFalse;
+	TInt i;
+	for (i=0; i<iMails.Count(); i++)
+		{
+		for (TInt j=0; j<iMails[i].mailAttachments.Count(); j++)
+			{
+		   	if ( iMails[i].mailAttachments[j].partData.iMessagePartId == aPart.iMessagePartId )
+		   		{
+		   		attachmentFound = ETrue;
+    	   		// 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 )
+    	   		    {
+    	   		    iMails[i].mailAttachments[j].downloadProgress = 0;
+    	   		    }
+    	   		else
+    	   		    {
+        	   		switch ( aEvent.iProgressStatus )
+        	   		    {
+        	   		    case TFSProgress::EFSStatus_Status:
+        	   		        {
+                	   		if ( aEvent.iMaxCount > 0 && aEvent.iCounter > 0 )
+                	   			{
+                				iMails[i].mailAttachments[j].downloadProgress = 
+                				    KComplete * aEvent.iCounter / aEvent.iMaxCount;
+                	   			}
+                	   		else
+                	   			{
+                	   			iMails[i].mailAttachments[j].downloadProgress = KNone;
+                	   			}
+        	   		        }
+        	   		    break;
+        	   		    
+        	   		    case TFSProgress::EFSStatus_RequestComplete:
+        	   		        {
+        	   		        iMails[i].mailAttachments[j].downloadProgress = KComplete;
+        	   		        }
+        	   		    break;
+        	   		    
+        	   		    case TFSProgress::EFSStatus_RequestCancelled:
+        	   		        {
+        	   		        iMails[i].mailAttachments[j].downloadProgress = KNone;
+        	   		        }
+        	   		    break;
+        	   		    
+        	   		    default:
+        	   		        // do nothing with other events
+        	   		    break;
+        	   		    }
+    	   		    }
+    	   		
+   	   		    iObserver.DownloadStatusChangedL(i);
+				}
+			}
+		}
+	if ( !attachmentFound )
+		{
+		CFSMailMessage* mailMessage = iAppUi.GetMailClient()->GetMessageByUidL( aPart.iMailBoxId, aPart.iFolderId, aPart.iMessageId, EFSMsgDataEnvelope );
+		CleanupStack::PushL( mailMessage );
+		CFSMailMessagePart* messagePart = mailMessage->ChildPartL( aPart.iMessagePartId );
+		CleanupStack::PushL( messagePart );
+
+    	TFileType fileType = TFsEmailUiUtility::GetFileType( messagePart->AttachmentNameL(),
+    	                                                     messagePart->GetContentType() );
+		TUint downloadProgress;
+		if ( aEvent.iMaxCount > 0 )
+			{
+			downloadProgress = KComplete * aEvent.iCounter / aEvent.iMaxCount;
+   			}
+   		else
+			{
+			downloadProgress = KNone;
+			}
+
+
+		TAttachmentData attachment = 
+			{
+			messagePart->ContentSize(),
+			downloadProgress,
+			fileType,
+			messagePart->AttachmentNameL(),
+			KFsTreeNoneID,
+			aPart
+			};
+
+		TBool messageFound = EFalse;
+		for ( TInt i=0; i<iMails.Count(); i++ )
+			{
+			if ( iMails[i].partData.iMessageId  == aPart.iMessageId )
+				{
+				// Insert the new attachment as the first entry of the message node. 
+				iMails[i].mailAttachments.InsertL( attachment, 0 );
+				iObserver.DownloadStatusChangedL(i);
+				messageFound = ETrue;
+				}
+			}
+
+		if ( !messageFound )
+			{
+			// If no message node is already present in the list, a new one is created on
+			// the top of the list.
+			RArray<TAttachmentData> attachmentData;
+			attachmentData.Append( attachment );
+			
+			HBufC* subjectText = TFsEmailUiUtility::CreateSubjectTextLC( mailMessage );
+			TMessageData msgData = { subjectText, attachmentData, aPart, KFsTreeNoneID };
+			iMails.InsertL( msgData, 0 );
+            CleanupStack::Pop( subjectText );
+			iObserver.DownloadStatusChangedL( 0 );
+			}
+		CleanupStack::PopAndDestroy( messagePart );
+		CleanupStack::PopAndDestroy( mailMessage );
+		}		
+	}
+
+void CFSEmailUiDownloadManagerModel::SetNodeIdL( TInt aNodeIndex, TFsTreeItemId aTreeItemId )
+	{
+    FUNC_LOG;
+	if ( iMails.Count() > aNodeIndex )
+		{
+		iMails[aNodeIndex].treeId = aTreeItemId;
+		}
+	else
+		{
+		User::Leave ( KErrNotFound );
+		}
+
+	}
+
+TBool CFSEmailUiDownloadManagerModel::DownloadAllAttachmentsL()
+    {
+    FUNC_LOG;
+    TBool retVal = EFalse;
+	for (TInt i=0; i<iMails.Count(); i++)
+		{
+		for (TInt j=0; j<iMails[i].mailAttachments.Count(); j++)
+	   		{
+			TBool downloadStarted = StartDownloadL( iMails[i].mailAttachments[j].treeId );
+			retVal = downloadStarted || retVal;
+		   	}
+		}
+	return retVal;	
+    }
+	
+TBool CFSEmailUiDownloadManagerModel::SaveAllAttachmentsL( const TDesC& aFileName )
+	{
+    FUNC_LOG;
+	TBool retVal = EFalse;
+	TInt savedCount( 0 );
+	for (TInt i=0; i<iMails.Count(); i++)
+		{
+		for (TInt j=0; j<iMails[i].mailAttachments.Count(); j++)
+	   		{
+			TBool downloadStarted = SaveAttachmentL( iMails[i].mailAttachments[j].treeId, aFileName, savedCount );
+			retVal = downloadStarted || retVal;
+		   	}
+		}
+	if ( savedCount )
+	    {
+	    // <cmail>
+	    TFsEmailUiUtility::ShowFilesSavedToFolderNoteL( savedCount );        
+	    }
+	return retVal;
+	}
+
+void CFSEmailUiDownloadManagerModel::CancelAllDownloadsL()
+    {
+    FUNC_LOG;
+	for (TInt i=0; i<iMails.Count(); i++)
+		{
+		for (TInt j=0; j<iMails[i].mailAttachments.Count(); j++)
+	   		{
+	   		TFSMailMsgId attPartId = iMails[i].mailAttachments[j].partData.iMessagePartId;
+   			if ( iAppUi.DownloadInfoMediator() )
+   				{
+	   			iAppUi.DownloadInfoMediator()->CancelDownloadL( attPartId );				
+   				}
+			}
+		}
+    }
+
+TBool CFSEmailUiDownloadManagerModel::IsThereAnyMessageAttachments()
+    {
+    FUNC_LOG;
+    TBool msgFound = EFalse;
+    TInt mailCount = iMails.Count();
+    for ( TInt i = 0 ; i < mailCount && !msgFound ; i++ )
+        {
+        TInt attCount = iMails[i].mailAttachments.Count();
+        for ( TInt j = 0 ; j < attCount && !msgFound ; j++ )
+            {
+            const TAttachmentData& attachment = iMails[i].mailAttachments[j];
+            msgFound = IsMessage( attachment );
+            }
+        }
+    return msgFound;
+    }
+    
+TBool CFSEmailUiDownloadManagerModel::ClearInvalidItemsL()
+	{
+    FUNC_LOG;
+	TBool itemWasRemoved = EFalse;
+	
+	// Loop from back to beginning, easier to destroy items.
+	if ( iMails.Count() )
+		{
+		for ( TInt i=iMails.Count()-1; i>=0; i-- )
+			{
+			// Remove items from model if they are not valid anymore
+		    CFSMailMessage* confirmedMsgPtr(0);
+		    // TRAP KErrNotFound leave with ignore cause null pointer is checked after this
+		    TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iMails[i].partData.iMailBoxId, 
+				          iMails[i].partData.iFolderId, iMails[i].partData.iMessageId , EFSMsgDataIdOnly ) ); // Check if id is valid
+			if ( confirmedMsgPtr )
+				{
+				delete confirmedMsgPtr; // delete unnecessary object
+				}		
+			else
+				{
+		        iMails[i].mailAttachments.Close();
+		        delete iMails[i].mailSubject;
+				iMails.Remove(i); // Remove
+				itemWasRemoved = ETrue;
+				}
+			}			
+		}
+	
+	return itemWasRemoved;
+	}
+