diff -r 16ed8d08d0b1 -r 478bc57ad291 emailservices/nmailagent/src/nmmailagent.cpp --- a/emailservices/nmailagent/src/nmmailagent.cpp Wed Aug 18 09:37:47 2010 +0300 +++ b/emailservices/nmailagent/src/nmmailagent.cpp Thu Sep 02 20:15:00 2010 +0300 @@ -58,8 +58,6 @@ (settingKey.key() == cenrepSettingKey.key())); } - - /*! \class NmMailboxInfo @@ -76,30 +74,32 @@ mInboxChangedMessages(0), mInboxDeletedMessages(0), mOutboxMails(0), - mActive(false), - mInboxActive(false) + mActive(false) { NM_FUNCTION; } + /*! \class NmMailAgent - \brief Main class for receiving email events. Activates and deactivates indicator. - */ -NmMailAgent::NmMailAgent() : - mIndicator(NULL), - mSystemTone(NULL), - mPluginFactory(NULL), - mVibra(NULL), - mAlertToneAllowed(true), - mLastOutboxCount(0), - mUnreadIndicatorActive(false), - mSettingManager(NULL), - mSilenceMode(NmSilenceModeOn) // by default silent mode is on - { - NM_FUNCTION; - } + \brief Main class for receiving email events. Activates and deactivates + the indicator. +*/ +NmMailAgent::NmMailAgent() +: mIndicator(NULL), + mPluginFactory(NULL), + mVibra(NULL), + mSettingManager(NULL), + mUiEventsNotifier(NULL), + mAlertToneAllowed(true), + mLastOutboxCount(0), + mUnreadIndicatorActive(false), + mSilenceMode(NmSilenceModeOn) // by default silent mode is on +{ + NM_FUNCTION; +} + /*! Delayed start. @@ -118,7 +118,7 @@ Initialise the agent. \return true if succesfully started. - */ +*/ bool NmMailAgent::init() { NM_FUNCTION; @@ -151,10 +151,6 @@ mSilenceMode = NmSilenceModeOn; } - delete mSystemTone; - mSystemTone = NULL; - mSystemTone = new XQSystemToneService(); - delete mIndicator; mIndicator = NULL; mIndicator = new HbIndicator(); @@ -191,6 +187,18 @@ mVibra = NULL; TRAP_IGNORE(mVibra = CHWRMVibra::NewL()); + // Start monitoring the UI events. + delete mUiEventsNotifier; + mUiEventsNotifier = NULL; + mUiEventsNotifier = new NmUiEventsNotifier(this); + + connect(mUiEventsNotifier, + SIGNAL(viewStateChanged(NmUiEventsNotifier::NmUiEventType, + NmUiViewId, NmId)), + this, + SLOT(handleViewStateChangedEvent(const NmUiEventsNotifier::NmUiEventType, + const NmUiViewId, const NmId))); + // load all current mailboxes initMailboxStatus(); @@ -199,20 +207,24 @@ /*! Destructor of NmMailAgent. - */ +*/ NmMailAgent::~NmMailAgent() { NM_FUNCTION; delete mIndicator; delete mVibra; - delete mSystemTone; + if (mSettingManager) { mSettingManager->stopMonitoring(NmSilenceModeKey); delete mSettingManager; } + qDeleteAll(mMailboxes); + delete mUiEventsNotifier; + mUiEventsNotifier = NULL; + NmDataPluginFactory::releaseInstance(mPluginFactory); } @@ -244,16 +256,16 @@ NmMailboxInfo *mailboxInfo = createMailboxInfo(*mailbox, plugin); if (mailboxInfo) { bool activate = updateUnreadCount(mailbox->id(), *mailboxInfo); + NM_COMMENT(QString("Mailbox %1 initial state: newUnread=%2 total=%3"). + arg(mailboxInfo->mName). + arg(mailboxInfo->mNewUnreadMailIdList.count()). + arg(mailboxInfo->mMailIdList.count())); + bool wasActive = isMailboxActive(mailbox->id()); - if (activate) { - if (!wasActive) { - // do not activate the mailbox if it was left as hidden last time - activate = false; - } - else { - // otherwise, activate the mailbox and show inbox state - mailboxInfo->mInboxActive = true; - } + if (!wasActive) { + // do not activate the mailbox if it was left as hidden last time + activate = false; + mailboxInfo->mNewUnreadMailIdList.clear(); } mailboxInfo->mOutboxMails = getOutboxCount(mailbox->id(), @@ -300,33 +312,50 @@ QList messageList; plugin->listMessages(mailboxId, inboxId, messageList); - QList newUnreadMessageIdList; + QList newMessageIdList; + + int unreadCount(0); foreach (const NmMessageEnvelope* envelope, messageList) { // if the message is not read, it is "unread" - if (!envelope->isRead()) { - quint64 messageId = envelope->messageId().id(); - newUnreadMessageIdList.append(envelope->messageId()); + quint64 messageId = envelope->messageId().id(); + newMessageIdList.append(envelope->messageId()); + bool read = envelope->isRead(); + + // This is a new unread mail + if (!read) { + unreadCount++; + + // Iterate through all known ids. If the id can't be found the mail is new. bool found(false); - // Iterate through all known ids. If the id can't be found the mail is new. - foreach (const NmId id, mailboxInfo.mUnreadMailIdList) { + foreach (const NmId id, mailboxInfo.mMailIdList) { if (id.id() == messageId) { found = true; break; } } + // it was new unread message if (!found) { - newUnreadMessages++; + if (mailboxInfo.mNewUnreadMailIdList.indexOf(messageId)<0) { + mailboxInfo.mNewUnreadMailIdList.append(messageId); + newUnreadMessages++; + } } } + else { + // message is now 'read' - make sure it is no longer in list new unread mails + mailboxInfo.mNewUnreadMailIdList.removeAll(messageId); + } } qDeleteAll(messageList); // Save updated list of unread message IDs - mailboxInfo.mUnreadMailIdList = newUnreadMessageIdList; + mailboxInfo.mMailIdList = newMessageIdList; + + NM_COMMENT(QString("NmMailAgent::getUnreadCount(): totalCount=%1, newUnread=%2"). + arg(mailboxInfo.mMailIdList.count()). + arg(newUnreadMessages)); } - NM_COMMENT(QString("NmMailAgent::getUnreadCount(): count=%1, new=%2"). - arg(mailboxInfo.mUnreadMailIdList.count()).arg(newUnreadMessages)); return (newUnreadMessages > 0); } @@ -358,7 +387,7 @@ } /*! - Get list of unread counts in active mailboxes. + Get list of unread counts in all active mailboxes. \returns total number of unread mails */ @@ -368,8 +397,8 @@ int unreads = 0; foreach (const NmMailboxInfo *mailbox, mMailboxes) { - if (mailbox->mActive && mailbox->mInboxActive) { - unreads += mailbox->mUnreadMailIdList.count(); + if (mailbox->mActive) { + unreads += mailbox->mNewUnreadMailIdList.count(); } } return unreads; @@ -389,6 +418,24 @@ } /*! + Update mailbox visibility according to current status +*/ +bool NmMailAgent::updateMailboxState(const NmId &mailboxId) +{ + NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId); + bool shown = false; + + if( mailboxInfo->mActive && + (mailboxInfo->mNewUnreadMailIdList.count() > 0 || + mailboxInfo->mOutboxMails>0)) { + shown = true; + } + + return updateMailboxState(mailboxId,shown,false); +} + + +/*! Update the mailbox visibility and status. \param mailboxId id of the mailbox @@ -452,7 +499,7 @@ QList list; list.append(mailboxInfo.mId.id()); list.append(mailboxInfo.mName); - list.append(mailboxInfo.mUnreadMailIdList.count()); + list.append(mailboxInfo.mNewUnreadMailIdList.count()); list.append(mailboxInfo.mSyncState); list.append(mailboxInfo.mConnectState); list.append(mailboxInfo.mOutboxMails); @@ -482,14 +529,17 @@ NM_FUNCTION; bool activated = false; - if (active != mUnreadIndicatorActive) { - if (active) { - mIndicator->activate(NmUnreadIndicatorName); - activated = true; - } - else { - mIndicator->deactivate(NmUnreadIndicatorName); - } + bool ok; + if (active) { + ok = mIndicator->activate(NmUnreadIndicatorName); + activated = true; + } + else { + ok = mIndicator->deactivate(NmUnreadIndicatorName); + } + + // update the state only if the activation/deactivation was successful + if (ok) { mUnreadIndicatorActive = active; } @@ -528,11 +578,9 @@ \param folderId Id of the folder that includes the message \param messageIds Message ids that are checked \param mailboxId Id of the mailbox that includes the message - \param updateNeeded Set to true if update needed otherwise not touched - \param activate Set to true if activation needed otherwise not touched */ void NmMailAgent::handleMessageCreatedEvent(const NmId &folderId, const QList &messageIds, - const NmId &mailboxId, bool &updateNeeded, bool &activate) + const NmId &mailboxId) { NM_FUNCTION; @@ -551,21 +599,32 @@ } if (folderId == mailboxInfo->mInboxFolderId) { + mailboxInfo->mInboxCreatedMessages += messageIds.count(); + foreach (NmId messageId, messageIds) { bool messageUnread = false; + mailboxInfo->mMailIdList.append(messageId); - // Check the message if we can either play a tone or if the "@" is - // not visible at the moment - if (mAlertToneAllowed || !mUnreadIndicatorActive) { + // double check that the message ID is really new + bool newMessage = true; + if (mailboxInfo->mNewUnreadMailIdList.indexOf(messageId)>=0) { + newMessage = false; + } + + // If it is a new message, update the mailbox status + if (newMessage) { if (getMessageUnreadInfo(folderId, messageId, mailboxId, messageUnread)) { if (messageUnread) { - mailboxInfo->mUnreadMailIdList.append(messageId); - mailboxInfo->mInboxActive = true; + mailboxInfo->mNewUnreadMailIdList.append(messageId); + NM_COMMENT(QString(" new unread messages: count=%1"). + arg(mailboxInfo->mNewUnreadMailIdList.count())); + + if (!mUnreadIndicatorActive) { + // make the "@" appear immediatelly + updateUnreadIndicator(true); + } updateMailboxState(mailboxId, true, false); - // make the "@" appear immediatelly - updateUnreadIndicator(true); - // Play the tone as well playAlertTone(); } @@ -574,21 +633,15 @@ } } - if (folderId==mailboxInfo->mInboxFolderId) { - mailboxInfo->mInboxCreatedMessages += messageIds.count(); - } - // When created a new mail in the outbox, we are in sending state if (mailboxInfo->mOutboxFolderId == folderId) { // The first mail created in the outbox if (mailboxInfo->mOutboxMails <= 0) { NM_COMMENT("NmMailAgent: first mail in outbox"); } - // Always activate the indicator - activate = true; - updateNeeded = true; - mailboxInfo->mOutboxMails += messageIds.count(); + + updateMailboxState(mailboxId,true,true); updateSendIndicator(); } } @@ -601,45 +654,39 @@ \param folderId Id of the folder that includes the message \param messageIds Message ids that are checked \param mailboxId Id of the mailbox that includes the message - \param updateNeeded Set to true if update needed otherwise not touched - \param activate Set result value of updateUnreadCount method */ -void NmMailAgent::handleMessageChangedEvent(const NmId &folderId, +void NmMailAgent::handleMessageChangedEvent(const NmId &folderId, const QList &messageIds, - const NmId &mailboxId, - bool &updateNeeded, bool &activate) + const NmId &mailboxId) { + NM_FUNCTION; + NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId); // we are interested only about changes in the inbox - if (folderId == mailboxInfo->mInboxFolderId) { + if (mailboxInfo && folderId == mailboxInfo->mInboxFolderId) { mailboxInfo->mInboxChangedMessages++; - // If not currently syncronizing the mailbox, this may mean - // that a message was read/unread - if (mailboxInfo && mailboxInfo->mSyncState == SyncComplete) { - // If there was no unread mails in the list, do nothing - int oldCount(mailboxInfo->mUnreadMailIdList.count()); - if (oldCount>0) { - // Check how many messages were unread earlier - int unreadMessages = 0; - foreach (NmId messageId, messageIds) { - if (mailboxInfo->mUnreadMailIdList.indexOf(messageId)>=0) { - unreadMessages++; + if (mailboxInfo->mNewUnreadMailIdList.count()>0) { + bool updateMailbox = false; + + // Check how many messages was in the list of new unread mails + foreach (NmId messageId, messageIds) { + if (mailboxInfo->mNewUnreadMailIdList.indexOf(messageId)>=0) { + bool messageUnread(false); + if (getMessageUnreadInfo(folderId, messageId, mailboxId, messageUnread)) { + // Message is no longer unread + if (!messageUnread) { + mailboxInfo->mNewUnreadMailIdList.removeAll(messageId); + updateMailbox = true; + } } } - - // Could lead the count drop to 0 => mailbox will be hidden - if (unreadMessages > 0) { - // check the unread status again - activate = updateUnreadCount(mailboxId, *mailboxInfo); - - // no more unread mails in the inbox - if (mailboxInfo->mUnreadMailIdList.count()==0) { - NM_COMMENT("NmMailAgent:handleMessageChangedEvent - no more unread msgs"); - updateNeeded = true; - } - } + } + + if (updateMailbox) { + updateMailboxState(mailboxId); + updateUnreadIndicator(); } } } @@ -651,16 +698,28 @@ \param folderId Id of the folder that includes the message \param messageIds Message ids that are checked \param mailboxId Id of the mailbox that includes the message - \param updateNeeded Set to true if update needed otherwise not touched - \param activate Set to true if activation needed otherwise not touched */ void NmMailAgent::handleMessageDeletedEvent(const NmId &folderId, const QList &messageIds, - const NmId &mailboxId, bool &updateNeeded, bool &activate) + const NmId &mailboxId) { + NM_FUNCTION; + NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId); - if (folderId == mailboxInfo->mInboxFolderId) { + if (mailboxInfo && folderId == mailboxInfo->mInboxFolderId) { mailboxInfo->mInboxDeletedMessages++; + + // Clear the IDs from 'new unread messages' list + foreach (NmId messageId, messageIds) { + mailboxInfo->mNewUnreadMailIdList.removeAll(messageId); + } + + // All new unread messages are now deleted + if (mailboxInfo->mNewUnreadMailIdList.count()==0) { + NM_COMMENT(" No more new unread messages"); + updateUnreadIndicator(); + updateMailboxState(mailboxId); + } } // Deleted mails from the outbox @@ -672,25 +731,12 @@ mailboxInfo->mOutboxMails = 0; } - // The last mail was now deleted + // The last mail was now deleted from outbox if (mailboxInfo->mOutboxMails == 0) { NM_COMMENT("NmMailAgent: last mail deleted from outbox"); - updateNeeded = true; - - // Keep it active if there is unread mails and inbox is still active - if (mailboxInfo->mInboxActive && - mailboxInfo->mUnreadMailIdList.count() > 0) { - activate = true; - } + updateSendIndicator(); } - else { - // Also update the indicator status if it is already shown - if (mailboxInfo->mActive) { - activate = true; - updateNeeded = true; - } - } - updateSendIndicator(); + updateMailboxState(mailboxId); } } @@ -800,6 +846,35 @@ getMailboxInfo(mailboxId); } + +/*! + Handles the view state changed UI event. The event notification is received + via NmUiEventsNotifier. + + \param eventType The type of the UI event. + \param viewId The ID of the view the event concerns. + \param mailboxId The ID of the mailbox related to the UI event. +*/ +void NmMailAgent::handleViewStateChangedEvent( + const NmUiEventsNotifier::NmUiEventType eventType, + const NmUiViewId viewId, + const NmId mailboxId) +{ + if (eventType == NmUiEventsNotifier::NmViewShownEvent && + viewId == NmUiViewMessageList) { + // Get the mailbox info. + NmMailboxInfo *info = getMailboxInfo(mailboxId); + + if (info) { + // The message list view was shown. If the indicator of the mailbox + // in question is active, deactivate it. + updateMailboxState(info->mId, false, false); + resetMailboxState(info); + } + } +} + + /*! Map the type name to mailbox info. @@ -827,6 +902,20 @@ } /*! + Clear the mailbox state to be 'seen' + \param info mailbox that will be reseted + */ +void NmMailAgent::resetMailboxState(NmMailboxInfo *info) +{ + NM_FUNCTION; + + info->mActive = false; // indicator is no longer active + info->mNewUnreadMailIdList.clear(); // no mails are no longer 'new' + storeMailboxActive(info->mId, false); + updateUnreadIndicator(); +} + +/*! Called when indicator is clicked from the indicator menu - indicator will be hide from the menu - mailbox will be launched @@ -842,10 +931,7 @@ // map the indicator type to mailbox NmMailboxInfo *info = getMailboxByType(type); if (info) { - info->mActive = false; // indicator is no longer active - info->mInboxActive = false; // also inbox does not activate the indicator - storeMailboxActive(info->mId, false); - updateUnreadIndicator(); + resetMailboxState(info); launchMailbox(info->mId.id()); } @@ -886,33 +972,22 @@ NM_COMMENT(QString("NmMailAgent::handleMessageEvent(): event=%1, id=%2"). arg(event).arg(mailboxId.id())); - bool updateNeeded = false; - bool activate = false; - switch (event) { case NmMessageCreated: { - handleMessageCreatedEvent(folderId, messageIds, mailboxId, updateNeeded, activate); + handleMessageCreatedEvent(folderId, messageIds, mailboxId); break; } case NmMessageChanged: { - handleMessageChangedEvent(folderId, messageIds, mailboxId, updateNeeded, activate); + handleMessageChangedEvent(folderId, messageIds, mailboxId); break; } case NmMessageDeleted: { - handleMessageDeletedEvent(folderId, messageIds, mailboxId, updateNeeded, activate); + handleMessageDeletedEvent(folderId, messageIds, mailboxId); break; } default: break; } - - if (updateNeeded) { - updateUnreadIndicator(); - - NmMailboxInfo *mailboxInfo = getMailboxInfo(mailboxId); - updateMailboxState(mailboxId, - activate, true /* force refresh */); - } } /*! @@ -932,39 +1007,6 @@ NmMailboxInfo *info = getMailboxInfo(event.mMailboxId); if (info) { info->mSyncState = state; - - if (state==Synchronizing) { - // Reset counters when sync is started - info->mInboxCreatedMessages = 0; - info->mInboxChangedMessages = 0; - info->mInboxDeletedMessages = 0; - } - else if (state==SyncComplete) { - // Check the unread status here again - bool updateMailbox = updateUnreadCount(event.mMailboxId, *info); - int oldOutboxCount = info->mOutboxMails; - info->mOutboxMails = getOutboxCount(event.mMailboxId, info->mOutboxFolderId); - int unreadMailCount(info->mUnreadMailIdList.count()); - if (info->mOutboxMails > oldOutboxCount || unreadMailCount == 0) { - // new mails in outbox - updateMailbox = true; - } - bool active = unreadMailCount || info->mOutboxMails; - - // Refresh the indicator if messages created or changed - NM_COMMENT(QString("NmMailAgent::handleSyncStateEvent(): " - "created=%1, changed=%2, deleted=%3"). - arg(info->mInboxCreatedMessages). - arg(info->mInboxChangedMessages). - arg(info->mInboxDeletedMessages)); - bool refresh = (info->mInboxCreatedMessages > 0) || (info->mInboxChangedMessages > 0); - - updateUnreadIndicator(); - - if (updateMailbox) { - updateMailboxState(event.mMailboxId, active, refresh); - } - } } } @@ -1141,10 +1183,11 @@ bool played(false); if (mAlertToneAllowed) { - // Play tone only if system tone service is available and - // phone is not in silence mode. - if (mSystemTone && !mSilenceMode) { - mSystemTone->playTone(XQSystemToneService::EmailAlertTone); + // Play tone only when phone is not in silence mode. + if (!mSilenceMode) { + // Must instantiate it again to make sure correct tone is played + XQSystemToneService systemTone; + systemTone.playTone(XQSystemToneService::EmailAlertTone); } // Execute the vibra effect.