diff -r 6c59112cfd31 -r 38bf5461e270 ipsservices/nmipssettings/src/nmipssettingsdeletemailboxop.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ipsservices/nmipssettings/src/nmipssettingsdeletemailboxop.cpp Thu Oct 14 17:33:43 2010 +0300 @@ -0,0 +1,357 @@ +/* +* Copyright (c) 2010 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 +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "nmipssettingsdeletemailboxop.h" +#include "nmipssettingsmanagerbase.h" + +/// CONSTANTS + +/// How many times the delete is attempted before giving up. +const int KDeleteRetryCount = 3; +/// How long will the operation wait (ms) for the disconnect event to arrive before timing out +const int KDisconnectTimeout = 2500; +/// How long will the operation wait (ms) before attempting the delete again if error happened. +const int KRetryDelay = 250; + + +/*! + \class CMailboxDisconnectWait + \brief Symbian helper class for mailbox delete operation. Used for listening disconnect events + from messaging server. + +*/ +class CMailboxDisconnectWait : public CBase, public MMsvSessionObserver +{ +public: + static CMailboxDisconnectWait* NewL( + NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId ); + ~CMailboxDisconnectWait(); + + TBool IsConnected(); + +public: // from MMsvSessionObserver + void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3); + +private: + CMailboxDisconnectWait( NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId ); + +private: // data + /// Own. Messaging server session + CMsvSession* iMsvSession; + /// Mailbox ID that is observed + TMsvId iMailboxId; + /// Delete operation + NmIpsSettingsDeleteMailboxOp& iDeleteOp; +}; + +/*! + Constructor of CMailboxDisconnectWait. +*/ +CMailboxDisconnectWait* CMailboxDisconnectWait::NewL( + NmIpsSettingsDeleteMailboxOp& aDeleteOp, + const TMsvId& aMailboxId ) +{ + CMailboxDisconnectWait* self = new(ELeave) CMailboxDisconnectWait( aDeleteOp, aMailboxId ); + CleanupStack::PushL( self ); + self->iMsvSession = CMsvSession::OpenSyncL( *self ); + CleanupStack::Pop( self ); + return self; +} + +/*! + Constructor of CMailboxDisconnectWait. +*/ +CMailboxDisconnectWait::CMailboxDisconnectWait( + NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId ) : + iMailboxId( aMailboxId ), + iDeleteOp( aDeleteOp ) +{ +} + +/*! + Destructor of CMailboxDisconnectWait. +*/ +CMailboxDisconnectWait::~CMailboxDisconnectWait() +{ + delete iMsvSession; +} + +/*! + Check if observed mailbox is connected or not +*/ +TBool CMailboxDisconnectWait::IsConnected() +{ + TBool connected = EFalse; + TMsvEntry entry; + TMsvId id; + if( iMsvSession->GetEntry( iMailboxId, id, entry ) == KErrNone ) + { + connected = entry.Connected(); + } + return connected; +} + +/*! + Event handler of Messaging server events +*/ +void CMailboxDisconnectWait::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/) +{ + // Entry changed event is received when online/offline state has changed + if( EMsvEntriesChanged == aEvent ) + { + // mailboxes are only on root level, so check the parent + TMsvId parent = *static_cast(aArg2); + if( parent == KMsvRootIndexEntryId ) + { + // find the mailbox we're observing + CMsvEntrySelection* selection = static_cast(aArg1); + TInt count = selection->Count(); + for( TInt i = 0; i < count; ++i ) + { + if( (*selection)[i] == iMailboxId ) + { + // if mailbox is not connected -> report to observer + TMsvEntry entry; + TMsvId id; + TInt err = iMsvSession->GetEntry( iMailboxId, id, entry ); + if( !err && !entry.Connected() ) + { + TInt err; // error code ignored + QT_TRYCATCH_ERROR( err, iDeleteOp.mailboxDisconnected() ); + Q_UNUSED(err); // remove compile warning + } + } + } + } + } +} + + +/*! + \class NmIpsSettingsDeleteMailboxOp + \brief Operation that handles the deletion of mailbox + +*/ + +// ======== MEMBER FUNCTIONS ======== + +/*! + Constructor of NmIpsSettingsDeleteMailboxOp. +*/ +NmIpsSettingsDeleteMailboxOp::NmIpsSettingsDeleteMailboxOp(NmIpsSettingsManagerBase &settingsManager) : + mDisconnectWait(NULL), + mSettingsManager(settingsManager), + mDeleteConfirmationDlg(NULL), + mDeleteProgressDlg(NULL), + mRetryCount(KDeleteRetryCount), + mError(0) +{ + connect( this, SIGNAL(stateChanged()), this, SLOT(processState()), Qt::QueuedConnection ); +} + +/*! + Destructor of NmIpsSettingsDeleteMailboxOp. +*/ +NmIpsSettingsDeleteMailboxOp::~NmIpsSettingsDeleteMailboxOp() +{ + delete mDeleteConfirmationDlg; + delete mDeleteProgressDlg; + delete mDisconnectWait; +} + +/*! + Starts the operation +*/ +void NmIpsSettingsDeleteMailboxOp::startOperation() +{ + // reset state + mRetryCount = KDeleteRetryCount; + mResult = DeleteMbResultSuccess; + mError = 0; + + delete mDisconnectWait; + mDisconnectWait = NULL; + TRAPD( err, mDisconnectWait = CMailboxDisconnectWait::NewL( + *this, mSettingsManager.mailboxId().id32() ) ); + + if(!err) { + changeState(StateConfirmation); + } else { + // failed + complete(DeleteMbResultFailure, err); + } +} + +/*! + Observer method to get notifications when the handled mailbox has disconnected +*/ +void NmIpsSettingsDeleteMailboxOp::mailboxDisconnected() +{ + if( mState == StateDisconnect ) + { + changeState(StateDelete); + } +} + +/*! + Notification method that is called when user has responded to confirmation query +*/ +void NmIpsSettingsDeleteMailboxOp::handleConfimationDlg(HbAction *action) +{ + if (action == mDeleteConfirmationDlg->actions().at(0)) { + changeState(StateDisconnect); + } else { + complete(DeleteMbResultCanceled, 0); + } +} + +/*! + Notification method that is called when timeout has occured while waiting for disconnect event +*/ +void NmIpsSettingsDeleteMailboxOp::handleDisconnectTimeout() +{ + if( mState == StateDisconnect ) + { + changeState(StateDelete); + } +} + +/*! + Operation's state machine. Handles states. +*/ +void NmIpsSettingsDeleteMailboxOp::processState() +{ + switch( mState ) { + case StateConfirmation: { + // Ask user whether to delete or not + if(!mDeleteConfirmationDlg) { + mDeleteConfirmationDlg = + new HbMessageBox(HbMessageBox::MessageTypeQuestion); + mDeleteConfirmationDlg->setText( + hbTrId("txt_mail_dialog_do_you_want_to_delete_the_mailbox")); + mDeleteConfirmationDlg->setTimeout(HbMessageBox::NoTimeout); + mDeleteConfirmationDlg->setStandardButtons(HbMessageBox::Yes | HbMessageBox::No); + } + mDeleteConfirmationDlg->open(this, SLOT(handleConfimationDlg(HbAction *))); + break; + } + + case StateDisconnect: { + // Disconnect mailbox + emit goOffline(mSettingsManager.mailboxId()); + + // Display the progress note during rest of the operation + if( !mDeleteProgressDlg ) { + mDeleteProgressDlg = new HbProgressDialog(HbProgressDialog::WaitDialog); + mDeleteProgressDlg->removeAction( mDeleteProgressDlg->actions().at(0)); + mDeleteProgressDlg->setText(hbTrId("txt_common_info_deleting")); + } + mDeleteProgressDlg->delayedShow(); + + if( mDisconnectWait->IsConnected() ) { + // connected -> wait for disconnect or timeout + QTimer::singleShot(KDisconnectTimeout, this, SLOT(handleDisconnectTimeout())); + } else { + // not connected -> delete mailbox immediately + changeState( StateDelete ); + } + break; + } + + case StateDelete: { + // delete mailbox + int error = mSettingsManager.deleteMailbox(); + if( !error ) { + changeState(StateUnregisterMailbox); + + } else if( mRetryCount-- ) { + // attempt again after small delay + QTimer::singleShot(KRetryDelay, this, SLOT(processState())); + + } else { + // enough failures. give up + complete(DeleteMbResultFailure, error); + } + break; + } + + case StateUnregisterMailbox: { + // Unregister mailbox from application library + QtMobility::QServiceManager manager; + QtMobility::QServiceFilter filter("com.nokia.symbian.IEmailRegisterAccount"); + QList interfaces = manager.findInterfaces(filter); + QObject *registerInterface = NULL; + if (!interfaces.isEmpty()) { + registerInterface = manager.loadInterface(interfaces.first()); + } + + if (registerInterface) { + quint64 mailboxId(mSettingsManager.mailboxId().id()); + // Try to remove the mailbox from the App Library. + (void)QMetaObject::invokeMethod(registerInterface, + "unregisterMailbox", Q_ARG(quint64, mailboxId)); + } + + // All done -> complete + complete(DeleteMbResultSuccess, 0); + break; + } + + case StateDone: // fall through + default: { + // Hide the progress note + if( mDeleteProgressDlg ) { + mDeleteProgressDlg->close(); + } + emit operationComplete(mResult, mError); + break; + } + } +} + +/*! + Changes the operation state +*/ +void NmIpsSettingsDeleteMailboxOp::changeState(DeleteOpStates nextState) +{ + mState = nextState; + emit stateChanged(); +} + +/*! + Completes the operation by setting the result values and changing the state to [done] +*/ +void NmIpsSettingsDeleteMailboxOp::complete(int result, int error) +{ + mError = error; + mResult = result; + mState = StateDone; + emit stateChanged(); +} + +