emailuis/nmhswidget/src/nmhswidgetemailengine.cpp
changeset 23 2dc6caa42ec3
parent 20 ecc8def7944a
child 30 759dc5235cdb
--- a/emailuis/nmhswidget/src/nmhswidgetemailengine.cpp	Mon May 03 12:23:15 2010 +0300
+++ b/emailuis/nmhswidget/src/nmhswidgetemailengine.cpp	Fri May 14 15:41:10 2010 +0300
@@ -15,11 +15,11 @@
  *
  */
 
+#include <xqservicerequest.h>
 #include <QDebug>
 #include <QTimer>
 #include <QDir>
 #include <qpluginloader.h>
-#include <XQServiceRequest.h>
 #include "email_services_api.h"
 #include "nmcommon.h"
 #include "nmmessageenvelope.h"
@@ -28,135 +28,184 @@
 #include "nmmailbox.h"
 #include "nmfolder.h"
 #include "nmdatapluginfactory.h"
+#include "nmhswidgetconsts.h"
 
 /*!
  Constructor
  */
 NmHsWidgetEmailEngine::NmHsWidgetEmailEngine(const NmId& monitoredMailboxId) :
-    mMailboxId(monitoredMailboxId), mAccountName(0), mUnreadCount(0),
-            mEmailInterface(0), mFactory(0), mAccountEventReceivedWhenSuspended(false),
-            mMessageEventReceivedWhenSuspended(false), mSuspended(false) 
-    {
-    qDebug()<<"NmHsWidgetEmailEngine() -- START";
-    constructNmPlugin();
+    mMailboxId(monitoredMailboxId), 
+    mFolderId(0), 
+    mAccountName(0), 
+    mUnreadCount(-1),
+    mEmailInterface(0), 
+    mFactory(0), 
+    mAccountEventReceivedWhenSuspended(false),
+    mMessageEventReceivedWhenSuspended(false), 
+    mSuspended(false),
+    mUpdateTimer(0)
+{
+    qDebug() << "NmHsWidgetEmailEngine() -- START";
+
+    qDebug() << "NmHsWidgetEmailEngine() -- END";
+}
+
+/*!
+ initilaize - Initializes the engine
+ Works as a second phase constructor. Must be called before any other operations.
+ Client should connect to exceptionOccured signal before calling this method.
+ /return true if initialize succeedes otherwise false. If false the object is unusable.
+ */
+bool NmHsWidgetEmailEngine::initialize()
+{
+    qDebug() << "initialize() -- START";
+        
+    if (!constructNmPlugin()) {
+        //if plugin connection fails, there's no reason to proceed
+        return false;
+    }
     updateData();
     updateAccount();
-    qDebug()<<"NmHsWidgetEmailEngine() -- END";
-    }
-
+    
+    mUpdateTimer = new QTimer(this);
+    mUpdateTimer->setInterval(NmHsWidgetEmailEngineUpdateTimerValue);
+    connect(mUpdateTimer, SIGNAL(timeout()), this, SLOT(handleUpdateTimeout()) );
+    
+    qDebug() << "initialize() -- END";
+    return true;
+}
 
 /*!
  constructNmPlugin
+ /post Constructs a connection to an instance of NmDataPluginInterface
+ /return true if construction succeeded, otherwise false.
  */
-void NmHsWidgetEmailEngine::constructNmPlugin()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::constructNmPlugin() -- START";
-    
-    QObject* pluginInstance(0); 
+bool NmHsWidgetEmailEngine::constructNmPlugin()
+{
+    qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- START";
+
+    QObject* pluginInstance(0);
     //Get data plugin factory instance
     mFactory = NmDataPluginFactory::instance();
+    if (!mFactory) {
+        qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- mFactory FAILED";
+        return false;
+    }
 
-    if(mFactory)        
-        {
-        pluginInstance = mFactory->pluginInstance(mMailboxId);
-        }
+    //Get plugin instance
+    pluginInstance = mFactory->pluginInstance(mMailboxId);
+    if (!pluginInstance) {
+        qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- pluginInstance FAILED";
+        return false;
+    }
+
+    //get interface instance
+    mEmailInterface = mFactory->interfaceInstance(pluginInstance);
 
-    if(pluginInstance)
-        { 
-        mEmailInterface = mFactory->interfaceInstance( pluginInstance );
-        mFolderId = mEmailInterface->getStandardFolderId(mMailboxId, NmFolderInbox);
-        //Subscription is needed - otherwise the signals will not be received
-        mEmailInterface->subscribeMailboxEvents(mMailboxId);
-        
-        //Connect to events
-        connect(pluginInstance,
-                SIGNAL( messageEvent(NmMessageEvent, const NmId&, 
-                        const QList<NmId>&, const NmId&) ),
-                this,
-                SLOT( handleMessageEvent(NmMessageEvent, const NmId&, 
-                        const QList<NmId>&, const NmId&) ));
+    if (!mEmailInterface) {
+        qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- mEmailInterface FAILED";
+        return false;       
+    }
+    //Verify that the mailbox we are interested actually exists.
+    //Otherwise emit account deleted event (instead of just returning)
+    QList<NmId> ids; 
+    mEmailInterface->listMailboxIds(ids);
+    if(!ids.contains(mMailboxId)){
+        qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- !ids.contains(mMailboxId) FAILED";
+        emit exceptionOccured(NmEngineExcAccountDeleted);
+        return false;
+    }
+    
+    //retrieve folderID for this mailbox's inbox
+    //If NmId equals zero, we don't have the Initial sync done for the account
+    //This is valid at least for IMAP accounts. 
+    //Folder ID is then retrieved later when first message event is received
+    mFolderId = mEmailInterface->getStandardFolderId(mMailboxId, NmFolderInbox);
+    qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- mFolderId==" << mFolderId.id();
 
-        connect(pluginInstance,
-                SIGNAL( mailboxEvent(NmMailboxEvent, const QList<NmId>& ) ),
-                this,
-                SLOT( handleMailboxEvent(NmMailboxEvent, const QList<NmId>&) ));
-        
-        qDebug()<<"NmHsWidgetEmailEngine::constructNmPlugin() -- OK";
-        }
-    else
-        {
-        emit errorOccured(NmEngineErrFailure);
-        qDebug()<<"NmHsWidgetEmailEngine::constructNmPlugin() -- FAILED";
-        }
+    //Subscription is needed - otherwise the signals will not be received
+    mEmailInterface->subscribeMailboxEvents(mMailboxId);
 
-    qDebug()<<"NmHsWidgetEmailEngine::constructNmPlugin() -- END";
-    }
+    //Connect to events
+    connect(pluginInstance, SIGNAL( messageEvent(NmMessageEvent, const NmId&,
+            const QList<NmId>&, const NmId&) ), this,
+        SLOT( handleMessageEvent(NmMessageEvent, const NmId&,
+                const QList<NmId>&, const NmId&) ));
+
+    connect(pluginInstance, SIGNAL( mailboxEvent(NmMailboxEvent, const QList<NmId>& ) ), this,
+        SLOT( handleMailboxEvent(NmMailboxEvent, const QList<NmId>&) ));
+
+    qDebug() << "NmHsWidgetEmailEngine::constructNmPlugin() -- OK";
+
+    return true;
+}
 
 /*!
  Reset envelope list
  \post mEnvelopeList.isEmpty() == true && all contained objects are deleted
  */
 void NmHsWidgetEmailEngine::resetEnvelopeList()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::resetEnvelopeList() -- START";
-    
-    while (!mEnvelopeList.isEmpty())
-        {
+{
+    qDebug() << "NmHsWidgetEmailEngine::resetEnvelopeList() -- START";
+
+    while (!mEnvelopeList.isEmpty()) {
         delete mEnvelopeList.takeFirst();
-        }
-    
-    qDebug()<<"NmHsWidgetEmailEngine::resetEnvelopeList() -- END";
     }
 
+    qDebug() << "NmHsWidgetEmailEngine::resetEnvelopeList() -- END";
+}
+
 /*!
  Destructor
  */
 NmHsWidgetEmailEngine::~NmHsWidgetEmailEngine()
-    {
-    qDebug()<<"~NmHsWidgetEmailEngine -- START";
- 
+{
+    qDebug() << "~NmHsWidgetEmailEngine -- START";
+
     resetEnvelopeList();
-    if  ( mFactory )
-        {        
+    if (mFactory) {
         NmDataPluginFactory::releaseInstance(mFactory);
-        }
-    qDebug()<<"~NmHsWidgetEmailEngine -- END";
     }
-
+    
+    if (mUpdateTimer){
+        mUpdateTimer->stop();
+        delete mUpdateTimer;
+    }
+    
+    qDebug() << "~NmHsWidgetEmailEngine -- END";
+}
 
 /*!
  getEnvelopes() provides message envelopes as a list of stack objects
  Amount of message envelopes in the list parameter is the smallest of the following factors:
  'KMaxNumberOfEnvelopesProvided', 'maxEnvelopeAmount', 'amount of available envelopes'. 
-  
+ 
  \param list list to be filled with message envelopes
  \param maxEnvelopeAmount Client side limit for amount of message envelope count. 
  \return count of envelopes added to list
  */
-int NmHsWidgetEmailEngine::getEnvelopes(QList<NmMessageEnvelope> &list,
-        int maxEnvelopeAmount)
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::getEnvelopes()";
+int NmHsWidgetEmailEngine::getEnvelopes(QList<NmMessageEnvelope> &list, int maxEnvelopeAmount)
+{
+    qDebug() << "NmHsWidgetEmailEngine::getEnvelopes()";
     list.clear(); //Reset the parameter list to avoid side effects
     int i = 0;
-    for (; i < mEnvelopeList.count() && i < maxEnvelopeAmount; i++)
-        {
+    for (; i < mEnvelopeList.count() && i < maxEnvelopeAmount; i++) {
         NmMessageEnvelope env(*mEnvelopeList[i]);
         list.append(env);
-        }
+    }
     return i;
-    }
+}
 
 /*!
  UnreadCount
 
- \return count of unread mails
+ \return count of unread mails, or -1 if there are no mails at all in the mailbox.
  */
 int NmHsWidgetEmailEngine::unreadCount()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::unreadCount()";
+{
+    qDebug() << "NmHsWidgetEmailEngine::unreadCount()";
     return mUnreadCount;
-    }
+}
 
 /*!
  accountName
@@ -164,170 +213,221 @@
  \return name of the monitored account
  */
 QString NmHsWidgetEmailEngine::accountName()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::accountName()";
+{
+    qDebug() << "NmHsWidgetEmailEngine::accountName()";
     return mAccountName;
-    }
+}
 
 /*!
  Refresh email data.
  \post mEnvelopeList is refreshed with valid content so that it has
- valid data with maximum of KMaxNumberOfEnvelopesProvided envelopes
+       valid data with maximum of KMaxNumberOfEnvelopesProvided envelopes. 
+       
+ - emits exceptionOccured(NmEngineExcFailure) if fatal error occurs.
+ - emits mailDataChanged() if new mail data is set into mEnvelopeList
+ - emits unreadCountChanged(mUnreadCount), if mUnreadCount is updated
  
+ \return true if everything succeeded, otherwise false
  */
-void NmHsWidgetEmailEngine::updateData()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::updateData() -- START";
-    if(!mEmailInterface)
-        {
-        qDebug()<<"NmHsWidgetEmailEngine::updateData() -- Interface missing";
-        return; //if interface is missing there's nothing to do
-        }
+bool NmHsWidgetEmailEngine::updateData()
+{
+    qDebug() << "NmHsWidgetEmailEngine::updateData() -- START";
+    if (!mEmailInterface) {
+        qDebug() << "NmHsWidgetEmailEngine::updateData() -- Interface missing";
+        emit exceptionOccured(NmEngineExcFailure); //fatal error
+        return false; //if interface is missing there's nothing to do
+    }
+
     //reset envelope list before retrieving new items
-    resetEnvelopeList(); 
+    resetEnvelopeList();
+
     //get messages from inbox
-    mEmailInterface->listMessages(mMailboxId, mFolderId, mEnvelopeList, KMaxNumberOfEnvelopesProvided);
-    Q_ASSERT_X(mEnvelopeList.count() <= KMaxNumberOfEnvelopesProvided, "nmhswidgetemailengine", "list max size exeeded");
+    int msgErr = mEmailInterface->listMessages(mMailboxId, mFolderId, mEnvelopeList,
+        KMaxNumberOfEnvelopesProvided);
+    if (msgErr) {
+        //retrieval of messages failed.  
+        return false;
+    }
     //emit signal about new message data right away
     emit mailDataChanged();
     //retrieve new unread count to mUnreadCount
     NmFolder* folder = NULL;
-    int err = mEmailInterface->getFolderById(mMailboxId, mFolderId, folder);
- 
-    if(folder)
-        {
-        mUnreadCount = folder->unreadMessageCount();
+    int folderErr = mEmailInterface->getFolderById(mMailboxId, mFolderId, folder);
+    if (folderErr) {
+        //retrieval of valid folder failed.
+        return false;
+    }
+    if (folder) {
+        //If messageCount in the folder is zero we must indicate unread count to be -1
+        if (folder->messageCount() == 0) {
+            mUnreadCount = -1;
+        }
+        else {
+            mUnreadCount = folder->unreadMessageCount();
+        }
         delete folder;
         folder = NULL;
         //limit the unread count to KMaxUnreadCount
-        if( mUnreadCount > KMaxUnreadCount)
-            {
+        if (mUnreadCount > KMaxUnreadCount) {
             mUnreadCount = KMaxUnreadCount;
-            }
+        }
         //emit signal about changed unread count
         emit unreadCountChanged(mUnreadCount);
-        }
-
+    }else{
+        return false;
+    }
 
-
-    qDebug()<<"NmHsWidgetEmailEngine::updateData() -- END";
-    }
+    qDebug() << "NmHsWidgetEmailEngine::updateData() -- END";
+    return true;
+}
 
 /*!
  handleMessageEvent slot.
  */
-void NmHsWidgetEmailEngine::handleMessageEvent(NmMessageEvent event,
-        const NmId &folderId, const QList<NmId> &messageIds, const NmId& mailboxId)
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::handleMessageEvent() -- START";
+void NmHsWidgetEmailEngine::handleMessageEvent(
+    NmMessageEvent event,
+    const NmId &folderId,
+    const QList<NmId> &messageIds,
+    const NmId& mailboxId)
+{
+    qDebug() << "NmHsWidgetEmailEngine::handleMessageEvent() -- START";
     Q_UNUSED(event);
     Q_UNUSED(messageIds);
-    if ( (folderId == mFolderId) && (mailboxId == mMailboxId) )
-        {
+    
+    if (!mEmailInterface) {
+        qDebug() << "NmHsWidgetEmailEngine::handleMessageEvent() -- Interface missing";
+        emit exceptionOccured(NmEngineExcFailure); //fatal error
+        return; //if interface is missing there's nothing to do
+    }
+    
+    if (mFolderId == NmId(0)) {
+        // inbox was not created in construction phase, so let's
+        // get id now as received first mail event
+        mFolderId = mEmailInterface->getStandardFolderId(mMailboxId, NmFolderInbox);
+    }
+    if ((folderId == mFolderId) && (mailboxId == mMailboxId)) {
         //Data is updated only if the engine is not suspended
-        if( mSuspended )
-            {
+        if (mSuspended) {
             mMessageEventReceivedWhenSuspended = true;
-            }
-        else
-            {
-            updateData();
-            }   
         }
-    qDebug()<<"NmHsWidgetEmailEngine::handleMessageEvent() -- END";
+        else {
+            //start or restart the timer. Update is started when timer expires
+            mUpdateTimer->start();
+        }
     }
+    qDebug() << "NmHsWidgetEmailEngine::handleMessageEvent() -- END";
+}
 
 /*!
  handleMailboxEvent slot.
  */
-void NmHsWidgetEmailEngine::handleMailboxEvent(NmMailboxEvent event,
-        const QList<NmId> &mailboxIds)
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::handleMailboxEvent() -- START";
-    Q_UNUSED(mailboxIds);
-    //react only to NmMailboxChanged event
-    if (event == NmMailboxChanged)
-        {
-        if ( mSuspended )
-            {
-            mAccountEventReceivedWhenSuspended = true;
+void NmHsWidgetEmailEngine::handleMailboxEvent(NmMailboxEvent event, const QList<NmId> &mailboxIds)
+{
+    qDebug() << "NmHsWidgetEmailEngine::handleMailboxEvent() -- START";
+    if (mailboxIds.contains(mMailboxId)) {
+        switch (event) {
+            case (NmMailboxChanged): {
+                if (mSuspended) {
+                    mAccountEventReceivedWhenSuspended = true;
+                }
+                else {
+                    updateAccount();
+                }
+                break;
+            }
+            case (NmMailboxDeleted): {
+                emit exceptionOccured(NmEngineExcAccountDeleted);
+                break;
             }
-        else
-            {
-            updateAccount();
-            }
+            default:
+                //ignored
+                break;
+        }
+    }
+    qDebug() << "NmHsWidgetEmailEngine::handleMailboxEvent() -- END";
+}
 
-        }
-    qDebug()<<"NmHsWidgetEmailEngine::handleMailboxEvent() -- END";
+/*!
+ * handleUpdateTimeout slot
+ */
+void NmHsWidgetEmailEngine::handleUpdateTimeout()
+{
+    qDebug() << "NmHsWidgetEmailEngine::handleUpdateTimeout() -- START";
+    if (mUpdateTimer){
+        mUpdateTimer->stop();
     }
+    updateData();
+    qDebug() << "NmHsWidgetEmailEngine::updateAccount() -- END";
+}
 
 /*!
  Update Account data
  \post if mEmailInterface exists, the mAccountName is refreshed from adapter 
-       and accountNameChanged signal is emitted.
+ and accountNameChanged signal is emitted.
  */
-void NmHsWidgetEmailEngine::updateAccount()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::updateAccount() -- START";
-    
+bool NmHsWidgetEmailEngine::updateAccount()
+{
+    qDebug() << "NmHsWidgetEmailEngine::updateAccount() -- START";
+
     NmMailbox* box = NULL;
-    if(mEmailInterface)
-        {
-        mEmailInterface->getMailboxById(mMailboxId, box);
+    if (mEmailInterface) {
+        int err = mEmailInterface->getMailboxById(mMailboxId, box);
+        if (err) {
+            //By specification return and wait another event
+            return false;
         }
-    if (box)
-        {
+    }
+    if (box) {
         mAccountName = box->name();
-        emit accountNameChanged(mAccountName);
         delete box;
         box = NULL;
-        }
-    qDebug()<<"NmHsWidgetEmailEngine::updateAccount() -- END";
+        emit accountNameChanged(mAccountName);
     }
+    qDebug() << "NmHsWidgetEmailEngine::updateAccount() -- END";
+    return true;
+}
 
 /*!
-  suspend slot.
-  \post engine will not emit signals or refresh its data during suspension.
+ suspend slot.
+ \post engine will not emit signals or refresh its data during suspension.
  */
 void NmHsWidgetEmailEngine::suspend()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::suspend() -- START";
+{
+    qDebug() << "NmHsWidgetEmailEngine::suspend() -- START";
     mSuspended = true;
-    qDebug()<<"NmHsWidgetEmailEngine::suspend() -- END";
-    }
+    qDebug() << "NmHsWidgetEmailEngine::suspend() -- END";
+}
 
 /*!
-  activate slot.
-  \post Engine will immediately refresh all the data that has been announced to
-  have changed during the suspension. Events are enabled.
+ activate slot.
+ \post Engine will immediately refresh all the data that has been announced to
+ have changed during the suspension. Events are enabled.
  */
 void NmHsWidgetEmailEngine::activate()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::activate() -- START";
-    mSuspended = false; 
-    if ( mAccountEventReceivedWhenSuspended )
-        {
+{
+    qDebug() << "NmHsWidgetEmailEngine::activate() -- START";
+    mSuspended = false;
+    if (mAccountEventReceivedWhenSuspended) {
         mAccountEventReceivedWhenSuspended = false;
         updateAccount();
-        }
-    if (mMessageEventReceivedWhenSuspended)
-        {
+    }
+    if (mMessageEventReceivedWhenSuspended) {
         mMessageEventReceivedWhenSuspended = false;
         updateData();
-        }
-    qDebug()<<"NmHsWidgetEmailEngine::activate() -- END";
     }
+    qDebug() << "NmHsWidgetEmailEngine::activate() -- END";
+}
 
 /*!
-  launchMailAppInboxView slot.
-  \post Mail application is launched to inbox view corresponding widget's mailbox id
+ launchMailAppInboxView slot.
+ \post Mail application is launched to inbox view corresponding widget's mailbox id
  */
 void NmHsWidgetEmailEngine::launchMailAppInboxView()
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::launchMailAppInboxView() -- START";
+{
+    qDebug() << "NmHsWidgetEmailEngine::launchMailAppInboxView() -- START";
 
     XQServiceRequest request(
-        emailInterfaceNameMailbox,
+        emailFullServiceNameMailbox,
         emailOperationViewInbox,
         false);
     
@@ -335,23 +435,22 @@
     list.append(QVariant(mMailboxId.id()));
 
     request.setArguments(list);
-    QVariant returnValue;
-    bool rval = request.send(returnValue);
-    
-    qDebug()<<"NmHsWidgetEmailEngine::launchMailAppInboxView() -- END";
-    }
+    request.send();
+
+    qDebug() << "NmHsWidgetEmailEngine::launchMailAppInboxView() -- END";
+}
 
 /*!
-  launchMailAppMailViewer slot.
-  \param messageId Defines the message opened to viewer
-  \post Mail application is launched and viewing mail specified by
+ launchMailAppMailViewer slot.
+ \param messageId Defines the message opened to viewer
+ \post Mail application is launched and viewing mail specified by
  */
 void NmHsWidgetEmailEngine::launchMailAppMailViewer(const NmId &messageId)
-    {
-    qDebug()<<"NmHsWidgetEmailEngine::launchMailAppMailViewer() -- START";
+{
+    qDebug() << "NmHsWidgetEmailEngine::launchMailAppMailViewer() -- START";
 
     XQServiceRequest request(
-       emailInterfaceNameMessage,
+       emailFullServiceNameMessage,
        emailOperationViewMessage,
        false);
     
@@ -359,10 +458,9 @@
     list.append(QVariant(mMailboxId.id()));
     list.append(QVariant(mFolderId.id()));
     list.append(QVariant(messageId.id()));
-    
+
     request.setArguments(list);
-    QVariant returnValue;
-    bool rval = request.send(returnValue);
-    
-    qDebug()<<"NmHsWidgetEmailEngine::launchMailAppMailViewer() -- END";
-    }
+    request.send();
+
+    qDebug() << "NmHsWidgetEmailEngine::launchMailAppMailViewer() -- END";
+}