ipsservices/nmipssettings/src/nmipssettingsdeletemailboxop.cpp
changeset 76 38bf5461e270
--- /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 <msvapi.h>
+#include <msvids.h>
+
+#include <QTimer>
+#include <QServiceManager>
+#include <QServiceFilter>
+#include <QServiceInterfaceDescriptor>
+
+#include <HbMessageBox>
+#include <HbProgressDialog>
+#include <HbAction>
+
+#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<TMsvId*>(aArg2);
+        if( parent == KMsvRootIndexEntryId )
+            {
+            // find the mailbox we're observing
+            CMsvEntrySelection* selection = static_cast<CMsvEntrySelection*>(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<QtMobility::QServiceInterfaceDescriptor> 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();
+}
+
+