ipsservices/nmipssettings/src/nmipssettingsdeletemailboxop.cpp
changeset 76 38bf5461e270
equal deleted inserted replaced
74:6c59112cfd31 76:38bf5461e270
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 #include <msvapi.h>
       
    18 #include <msvids.h>
       
    19 
       
    20 #include <QTimer>
       
    21 #include <QServiceManager>
       
    22 #include <QServiceFilter>
       
    23 #include <QServiceInterfaceDescriptor>
       
    24 
       
    25 #include <HbMessageBox>
       
    26 #include <HbProgressDialog>
       
    27 #include <HbAction>
       
    28 
       
    29 #include "nmipssettingsdeletemailboxop.h"
       
    30 #include "nmipssettingsmanagerbase.h"
       
    31 
       
    32 /// CONSTANTS
       
    33 
       
    34 /// How many times the delete is attempted before giving up.
       
    35 const int KDeleteRetryCount = 3;
       
    36 /// How long will the operation wait (ms) for the disconnect event to arrive before timing out
       
    37 const int KDisconnectTimeout = 2500;
       
    38 /// How long will the operation wait (ms) before attempting the delete again if error happened.
       
    39 const int KRetryDelay = 250;
       
    40 
       
    41 
       
    42 /*!
       
    43     \class CMailboxDisconnectWait
       
    44     \brief Symbian helper class for mailbox delete operation. Used for listening disconnect events
       
    45            from messaging server.
       
    46 
       
    47 */
       
    48 class CMailboxDisconnectWait : public CBase, public MMsvSessionObserver
       
    49 {
       
    50 public:
       
    51     static CMailboxDisconnectWait* NewL(
       
    52         NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId );
       
    53     ~CMailboxDisconnectWait();
       
    54 
       
    55     TBool IsConnected();
       
    56     
       
    57 public: // from MMsvSessionObserver
       
    58     void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
       
    59 
       
    60 private:
       
    61     CMailboxDisconnectWait( NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId );
       
    62 
       
    63 private: // data
       
    64     /// Own. Messaging server session
       
    65     CMsvSession* iMsvSession;
       
    66     /// Mailbox ID that is observed
       
    67     TMsvId iMailboxId;
       
    68     /// Delete operation
       
    69     NmIpsSettingsDeleteMailboxOp& iDeleteOp;
       
    70 };
       
    71 
       
    72 /*!
       
    73     Constructor of CMailboxDisconnectWait.
       
    74 */
       
    75 CMailboxDisconnectWait* CMailboxDisconnectWait::NewL( 
       
    76     NmIpsSettingsDeleteMailboxOp& aDeleteOp,
       
    77     const TMsvId& aMailboxId )
       
    78 {
       
    79     CMailboxDisconnectWait* self = new(ELeave) CMailboxDisconnectWait( aDeleteOp, aMailboxId );
       
    80     CleanupStack::PushL( self );
       
    81     self->iMsvSession = CMsvSession::OpenSyncL( *self );
       
    82     CleanupStack::Pop( self );
       
    83     return self;
       
    84 }
       
    85 
       
    86 /*!
       
    87     Constructor of CMailboxDisconnectWait.
       
    88 */
       
    89 CMailboxDisconnectWait::CMailboxDisconnectWait( 
       
    90     NmIpsSettingsDeleteMailboxOp& aDeleteOp, const TMsvId& aMailboxId ) : 
       
    91     iMailboxId( aMailboxId ),
       
    92     iDeleteOp( aDeleteOp )
       
    93 {
       
    94 }
       
    95 
       
    96 /*!
       
    97     Destructor of CMailboxDisconnectWait.
       
    98 */
       
    99 CMailboxDisconnectWait::~CMailboxDisconnectWait()
       
   100 {
       
   101     delete iMsvSession;
       
   102 }
       
   103 
       
   104 /*!
       
   105     Check if observed mailbox is connected or not
       
   106 */
       
   107 TBool CMailboxDisconnectWait::IsConnected()
       
   108 {
       
   109     TBool connected = EFalse;
       
   110     TMsvEntry entry;
       
   111     TMsvId id;
       
   112     if( iMsvSession->GetEntry( iMailboxId, id, entry ) == KErrNone )
       
   113         {
       
   114         connected = entry.Connected();
       
   115         }
       
   116     return connected;
       
   117 }
       
   118 
       
   119 /*!
       
   120     Event handler of Messaging server events
       
   121 */
       
   122 void CMailboxDisconnectWait::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
       
   123 {
       
   124     // Entry changed event is received when online/offline state has changed
       
   125     if( EMsvEntriesChanged == aEvent )
       
   126         {
       
   127         // mailboxes are only on root level, so check the parent
       
   128         TMsvId parent = *static_cast<TMsvId*>(aArg2);
       
   129         if( parent == KMsvRootIndexEntryId )
       
   130             {
       
   131             // find the mailbox we're observing
       
   132             CMsvEntrySelection* selection = static_cast<CMsvEntrySelection*>(aArg1);
       
   133             TInt count = selection->Count();
       
   134             for( TInt i = 0; i < count; ++i )
       
   135                 {
       
   136                 if( (*selection)[i] == iMailboxId )
       
   137                     {
       
   138                     // if mailbox is not connected -> report to observer
       
   139                     TMsvEntry entry;
       
   140                     TMsvId id;
       
   141                     TInt err = iMsvSession->GetEntry( iMailboxId, id, entry );
       
   142                     if( !err && !entry.Connected() )
       
   143                         {
       
   144                         TInt err; // error code ignored
       
   145                         QT_TRYCATCH_ERROR( err, iDeleteOp.mailboxDisconnected() );
       
   146                         Q_UNUSED(err); // remove compile warning
       
   147                         }
       
   148                     }
       
   149                 }
       
   150             }
       
   151         }
       
   152 }
       
   153 
       
   154 
       
   155 /*!
       
   156     \class NmIpsSettingsDeleteMailboxOp
       
   157     \brief Operation that handles the deletion of mailbox
       
   158 
       
   159 */
       
   160 
       
   161 // ======== MEMBER FUNCTIONS ========
       
   162 
       
   163 /*!
       
   164     Constructor of NmIpsSettingsDeleteMailboxOp.
       
   165 */
       
   166 NmIpsSettingsDeleteMailboxOp::NmIpsSettingsDeleteMailboxOp(NmIpsSettingsManagerBase &settingsManager) :
       
   167     mDisconnectWait(NULL),
       
   168     mSettingsManager(settingsManager),
       
   169     mDeleteConfirmationDlg(NULL),
       
   170     mDeleteProgressDlg(NULL),
       
   171     mRetryCount(KDeleteRetryCount),
       
   172     mError(0)
       
   173 {
       
   174     connect( this, SIGNAL(stateChanged()), this, SLOT(processState()), Qt::QueuedConnection );
       
   175 }
       
   176 
       
   177 /*!
       
   178     Destructor of NmIpsSettingsDeleteMailboxOp.
       
   179 */
       
   180 NmIpsSettingsDeleteMailboxOp::~NmIpsSettingsDeleteMailboxOp()
       
   181 {
       
   182     delete mDeleteConfirmationDlg;
       
   183     delete mDeleteProgressDlg;
       
   184     delete mDisconnectWait;
       
   185 }
       
   186 
       
   187 /*!
       
   188     Starts the operation
       
   189 */
       
   190 void NmIpsSettingsDeleteMailboxOp::startOperation()
       
   191 {
       
   192     // reset state
       
   193     mRetryCount = KDeleteRetryCount;
       
   194     mResult = DeleteMbResultSuccess;
       
   195     mError = 0;
       
   196     
       
   197     delete mDisconnectWait;
       
   198     mDisconnectWait = NULL;
       
   199     TRAPD( err, mDisconnectWait = CMailboxDisconnectWait::NewL( 
       
   200         *this, mSettingsManager.mailboxId().id32() ) );
       
   201 
       
   202     if(!err) {
       
   203         changeState(StateConfirmation);
       
   204     } else {
       
   205         // failed
       
   206         complete(DeleteMbResultFailure, err);
       
   207     }
       
   208 }
       
   209 
       
   210 /*!
       
   211     Observer method to get notifications when the handled mailbox has disconnected
       
   212 */
       
   213 void NmIpsSettingsDeleteMailboxOp::mailboxDisconnected()
       
   214 {
       
   215     if( mState == StateDisconnect )
       
   216         {
       
   217         changeState(StateDelete);
       
   218         }
       
   219 }
       
   220 
       
   221 /*!
       
   222     Notification method that is called when user has responded to confirmation query
       
   223 */
       
   224 void NmIpsSettingsDeleteMailboxOp::handleConfimationDlg(HbAction *action)
       
   225 {
       
   226     if (action == mDeleteConfirmationDlg->actions().at(0)) {
       
   227         changeState(StateDisconnect);
       
   228     } else {
       
   229         complete(DeleteMbResultCanceled, 0);
       
   230     }
       
   231 }
       
   232 
       
   233 /*!
       
   234     Notification method that is called when timeout has occured while waiting for disconnect event
       
   235 */
       
   236 void NmIpsSettingsDeleteMailboxOp::handleDisconnectTimeout()
       
   237 {
       
   238     if( mState == StateDisconnect )
       
   239         {
       
   240         changeState(StateDelete);
       
   241         }
       
   242 }
       
   243 
       
   244 /*!
       
   245     Operation's state machine. Handles states.
       
   246 */
       
   247 void NmIpsSettingsDeleteMailboxOp::processState()
       
   248 {
       
   249     switch( mState ) {
       
   250     case StateConfirmation: {
       
   251         // Ask user whether to delete or not
       
   252         if(!mDeleteConfirmationDlg) {
       
   253             mDeleteConfirmationDlg =
       
   254                 new HbMessageBox(HbMessageBox::MessageTypeQuestion);
       
   255             mDeleteConfirmationDlg->setText(
       
   256                 hbTrId("txt_mail_dialog_do_you_want_to_delete_the_mailbox"));
       
   257             mDeleteConfirmationDlg->setTimeout(HbMessageBox::NoTimeout);
       
   258             mDeleteConfirmationDlg->setStandardButtons(HbMessageBox::Yes | HbMessageBox::No);
       
   259         }
       
   260         mDeleteConfirmationDlg->open(this, SLOT(handleConfimationDlg(HbAction *)));
       
   261         break;
       
   262     }
       
   263     
       
   264     case StateDisconnect: {
       
   265         // Disconnect mailbox
       
   266         emit goOffline(mSettingsManager.mailboxId());
       
   267 
       
   268         // Display the progress note during rest of the operation
       
   269         if( !mDeleteProgressDlg ) {
       
   270             mDeleteProgressDlg = new HbProgressDialog(HbProgressDialog::WaitDialog);
       
   271             mDeleteProgressDlg->removeAction( mDeleteProgressDlg->actions().at(0));
       
   272             mDeleteProgressDlg->setText(hbTrId("txt_common_info_deleting"));
       
   273         }
       
   274         mDeleteProgressDlg->delayedShow();
       
   275 
       
   276         if( mDisconnectWait->IsConnected() ) {
       
   277             // connected -> wait for disconnect or timeout
       
   278             QTimer::singleShot(KDisconnectTimeout, this, SLOT(handleDisconnectTimeout()));
       
   279         } else {
       
   280             // not connected -> delete mailbox immediately
       
   281             changeState( StateDelete );
       
   282         }
       
   283         break;
       
   284     }
       
   285     
       
   286     case StateDelete: {
       
   287         // delete mailbox
       
   288         int error = mSettingsManager.deleteMailbox();
       
   289         if( !error ) {
       
   290             changeState(StateUnregisterMailbox);
       
   291 
       
   292         } else if( mRetryCount-- ) {
       
   293             // attempt again after small delay
       
   294             QTimer::singleShot(KRetryDelay, this, SLOT(processState()));
       
   295         
       
   296         } else {
       
   297             // enough failures. give up
       
   298             complete(DeleteMbResultFailure, error);
       
   299         }
       
   300         break;
       
   301     }
       
   302     
       
   303     case StateUnregisterMailbox: {
       
   304         // Unregister mailbox from application library
       
   305         QtMobility::QServiceManager manager;
       
   306         QtMobility::QServiceFilter filter("com.nokia.symbian.IEmailRegisterAccount");
       
   307         QList<QtMobility::QServiceInterfaceDescriptor> interfaces = manager.findInterfaces(filter);
       
   308         QObject *registerInterface = NULL;
       
   309         if (!interfaces.isEmpty()) {
       
   310             registerInterface = manager.loadInterface(interfaces.first());
       
   311         }
       
   312 
       
   313         if (registerInterface) {
       
   314             quint64 mailboxId(mSettingsManager.mailboxId().id());
       
   315             // Try to remove the mailbox from the App Library.
       
   316             (void)QMetaObject::invokeMethod(registerInterface,
       
   317                 "unregisterMailbox", Q_ARG(quint64, mailboxId));
       
   318             }
       
   319         
       
   320         // All done -> complete
       
   321         complete(DeleteMbResultSuccess, 0);
       
   322         break;
       
   323     }
       
   324     
       
   325     case StateDone: // fall through
       
   326     default: {
       
   327         // Hide the progress note
       
   328         if( mDeleteProgressDlg ) {
       
   329             mDeleteProgressDlg->close();
       
   330         }
       
   331         emit operationComplete(mResult, mError);
       
   332         break;
       
   333     }
       
   334     }
       
   335 }
       
   336 
       
   337 /*!
       
   338     Changes the operation state
       
   339 */
       
   340 void NmIpsSettingsDeleteMailboxOp::changeState(DeleteOpStates nextState)
       
   341 {
       
   342     mState = nextState;
       
   343     emit stateChanged();
       
   344 }
       
   345 
       
   346 /*!
       
   347     Completes the operation by setting the result values and changing the state to [done]
       
   348 */
       
   349 void NmIpsSettingsDeleteMailboxOp::complete(int result, int error)
       
   350 {
       
   351     mError = error;
       
   352     mResult = result;
       
   353     mState = StateDone;
       
   354     emit stateChanged();
       
   355 }
       
   356 
       
   357