ipsservices/ipssosplugin/src/ipsplgimap4connectop.cpp
author hgs
Fri, 23 Jul 2010 19:09:50 +0300
changeset 56 15bc1d5d6267
parent 47 f83bd4ae1fe3
child 76 38bf5461e270
permissions -rw-r--r--
201029

/*
* 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 connect operation
*
*
*/

#include "emailtrace.h"
#include "ipsplgheaders.h"

// <qmail> removed

// <qmail> KIpsPlgIpsConnPanic removed

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::NewL()
// ----------------------------------------------------------------------------
// <qmail> priority parameter has been removed
// <qmail> MFSMailRequestObserver& changed it to pointer
// <qmail> aSignallingAllowed parameter has been removed
CIpsPlgImap4ConnectOp* CIpsPlgImap4ConnectOp::NewL(
    CMsvSession& aMsvSession,
    TRequestStatus& aObserverRequestStatus,
    TMsvId aService,
    CIpsPlgTimerOperation& aActivityTimer,
    TFSMailMsgId aFSMailBoxId,
    MFSMailRequestObserver* aFSOperationObserver,
    TInt aFSRequestId,
    CIpsPlgEventHandler* aEventHandler,
    TBool aDoPlainConnect )
    {
    FUNC_LOG;
    CIpsPlgImap4ConnectOp* self = new (ELeave) CIpsPlgImap4ConnectOp(
        aMsvSession, 
        aObserverRequestStatus,
        aService, 
        aActivityTimer,
        aFSMailBoxId, 
        aFSOperationObserver,
        aFSRequestId,
        aDoPlainConnect,
        aEventHandler );
        
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::CIpsPlgImap4ConnectOp()
// ----------------------------------------------------------------------------
// <qmail> priority parameter has been removed
// <qmail> MFSMailRequestObserver& changed it to pointer
// <qmail> aSignallingAllowed parameter has been removed
CIpsPlgImap4ConnectOp::CIpsPlgImap4ConnectOp(
    CMsvSession& aMsvSession,
    TRequestStatus& aObserverRequestStatus,
    TMsvId aService,
    CIpsPlgTimerOperation& aActivityTimer,
    TFSMailMsgId aFSMailBoxId,
    MFSMailRequestObserver* aFSOperationObserver,
    TInt aFSRequestId,
    TBool aDoPlainConnect,
    CIpsPlgEventHandler* aEventHandler)
    :
    CIpsPlgOnlineOperation(
	    aMsvSession,
	    aObserverRequestStatus,
	    aActivityTimer,
	    aFSMailBoxId,
	    aFSOperationObserver,
	    aFSRequestId ),
    iState( EStateIdle ),
    iSelection( NULL ),
    iDoPlainConnect( aDoPlainConnect ),
    iEventHandler( aEventHandler ),
    iIsSyncStartedSignaled( EFalse )
    {
    FUNC_LOG;
    iService = aService;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::~CIpsPlgImap4ConnectOp()
// ----------------------------------------------------------------------------
// 
CIpsPlgImap4ConnectOp::~CIpsPlgImap4ConnectOp()
    {
    FUNC_LOG;
    Cancel();
    delete iSelection;
    // <qmail> setting state in destructor makes no sense
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::ConstructL()
// ----------------------------------------------------------------------------
// 
void CIpsPlgImap4ConnectOp::ConstructL()
    {
    FUNC_LOG;
    BaseConstructL( KUidMsgTypeIMAP4 ); 
    iSelection = new(ELeave) CMsvEntrySelection;
    
    TMsvEntry tentry;
    TMsvId service;
    iMsvSession.GetEntry( iService, service, tentry );
    
    if ( tentry.iType.iUid != KUidMsvServiceEntryValue )
        {
        User::Panic( KIpsPlgIpsConnPanic, KErrNotSupported );
        }
    
    // <qmail> moved here from StartL which was removed
    if ( Connected() && iDoPlainConnect )
        {
        // trivial case: connect requested, but already connected
        // (sync is done automatically on background)
        iState = EStateIdle;
        }
    else
        {
        iState = EStateStartConnect;
        }
    iStatus = KRequestPending;    
    // <qmail> SetActive(); moved inside CompleteThis();
    CompleteThis();
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::ProgressL()
// ----------------------------------------------------------------------------
//
const TDesC8& CIpsPlgImap4ConnectOp::ProgressL()
    {
    FUNC_LOG;
    if( iError != KErrNone )
        {
        return GetErrorProgressL( iError );
        }
    else if( iSubOperation )
        {
        return iSubOperation->ProgressL();
        }
        
    TImap4CompoundProgress& prog = iProgressBuf();
    prog.iGenericProgress.iErrorCode = KErrNone;
    return iProgressBuf;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::GetErrorProgressL()
// ----------------------------------------------------------------------------    
//   
const TDesC8& CIpsPlgImap4ConnectOp::GetErrorProgressL(TInt aError)
    {
    FUNC_LOG;
    TImap4CompoundProgress& prog = iProgressBuf();
    prog.iGenericProgress.iErrorCode = aError;      
    return iProgressBuf;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::GetFSProgressL()
// ----------------------------------------------------------------------------
// 
TFSProgress CIpsPlgImap4ConnectOp::GetFSProgressL() const
    {
    FUNC_LOG;
    // might not never called, but gives something reasonable if called
    TFSProgress result = { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone };
    result.iError = KErrNone;
    switch( iState )
        {
        // <qmail> cases EStateQueryingDetails/EStateQueryingDetailsBusy removed
        case EStateStartConnect:
            result.iProgressStatus = TFSProgress::EFSStatus_Started;
            break;
        case EStateConnectAndSync:
            result.iProgressStatus = TFSProgress::EFSStatus_Connecting;
            break;
        case EStateCompleted:
        default:
            result.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
            break;
        }
    if ( iStatus.Int() == KErrCancel )
        {
        result.iProgressStatus = TFSProgress::EFSStatus_RequestCancelled;
        result.iError = KErrCancel;
        }
    return result;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::IpsOpType()
// ----------------------------------------------------------------------------
// <qmail> return type
TIpsOpType CIpsPlgImap4ConnectOp::IpsOpType() const
    {
    FUNC_LOG;
    return EIpsOpTypeImap4SyncOp;
    }

// <qmail> Connected() moved to baseclass
// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::DoCancel()
// ----------------------------------------------------------------------------
// 
void CIpsPlgImap4ConnectOp::DoCancel()
    {
    FUNC_LOG;
    if( iSubOperation )
        {
        iSubOperation->Cancel();
        }
    SignalSyncCompleted( KErrCancel );
    CompleteObserver( KErrCancel );
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::DoRunL()
// ----------------------------------------------------------------------------    
//  
void CIpsPlgImap4ConnectOp::DoRunL()
    {
    FUNC_LOG;
    TInt err( KErrNone );
    __ASSERT_DEBUG( !(iSubOperation && iSubOperation->IsActive()),
        User::Panic( KIpsPlgPanicCategory, KErrGeneral ) );
    if ( iSubOperation )
        {
        err = iSubOperation->iStatus.Int();
        delete iSubOperation;
        iSubOperation = NULL;
        }
    
    switch( iState )
        {
        // <qmail> removing case EStateQueryingDetails
        case EStateStartConnect:
            // <qmail> remove StartL() func and replace it directly with DoConnectOpL
            DoConnectOpL();
            break;
        case EStateConnectAndSync:
            // Connection completed
                
            // <qmail> all errors should fail the op
            if( err )
                {
                iState = EStateIdle;
                // <qmail> SetActive(); moved inside CompleteThis();
                CompleteThis();
                }
            else
                {
                // no errors in connection
                if( !iDoPlainConnect )
                    {
                    DoPopulateAllL();
                    }
                else
                    {
                    // Get on with others using this class for connection only
                    iState = EStateIdle;
                    // <qmail> SetActive(); moved inside CompleteThis();
                    CompleteThis();
                    }
                }
            break;
        case EStatePopulateAllCompleted:
            CIpsPlgSyncStateHandler::SaveSuccessfulSyncTimeL( iMsvSession, iService );
            // break command is intentially left out
        case EStateCompleted:
            if ( err == KErrNone )
                {
                iState = EStateIdle;
                // <qmail> SetActive(); moved inside CompleteThis();
                CompleteThis();
                }
            break;
        case EStateIdle:
        default:
            if ( iSubOperation )
                {
                delete iSubOperation;
                iSubOperation = NULL;
                }
            CompleteObserver();
            break;
        }
   
    // if iError < 0, observer is completed in base class
    iError = err;
    if ( err != KErrNone )
        {
        SignalSyncCompleted( err );
        }
    }

// <qmail> CIpsPlgImap4ConnectOp::HandleImapConnectionEvent() removed

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::RequestResponseL()
// ----------------------------------------------------------------------------    
//   
void CIpsPlgImap4ConnectOp::RequestResponseL( 
    TFSProgress /*aEvent*/, TInt /*aRequestId*/ )
    {
    FUNC_LOG;
    }

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::DoConnectOpL()
// ----------------------------------------------------------------------------    
//   
void CIpsPlgImap4ConnectOp::DoConnectOpL()
	{
    FUNC_LOG;
    iBaseMtm->SwitchCurrentEntryL( iService );

    iSelection->ResizeL(0);
    iSelection->AppendL(iService);
    
    // <qmail>
    iStatus = KRequestPending;
    if ( iDoPlainConnect && !Connected() )
        {
        TBuf8<1> parameter;
        NM_COMMENT("CIpsPlgImap4ConnectOp: do plain connect");
        // connect and synchronise starts background sync or idle
        iSubOperation = iBaseMtm->InvokeAsyncFunctionL(
            KIMAP4MTMConnect, *iSelection, parameter, iStatus);
        }
    else if ( Connected() )
        {
        // in this point cant use "connect and do something" commands,
        // use regular sync, when new mails is populated elsewhere.
        TBuf8<1> parameter;
        NM_COMMENT("CIpsPlgImap4ConnectOp: full sync starting");
        iSubOperation = iBaseMtm->InvokeAsyncFunctionL(
            KIMAP4MTMFullSync, *iSelection, parameter, iStatus);
        }
    else
        {
        // the used command requires an observer to be given even though we're not using it
        NM_COMMENT("CIpsPlgImap4ConnectOp: connect and sync");
        TPckg<MMsvImapConnectionObserver*> parameter( NULL );
        iSubOperation = iBaseMtm->InvokeAsyncFunctionL(
            KIMAP4MTMConnectAndSyncCompleteAfterFullSync, 
            *iSelection, parameter, iStatus );
        }
    SignalSyncStarted();
    iState = EStateConnectAndSync;
    SetActive();
    // </qmail>
	}

// ----------------------------------------------------------------------------
// CIpsPlgImap4ConnectOp::DoPopulateAll()
// ---------------------------------------------------------------------------- 
void CIpsPlgImap4ConnectOp::DoPopulateAllL()
    {
    FUNC_LOG;
    
    NM_COMMENT("CIpsPlgImap4ConnectOp: populate all");
    // construct partial fetch info according to imap settings
    // <qmail> new function to wrap settings loading
    CImImap4Settings* settings = GetImapSettingsLC();
    TImImap4GetPartialMailInfo info;
    ConstructImapPartialFetchInfo( info, *settings );
    TPckgBuf<TImImap4GetPartialMailInfo> package(info);
    CleanupStack::PopAndDestroy( settings );
    settings = NULL;
    
    // do populate operation unless only headers should be fetched
    if ( info.iTotalSizeLimit != KIpsSetDataHeadersOnly )
        {
        // Update iSelection (which will be given to populate op)
        // <qmail> new function to wrap iSelection populating
        CreateInboxMessagesSelectionL();
        
        iStatus = KRequestPending;
        iBaseMtm->SwitchCurrentEntryL( iService );
        // <qmail> priority parameter has been removed
        iSubOperation = CIpsPlgImap4PopulateOp::NewL(
            iMsvSession,
            iStatus,
            iService,
            // <qmail> passing in activity timer; only place where NULL "reference" was used
            // <qmail> -> can get rid of checking existence of a reference memeber...
            *iActivityTimer,
            info,
            *iSelection,
            iFSMailboxId,
            NULL, // no observer for suboperation
            0, // requestId can be 0
            iEventHandler );
        
        SetActive();
        // <qmail> SignalSyncStarted signal moved to happen later in case something goes wrong
        SignalSyncStarted();
        }
    else
        {
        // <qmail> SetActive(); moved inside CompleteThis();
        CompleteThis();
        }
    iState = EStatePopulateAllCompleted;
    }

// <qmail> removed CIpsPlgImap4ConnectOp::StartL()
// <qmail> removed CIpsPlgImap4ConnectOp::QueryUserPwdL()
// <qmail> removed CIpsPlgImap4ConnectOp::GetOperationErrorCodeL()

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------       
void CIpsPlgImap4ConnectOp::SignalSyncStarted()
    {
    FUNC_LOG;
    if ( iEventHandler && !iIsSyncStartedSignaled )
        {
        // mark that sync is signaled to prevent 
        // sending necessary event
        iIsSyncStartedSignaled = ETrue;
        iEventHandler->SetNewPropertyEvent( iService, KIpsSosEmailSyncStarted, KErrNone );
        }
    }

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------       
void CIpsPlgImap4ConnectOp::SignalSyncCompleted( TInt aError )
    {
    FUNC_LOG;
    // <qmail> don't test for aError code; all situations should complete op
    if ( iEventHandler )
        {
        iEventHandler->SetNewPropertyEvent( iService, KIpsSosEmailSyncCompleted, aError );
        iIsSyncStartedSignaled = EFalse;
        }
    }

// <qmail> Removing CIpsPlgImap4ConnectOp::CredientialsSetL 

// <qmail> new functions added
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void CIpsPlgImap4ConnectOp::ConstructImapPartialFetchInfo( 
    TImImap4GetPartialMailInfo& aInfo, 
    const CImImap4Settings& aImap4Settings )
    {
    FUNC_LOG;
    TInt sizeLimit = aImap4Settings.BodyTextSizeLimit();
    
    if ( sizeLimit == KIpsSetDataHeadersOnly )
        {
        aInfo.iTotalSizeLimit = KIpsSetDataHeadersOnly;
        }
    else if ( sizeLimit == KIpsSetDataFullBodyAndAttas )
        {        
        aInfo.iTotalSizeLimit = KMaxTInt;
        aInfo.iAttachmentSizeLimit = KMaxTInt;
        aInfo.iBodyTextSizeLimit = KMaxTInt;
        aInfo.iMaxEmailSize = KMaxTInt;
        aInfo.iPartialMailOptions = ENoSizeLimits;
        aInfo.iGetMailBodyParts = EGetImap4EmailBodyTextAndAttachments;
        }
    else if ( sizeLimit == KIpsSetDataFullBodyOnly )
        {
        aInfo.iTotalSizeLimit = KMaxTInt; 
        aInfo.iAttachmentSizeLimit = 0;
        aInfo.iBodyTextSizeLimit = KMaxTInt;
        aInfo.iMaxEmailSize = KMaxTInt;
        aInfo.iPartialMailOptions = EBodyAlternativeText;
        aInfo.iGetMailBodyParts = EGetImap4EmailBodyAlternativeText;
        }
    else
        {
    //<qmail> include html in body
        aInfo.iTotalSizeLimit = sizeLimit*1024; 
        aInfo.iAttachmentSizeLimit = 0;
        aInfo.iMaxEmailSize = sizeLimit*1024;
        aInfo.iBodyTextSizeLimit = sizeLimit*1024;
        aInfo.iPartialMailOptions = EBodyAlternativeText;
        aInfo.iGetMailBodyParts = EGetImap4EmailBodyAlternativeText;
    // </qmail>    
        }
    }

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
CImImap4Settings* CIpsPlgImap4ConnectOp::GetImapSettingsLC()
    {
    FUNC_LOG;
    CImImap4Settings* settings = new ( ELeave ) CImImap4Settings();
    CleanupStack::PushL( settings );
    CEmailAccounts* accounts = CEmailAccounts::NewLC();
    TImapAccount imapAcc;
    accounts->GetImapAccountL(iService, imapAcc );
    accounts->LoadImapSettingsL( imapAcc, *settings );
    CleanupStack::PopAndDestroy( accounts );
    return settings;
    }

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void CIpsPlgImap4ConnectOp::CreateInboxMessagesSelectionL()
    {
    FUNC_LOG;
    // get children of service entry 
    CMsvEntry* cEntry = iMsvSession.GetEntryL( iService );
    CleanupStack::PushL( cEntry );
    CMsvEntrySelection* childrenSelection = cEntry->ChildrenL();
    CleanupStack::PopAndDestroy( cEntry );
    cEntry = NULL;
    CleanupStack::PushL( childrenSelection );

    if ( childrenSelection->Count() )
        {
        TMsvId id = (*childrenSelection)[0]; // index 0 == inbox
        cEntry = iMsvSession.GetEntryL( id ); // reusing cEntry pointer for Inbox entry
        CleanupStack::PushL( cEntry );
        delete iSelection;
        iSelection = NULL;
        // get message-type children of inbox
        iSelection = cEntry->ChildrenWithTypeL( KUidMsvMessageEntry );
        CleanupStack::PopAndDestroy( cEntry );
        }
    CleanupStack::PopAndDestroy( childrenSelection );
    }

// </qmail>