emailservices/nmailagent/src/nmmailagent.cpp
changeset 18 578830873419
child 20 ecc8def7944a
equal deleted inserted replaced
4:e7aa27f58ae1 18:578830873419
       
     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 
       
    18 #include "nmmailagentheaders.h"
       
    19 #include "nmmailagent.h"
       
    20 
       
    21 // CONSTS
       
    22 const int maxUnreadCount = 1; // 1 is enough
       
    23 
       
    24 
       
    25 /*!
       
    26     \class NmMailAgent
       
    27 
       
    28     \brief Main class for receiving email events and passing them to the HbIndicator
       
    29 */
       
    30 
       
    31 /*!
       
    32     Creates list of folder paths where plug-ins can be loaded from.
       
    33     \return folder path list.
       
    34 */
       
    35 QStringList NmMailAgent::pluginFolders()
       
    36 {
       
    37     const QString nmPluginPath("resource/plugins");
       
    38     QStringList pluginDirectories;
       
    39     QFileInfoList driveList = QDir::drives();
       
    40 
       
    41     foreach(const QFileInfo &driveInfo, driveList) {
       
    42         QString pluginDirectory =
       
    43             driveInfo.absolutePath() + nmPluginPath;
       
    44 
       
    45         if (QFileInfo(pluginDirectory).exists()) {
       
    46             pluginDirectories.append(pluginDirectory);
       
    47         }
       
    48     }
       
    49 
       
    50     return pluginDirectories;
       
    51 }
       
    52 
       
    53 NmMailboxInfo::NmMailboxInfo()
       
    54 {
       
    55     mId = 0;
       
    56     mSyncState = SyncComplete;
       
    57     mConnectState = Disconnected;
       
    58     mUnreadMails = 0;
       
    59     mActive = false;
       
    60 }
       
    61 
       
    62 NmMailAgent::NmMailAgent() :
       
    63  mAdapter(NULL),
       
    64  mActiveIndicators(0)
       
    65 {
       
    66     NMLOG("NmMailAgent::NmMailAgent");
       
    67 }
       
    68 
       
    69 /*!
       
    70     Initialise the agent. \return true if succesfully started.
       
    71 */
       
    72 bool NmMailAgent::init()
       
    73 {
       
    74     if (!loadAdapter()) {
       
    75         // Failed to load NmFrameworkAdapter
       
    76         return false;
       
    77     }
       
    78 
       
    79     // Start listening events
       
    80     connect(mAdapter, SIGNAL(mailboxEvent(NmMailboxEvent, const QList<NmId>&)),
       
    81         this, SLOT(handleMailboxEvent(NmMailboxEvent, const QList<NmId> &)));
       
    82 
       
    83     connect(mAdapter, SIGNAL(messageEvent(
       
    84             NmMessageEvent, const NmId &, const QList<NmId> &, const NmId&)),
       
    85         this, SLOT(handleMessageEvent(
       
    86             NmMessageEvent, const NmId &, const QList<NmId> &, const NmId&)));
       
    87 
       
    88     connect(mAdapter, SIGNAL(syncStateEvent(NmSyncState, const NmId)),
       
    89         this, SLOT(handleSyncStateEvent(NmSyncState, const NmId)));
       
    90 
       
    91     connect(mAdapter, SIGNAL(connectionEvent(NmConnectState, const NmId)),
       
    92         this, SLOT(handleConnectionEvent(NmConnectState, const NmId)));
       
    93 
       
    94     // load all current mailboxes
       
    95     initMailboxStatus();
       
    96 
       
    97     updateStatus();
       
    98     return true;
       
    99 }
       
   100 
       
   101 NmMailAgent::~NmMailAgent()
       
   102 {
       
   103     delete mAdapter;
       
   104     qDeleteAll(mMailboxes);
       
   105 }
       
   106 
       
   107 /*!
       
   108     Initialize the mailbox list with the current state
       
   109 */
       
   110 void NmMailAgent::initMailboxStatus()
       
   111 {
       
   112     NMLOG("NmMailAgent::initMailboxStatus");
       
   113     QList<NmMailbox*> mailboxes;
       
   114     mAdapter->listMailboxes(mailboxes);
       
   115     foreach (const NmMailbox* mailbox, mailboxes) {
       
   116         if (mailbox) {
       
   117             NmMailboxInfo *mailboxInfo = createMailboxInfo(*mailbox);
       
   118             if (mailboxInfo) {
       
   119                 mailboxInfo->mUnreadMails = getUnreadCount(mailbox->id(),maxUnreadCount);
       
   120                 updateMailboxActivity(mailbox->id(), isMailboxActive(*mailboxInfo));
       
   121             }
       
   122         }
       
   123     }
       
   124     qDeleteAll(mailboxes);
       
   125 }
       
   126 
       
   127 /*!
       
   128     Get mailbox unread count in inbox folder
       
   129     \param mailboxId id of the mailbox
       
   130     \param maxCount max number of unread mails that is needed
       
   131     \return number of unread mails in the mailbox
       
   132 */
       
   133 int NmMailAgent::getUnreadCount(const NmId &mailboxId, int maxCount)
       
   134 {
       
   135     NMLOG("NmMailAgent::getUnreadCount");
       
   136     int count(0);
       
   137 
       
   138     // get inbox folder ID
       
   139     NmId inboxId = mAdapter->getStandardFolderId(
       
   140             mailboxId, NmFolderInbox );
       
   141 
       
   142     // get list of messages in inbox
       
   143     QList<NmMessageEnvelope*> messageList;
       
   144     mAdapter->listMessages(mailboxId, inboxId, messageList);
       
   145 
       
   146     foreach (const NmMessageEnvelope* envelope, messageList) {
       
   147         // if the message is not read, it is "unread"
       
   148         if (!envelope->isRead()) {
       
   149             count++;
       
   150 
       
   151             // No more unread mails are needed
       
   152             if (count >= maxCount) {
       
   153                 break;
       
   154             }
       
   155         }
       
   156     }
       
   157 	qDeleteAll(messageList);
       
   158 	NMLOG(QString("NmMailAgent::getUnreadCount count=%1").arg(count));
       
   159 
       
   160     return count;
       
   161 }
       
   162 
       
   163 /*!
       
   164     Load NmFrameworkAdapter from plugins.
       
   165     \return true if adapter is loaded succesfully.
       
   166 */
       
   167 bool NmMailAgent::loadAdapter()
       
   168 {
       
   169     QStringList directories(pluginFolders());
       
   170 
       
   171      foreach (const QString &pluginPath, directories) {
       
   172          QPluginLoader *loader =
       
   173              new QPluginLoader(pluginPath + "/nmframeworkadapter.qtplugin");
       
   174          if (loader) {
       
   175              mAdapter = static_cast<NmFrameworkAdapter *>(loader->instance());
       
   176              if (mAdapter) {
       
   177                  return true;
       
   178              }
       
   179          }
       
   180      }
       
   181      NMLOG("NmMailAgent::loadAdapter failed");
       
   182      return false;
       
   183 }
       
   184 
       
   185 /*!
       
   186     Update the mailbox visibility
       
   187     \param mailboxId id of the mailbox
       
   188     \param active visibility state of the mailbox
       
   189     \return true if the mailbox state was changed
       
   190 */
       
   191 bool NmMailAgent::updateMailboxActivity(const NmId &mailboxId, bool active)
       
   192 {
       
   193     NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId);
       
   194     bool changed = false;
       
   195     if (mailboxInfo->mActive != active) {
       
   196         mailboxInfo->mActive = active;
       
   197         changed = true;
       
   198         if (active) {
       
   199             // Mailbox becomes active again. Move to the bottom of the list.
       
   200             mMailboxes.removeAll(mailboxInfo);
       
   201             mMailboxes.append(mailboxInfo);
       
   202         }
       
   203     }
       
   204     return changed;
       
   205 }
       
   206 
       
   207 /*!
       
   208     Updates status according to current information
       
   209 */
       
   210 void NmMailAgent::updateStatus()
       
   211 {
       
   212     NMLOG("NmMailAgent::updateStatus");
       
   213 
       
   214     int activeIndicators = 0;
       
   215 
       
   216     // Update the indicators
       
   217     foreach (NmMailboxInfo *mailboxInfo, mMailboxes) {
       
   218         // Show only active mailboxes
       
   219         if (mailboxInfo->mActive) {
       
   220             updateIndicator(activeIndicators,true,*mailboxInfo);
       
   221             activeIndicators++;
       
   222         }
       
   223     }
       
   224 
       
   225     // Hide the indicator that are not needed anymore
       
   226     for (int i=activeIndicators;i<mActiveIndicators;i++) {
       
   227         NmMailboxInfo mailboxInfo;
       
   228         updateIndicator(i,false,mailboxInfo);
       
   229     }
       
   230     mActiveIndicators = activeIndicators;
       
   231 }
       
   232 
       
   233 /*!
       
   234     Check if the mailbox indicator should be active, according to current state
       
   235     \param mailboxInfo information of the mailbox
       
   236     \return true if indicator should be now active
       
   237 */
       
   238 bool NmMailAgent::isMailboxActive(const NmMailboxInfo& mailboxInfo)
       
   239 {
       
   240     if (mailboxInfo.mUnreadMails>0) {
       
   241         return true;
       
   242     }
       
   243     return false;
       
   244 }
       
   245 
       
   246 /*!
       
   247     Updates indicator status
       
   248     \param mailboxIndex index of the item shown in indicator menu
       
   249     \param active indicator visibility state
       
   250     \param mailboxInfo information of the mailbox
       
   251     \return true if indicator was updated with no errors
       
   252 */
       
   253 bool NmMailAgent::updateIndicator(int mailboxIndex, bool active,
       
   254     const NmMailboxInfo& mailboxInfo)
       
   255 {
       
   256     NMLOG(QString("NmMailAgent::updateIndicator index=%1 active=%2 unread=%3").
       
   257         arg(mailboxIndex).arg(active).arg(mailboxInfo.mUnreadMails));
       
   258 
       
   259     bool ok = false;
       
   260     QString name = QString("com.nokia.nmail.indicatorplugin_")+mailboxIndex+"/1.0";
       
   261 
       
   262     QList<QVariant> list;
       
   263     list.append(mailboxInfo.mId.id());
       
   264     list.append(mailboxInfo.mName);
       
   265     list.append(mailboxInfo.mUnreadMails);
       
   266     list.append(mailboxInfo.mSyncState);
       
   267     list.append(mailboxInfo.mConnectState);
       
   268 
       
   269     HbIndicator indicator;
       
   270     if (active) {
       
   271         ok = indicator.activate(name,list);
       
   272     }
       
   273     else {
       
   274         ok = indicator.deactivate(name,list);
       
   275     }
       
   276     return ok;
       
   277 }
       
   278 
       
   279 /*!
       
   280     Received from NmFrameworkAdapter mailboxEvent signal
       
   281     \sa NmFrameworkAdapter
       
   282 */
       
   283 void NmMailAgent::handleMailboxEvent(NmMailboxEvent event, const QList<NmId> &mailboxIds)
       
   284 {
       
   285     NMLOG(QString("NmMailAgent::handleMailboxEvent %1").arg(event));
       
   286     bool updateNeeded(false);
       
   287 
       
   288     switch(event) {
       
   289         case NmMailboxCreated:
       
   290             foreach (NmId mailboxId, mailboxIds) {
       
   291                 getMailboxInfo(mailboxId); // create a new mailbox if needed
       
   292                 updateNeeded = true;
       
   293             }
       
   294             break;
       
   295         case NmMailboxChanged:
       
   296             // Mailbox name may have been changed
       
   297             foreach (NmId mailboxId, mailboxIds) {
       
   298                 NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId);
       
   299                 NmMailbox *mailbox(NULL);
       
   300                 mAdapter->getMailboxById(mailboxId,mailbox);
       
   301                 if (mailbox && mailboxInfo) {
       
   302                     if(mailbox->name() != mailboxInfo->mName) {
       
   303                         mailboxInfo->mName = mailbox->name();
       
   304                         updateNeeded = true;
       
   305                     }
       
   306                 }
       
   307                 delete mailbox;
       
   308             }
       
   309             break;
       
   310         case NmMailboxDeleted:
       
   311             foreach (NmId mailboxId, mailboxIds) {
       
   312                 if (removeMailboxInfo(mailboxId)) {
       
   313                     updateNeeded = true;
       
   314                 }
       
   315             }
       
   316             break;
       
   317         default:
       
   318             break;
       
   319     }
       
   320 
       
   321     if (updateNeeded) {
       
   322         updateStatus();
       
   323     }
       
   324 }
       
   325 
       
   326 /*!
       
   327     Received from NmFrameworkAdapter messageEvent signal
       
   328     \sa NmFrameWorkAdapter
       
   329 */
       
   330 void NmMailAgent::handleMessageEvent(
       
   331             NmMessageEvent event,
       
   332             const NmId &folderId,
       
   333             const QList<NmId> &messageIds,
       
   334             const NmId& mailboxId)
       
   335 {
       
   336     NMLOG(QString("NmMailAgent::handleMessageEvent %1 %2").arg(event).arg(mailboxId.id()));
       
   337     Q_UNUSED(folderId);
       
   338     Q_UNUSED(messageIds);
       
   339 
       
   340     switch (event) {
       
   341         case NmMessageChanged: {
       
   342             NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId);
       
   343             // If not currently syncronizing the mailbox, this may mean
       
   344             // that a message was read/unread
       
   345             if (mailboxInfo && mailboxInfo->mSyncState==SyncComplete) {
       
   346                 // check the unread status here again
       
   347                 mailboxInfo->mUnreadMails = getUnreadCount(mailboxId,maxUnreadCount);
       
   348                 if(updateMailboxActivity(mailboxId, isMailboxActive(*mailboxInfo))) {
       
   349                     updateStatus();
       
   350                 }
       
   351             }
       
   352 			break;
       
   353 		}
       
   354         default:
       
   355             break;
       
   356     }
       
   357 
       
   358     // Do not perform an update here, just in handleSyncState
       
   359 }
       
   360 
       
   361 /*!
       
   362     Received from NmFrameworkAdapter syncStateEvent signal
       
   363     \sa NmFrameWorkAdapter
       
   364 */
       
   365 void NmMailAgent::handleSyncStateEvent(
       
   366             NmSyncState state,
       
   367             const NmId mailboxId)
       
   368 {
       
   369     NMLOG(QString("NmMailAgent::handleSyncStateEvent %1 %2").arg(state).arg(mailboxId.id()));
       
   370     NmMailboxInfo *info = getMailboxInfo(mailboxId);
       
   371     if (info) {
       
   372         info->mSyncState = state;
       
   373 
       
   374         if (state==SyncComplete) {
       
   375             // check the unread status here again
       
   376             info->mUnreadMails = getUnreadCount(mailboxId,maxUnreadCount);
       
   377             if(updateMailboxActivity(mailboxId, isMailboxActive(*info))) {
       
   378                 updateStatus();
       
   379             }
       
   380         }
       
   381     }
       
   382 }
       
   383 
       
   384 /*!
       
   385     Received from NmFrameworkAdapter connectionState signal
       
   386     \sa NmFrameWorkAdapter
       
   387 */
       
   388 void NmMailAgent::handleConnectionEvent(NmConnectState state, const NmId mailboxId)
       
   389 {
       
   390     NMLOG(QString("NmMailAgent::handleConnectionEvent %1 %2").arg(state).arg(mailboxId.id()));
       
   391     NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId);
       
   392     if (mailboxInfo) {
       
   393         // Connecting, Connected, Disconnecting, Disconnected
       
   394         mailboxInfo->mConnectState = state;
       
   395     }
       
   396     updateStatus();
       
   397 }
       
   398 
       
   399 /*!
       
   400     Remove a mailbox info entry
       
   401     \return true if mailbox info was found
       
   402 */
       
   403 bool NmMailAgent::removeMailboxInfo(const NmId &id)
       
   404 {
       
   405     bool found = false;
       
   406     foreach (NmMailboxInfo *mailbox, mMailboxes) {
       
   407         if (mailbox->mId == id) {
       
   408             found = true;
       
   409             mMailboxes.removeAll(mailbox);
       
   410         }
       
   411     }
       
   412     return found;
       
   413 }
       
   414 
       
   415 /*!
       
   416     Create a new mailbox info entry
       
   417     \return new mailbox info object
       
   418 */
       
   419 NmMailboxInfo *NmMailAgent::createMailboxInfo(const NmId &id)
       
   420 {
       
   421     // get information of the mailbox
       
   422     NmMailbox *mailbox = NULL;
       
   423     mAdapter->getMailboxById(id, mailbox);
       
   424     if (mailbox) {
       
   425         return createMailboxInfo(*mailbox);
       
   426     }
       
   427     return NULL;
       
   428 }
       
   429 
       
   430 /*!
       
   431     Create a new mailbox info with given parameters
       
   432     \return new mailbox info object
       
   433 */
       
   434 NmMailboxInfo *NmMailAgent::createMailboxInfo(const NmMailbox& mailbox)
       
   435 {
       
   436     NmMailboxInfo *mailboxInfo = new NmMailboxInfo();
       
   437     mailboxInfo->mId = mailbox.id();
       
   438     mailboxInfo->mName = mailbox.name();
       
   439 
       
   440     mMailboxes.append(mailboxInfo);
       
   441 
       
   442     // Subscribe to get all mailbox events
       
   443     mAdapter->subscribeMailboxEvents(mailboxInfo->mId);
       
   444     return mailboxInfo;
       
   445 }
       
   446 
       
   447 /*!
       
   448     Return mailbox info class with mailbox id. If no class is found, create a new instance with given id.
       
   449     \return mailbox info object
       
   450 */
       
   451 NmMailboxInfo *NmMailAgent::getMailboxInfo(const NmId &id)
       
   452 {
       
   453     foreach (NmMailboxInfo *mailbox, mMailboxes) {
       
   454         if (mailbox->mId == id) {
       
   455             return mailbox;
       
   456         }
       
   457     }
       
   458 
       
   459     // Not found. Create a new mailbox info.
       
   460     return createMailboxInfo(id);
       
   461 }
       
   462 
       
   463 // End of file
       
   464