ipsservices/ipssosplugin/src/ipsplgimap4populateop.cpp
changeset 0 8466d47a6819
child 11 0396474f30f5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosplugin/src/ipsplgimap4populateop.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,435 @@
+/*
+* Copyright (c) 2007-2008 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:  IMAP4 fetch message operation
+*
+*/
+
+#include "emailtrace.h"
+#include "ipsplgheaders.h"
+
+// Constants and defines
+const TInt KFetchOpPriority = CActive::EPriorityStandard;
+const TInt KIpsPlgSelectionGra = 16;
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+EXPORT_C CIpsPlgImap4PopulateOp* CIpsPlgImap4PopulateOp::NewL(
+    CMsvSession& aMsvSession,
+    TRequestStatus& aObserverRequestStatus,
+    TInt aPriority,
+    TMsvId aService,
+    CIpsPlgTimerOperation& aActivityTimer,
+    const TImImap4GetPartialMailInfo& aPartialMailInfo,
+    const CMsvEntrySelection& aSel,
+    TFSMailMsgId aFSMailBoxId,
+    MFSMailRequestObserver& aFSOperationObserver,
+    TInt aFSRequestId,
+    CIpsPlgEventHandler* aEventHandler,
+    TBool aDoFilterSelection )
+    {
+    FUNC_LOG;
+    CIpsPlgImap4PopulateOp* op = new (ELeave) CIpsPlgImap4PopulateOp(
+        aMsvSession,
+        aObserverRequestStatus,
+        aPriority,
+        aService,
+        aActivityTimer,
+        aPartialMailInfo,
+        aFSMailBoxId,
+        aFSOperationObserver,
+        aFSRequestId,
+        aEventHandler );
+        
+    CleanupStack::PushL(op);
+    op->ConstructL( aSel, aDoFilterSelection );
+    CleanupStack::Pop( op );
+    return op;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsPlgImap4PopulateOp::CIpsPlgImap4PopulateOp(
+    CMsvSession& aMsvSession,
+    TRequestStatus& aObserverRequestStatus,
+    TInt aPriority,
+    TMsvId aService,
+    CIpsPlgTimerOperation& aActivityTimer,
+    const TImImap4GetPartialMailInfo& aPartialMailInfo,
+    TFSMailMsgId aFSMailBoxId,
+    MFSMailRequestObserver& aFSOperationObserver,
+    TInt aFSRequestId,
+    CIpsPlgEventHandler* aEventHandler )
+    :
+    CIpsPlgOnlineOperation(
+    aMsvSession,
+    aPriority,
+    aObserverRequestStatus,
+    aActivityTimer,
+    aFSMailBoxId,
+    aFSOperationObserver,
+    aFSRequestId),
+    iPartialMailInfo(aPartialMailInfo),
+    iSelection( KIpsPlgSelectionGra ),
+    iEventHandler( aEventHandler )
+    {
+    FUNC_LOG;
+    iService = aService;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsPlgImap4PopulateOp::~CIpsPlgImap4PopulateOp()
+    {
+    FUNC_LOG;
+    iSelection.Close();
+
+    if ( iTempSelection )
+    	{
+    	iTempSelection->Reset();
+   	delete iTempSelection;
+    	}
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::ConstructL( 
+        const CMsvEntrySelection& aSel,
+        TBool aDoFilterSelection )
+    {
+    FUNC_LOG;
+    BaseConstructL( KUidMsgTypeIMAP4 );
+    
+    if ( aDoFilterSelection )
+        {
+        FilterSelectionL( aSel );
+        }
+    else
+        {
+        for ( TInt i = 1; i < aSel.Count(); i++ )
+            {
+            if ( aSel[i] != iService )
+                {
+                iSelection.AppendL( aSel.At(i) );
+                }
+            }
+        }
+    iTempSelection = new ( ELeave ) CMsvEntrySelection();
+    DoConnectL();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsPlgImap4PopulateOp::IpsOpType() const
+    {
+    FUNC_LOG;
+    return EIpsOpTypeImap4PopulateOp;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::DoConnectL()
+    {
+    FUNC_LOG;
+    iState = EStateConnecting;
+    iStatus = KRequestPending;
+
+    CIpsPlgImap4ConnectOp* connOp = CIpsPlgImap4ConnectOp::NewL(
+        iMsvSession,
+        KFetchOpPriority,
+        iStatus, 
+        iService,
+        *iActivityTimer,
+        iFSMailboxId,
+        iFSOperationObserver,
+        iFSRequestId,
+        iEventHandler,
+        ETrue, // Do plain connect
+        EFalse );
+        
+    delete iOperation;
+    iOperation = connOp;
+
+    SetActive();
+    }
+    
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::RunL()
+    {
+    FUNC_LOG;
+    TRAPD(err, DoRunL());
+    if(err != KErrNone )
+        {
+        iSyncProgress().iErrorCode = err;
+        Complete();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::DoRunL()
+    {
+    FUNC_LOG;
+    TInt err = iStatus.Int();
+    delete iOperation;
+    iOperation = NULL;
+    
+    switch( iState )
+        {
+        case EStateConnecting:
+            {
+            TMsvEntry tentry;
+            TMsvId service;
+            iMsvSession.GetEntry(iService, service, tentry );
+            if( !tentry.Connected() )
+                {
+                CompleteObserver( KErrCouldNotConnect );
+                return;
+                }
+            DoPopulateL();
+            break;
+            }
+        case EStateFetching:         
+            {
+            if( err != KErrNone && iOperation )
+                {
+                iFetchErrorProgress = iOperation->ProgressL().AllocL();
+                iState = EStateIdle;
+                Complete();
+                }
+            else
+                {
+                
+                }
+            break;
+            }
+        case EStateInfoEntryChange:
+            {
+            DoPopulateL();
+            break;
+            }
+        case EStateIdle:
+        default:
+            break;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::DoCancel()
+    {
+    FUNC_LOG;
+    if( iOperation )
+        {
+        iOperation->Cancel();
+        }
+    CompleteObserver( KErrCancel );
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+const TDesC8& CIpsPlgImap4PopulateOp::ProgressL()
+    {
+    FUNC_LOG;
+    if(iFetchErrorProgress && (iState == EStateIdle))
+        {
+        // Completed, but with an error during fetch.
+        return *iFetchErrorProgress;
+        }        
+    TImap4SyncProgress progg;
+    progg.iErrorCode = KErrNone;
+    TPckgBuf<TImap4SyncProgress> param(progg);
+    iSyncProgress.Copy(param);
+    return iSyncProgress; 
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+const TDesC8& CIpsPlgImap4PopulateOp::GetErrorProgressL(TInt /*aError*/ )
+    {
+    FUNC_LOG;
+    return *iFetchErrorProgress;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TFSProgress CIpsPlgImap4PopulateOp::GetFSProgressL() const
+    {
+    FUNC_LOG;
+    // might not never called, but gives something reasonable if called
+    TFSProgress result = { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone };
+    switch( iState )
+        {
+        case EStateConnecting:
+            result.iProgressStatus = TFSProgress::EFSStatus_Connecting;
+            break;
+        case EStateFetching:
+            result.iProgressStatus = TFSProgress::EFSStatus_Connected;
+            break;
+        default:
+            result.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+            break;
+        }
+    if ( iStatus.Int() == KErrCancel )
+        {
+        result.iProgressStatus = TFSProgress::EFSStatus_RequestCancelled;
+        result.iError = KErrCancel;
+        }
+    return result;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------    
+TInt CIpsPlgImap4PopulateOp::GetEngineProgress( const TDesC8& aProgress )
+    {
+    FUNC_LOG;
+    if( !aProgress.Length() )
+        {
+        return KErrNone;
+        }
+    else
+        {
+        TPckgBuf<TImap4CompoundProgress> paramPack;
+        paramPack.Copy( aProgress );
+        const TImap4GenericProgress& progress = paramPack().iGenericProgress;
+        return progress.iErrorCode;        
+        }    
+    }    
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::Complete()
+    {
+    FUNC_LOG;
+    TRequestStatus* observer=&iObserverRequestStatus;
+    User::RequestComplete(observer, KErrNone);
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::FilterSelectionL( 
+        const CMsvEntrySelection& aSelection )
+    {
+    FUNC_LOG;
+    iSelection.Reset();
+    TMsvId messageId;
+    // NOTE: this code is taken from symbian os source IMPCMTM.CPP
+    // filter selection is in here because messages are
+    // fetched separately then we dont have to make unneccessery imap 
+    // client mtm calls
+
+    for (TInt i=0; i<aSelection.Count(); i++)
+        {
+        messageId = (aSelection)[i];
+        if ( messageId == iService )
+            {
+            continue;
+            }
+        TMsvEmailEntry entry;
+        TMsvId service = KMsvNullIndexEntryId;          
+        User::LeaveIfError(iMsvSession.GetEntry(messageId, service, entry));
+        
+        TBool isComplete = !(   ( entry.Complete() && entry.PartialDownloaded() ) 
+                             || ( !entry.Complete() && ( !entry.BodyTextComplete() 
+                             || ( iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailBodyTextAndAttachments ) ) 
+                                  && !entry.PartialDownloaded() ) );
+
+        TBool isMsgEntry = entry.iType == KUidMsvMessageEntry;
+        TBool isSizeUnderMax = entry.iSize <= iPartialMailInfo.iMaxEmailSize;
+        TBool isParentComp = entry.Parent() == 
+            iPartialMailInfo.iDestinationFolder && isComplete;
+        
+        if( IsPartialPopulate( )
+              && !isComplete
+              && entry.iType == KUidMsvMessageEntry )
+            {
+            iSelection.AppendL(messageId); 
+            }
+        else if ( isMsgEntry && isSizeUnderMax && !isParentComp )
+            {
+            iSelection.AppendL(messageId);
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TBool CIpsPlgImap4PopulateOp::IsPartialPopulate( )
+    {
+    FUNC_LOG;
+    // NOTE: this code is taken from symbian os source IMPCMTM.CPP
+    // code is modified to this class purpose 
+    
+    TBool isPartialPopulate = EFalse;
+    if(iPartialMailInfo.iPartialMailOptions == ENoSizeLimits &&
+       iPartialMailInfo.iTotalSizeLimit == KMaxTInt &&
+       iPartialMailInfo.iBodyTextSizeLimit == KMaxTInt && 
+       iPartialMailInfo.iAttachmentSizeLimit == KMaxTInt && 
+        (iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailHeaders || 
+         iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailBodyText ||
+         iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailBodyTextAndAttachments ||
+         iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailAttachments ||
+         iPartialMailInfo.iGetMailBodyParts == EGetImap4EmailBodyAlternativeText) )
+        {
+        isPartialPopulate = EFalse;
+        }
+    else
+        {
+        isPartialPopulate = ETrue;
+        }
+
+    return isPartialPopulate;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsPlgImap4PopulateOp::DoPopulateL( )
+    {
+    FUNC_LOG;
+    if ( iSelection.Count() > 0 )
+        {
+        TMsvEmailEntry tEntry;
+        TMsvId dummy;
+        TInt lastIndex = iSelection.Count()-1;
+        User::LeaveIfError( iMsvSession.GetEntry(
+                iSelection[lastIndex], dummy, tEntry ) );
+        
+        iState = EStateFetching;
+
+        iTempSelection->Reset();
+        iTempSelection->AppendL( iService );
+        iTempSelection->AppendL( iSelection[lastIndex] );
+        iSelection.Remove(lastIndex);
+        
+        
+        iStatus = KRequestPending;
+    
+        // Filters are not used when performing 'fetch'
+        // operation, use normal getmail info instead
+        TPckg<TImImap4GetPartialMailInfo> param(iPartialMailInfo);
+        iBaseMtm->SwitchCurrentEntryL( iService );
+        iOperation = iBaseMtm->InvokeAsyncFunctionL(
+                KIMAP4MTMPopulateMailSelectionWhenAlreadyConnected, 
+                *iTempSelection, param, this->iStatus);
+        iState = EStateInfoEntryChange;
+        SetActive();
+        }
+    else
+        {
+        iState = EStateIdle;
+        CompleteObserver();
+        }
+    }
+
+// End of File