diff options
author | Don Sanders <don.sanders@nokia.com> | 2011-08-12 19:40:33 +1000 |
---|---|---|
committer | Don Sanders <don.sanders@nokia.com> | 2011-08-12 19:40:33 +1000 |
commit | b5300c2b7ed58f6e3c11a8eada9168821a779663 (patch) | |
tree | 0a798e147c95cb9002d32a89896f23bcec066b4f | |
parent | 4fd28721c48ac7bf0b41b4658b9dd144c3ede1ea (diff) |
Improve imap idle support.2011W32
Better detection of flag changes and expunged messages.
Related to NB#269922
-rw-r--r-- | src/plugins/messageservices/imap/imapprotocol.cpp | 4 | ||||
-rw-r--r-- | src/plugins/messageservices/imap/imapservice.cpp | 49 |
2 files changed, 21 insertions, 32 deletions
diff --git a/src/plugins/messageservices/imap/imapprotocol.cpp b/src/plugins/messageservices/imap/imapprotocol.cpp index d380eec2..c5a591c6 100644 --- a/src/plugins/messageservices/imap/imapprotocol.cpp +++ b/src/plugins/messageservices/imap/imapprotocol.cpp @@ -2526,10 +2526,12 @@ void IdleState::untaggedResponse(ImapContext *c, const QString &line) SelectedState::untaggedResponse(c, line); if (idleResponsePattern.indexIn(str) == 0) { // Treat this event as a continuation point - if (previousExists != c->exists()) { + if (previousExists < c->exists()) { // '<' to avoid double check for expunges c->continuation(command(), QString("newmail")); } else if (idleResponsePattern.cap(1).compare("FETCH", Qt::CaseInsensitive) == 0) { c->continuation(command(), QString("flagschanged")); + } else if (idleResponsePattern.cap(1).compare("EXPUNGE", Qt::CaseInsensitive) == 0) { + c->continuation(command(), QString("flagschanged")); // flags check will find expunged messages } } } diff --git a/src/plugins/messageservices/imap/imapservice.cpp b/src/plugins/messageservices/imap/imapservice.cpp index 8fa94368..3a879b99 100644 --- a/src/plugins/messageservices/imap/imapservice.cpp +++ b/src/plugins/messageservices/imap/imapservice.cpp @@ -80,7 +80,6 @@ public: Source(ImapService *service) : QMailMessageSource(service), _service(service), - _flagsCheckQueued(false), _queuedMailCheckInProgress(false), _mailCheckPhase(RetrieveFolders), _unavailable(false), @@ -97,7 +96,7 @@ public: connect(_service->_client, SIGNAL(messageActionCompleted(QString)), this, SLOT(messageActionCompleted(QString))); connect(_service->_client, SIGNAL(retrievalCompleted()), this, SLOT(retrievalCompleted())); connect(_service->_client, SIGNAL(idleNewMailNotification(QMailFolderId)), this, SLOT(queueMailCheck(QMailFolderId))); - connect(_service->_client, SIGNAL(idleFlagsChangedNotification(QMailFolderId)), this, SLOT(queueFlagsChangedCheck())); + connect(_service->_client, SIGNAL(idleFlagsChangedNotification(QMailFolderId)), this, SLOT(queueFlagsChangedCheck(QMailFolderId))); connect(_service->_client, SIGNAL(matchingMessageIds(QMailMessageIdList)), this, SIGNAL(matchingMessageIds(QMailMessageIdList))); connect(&_strategyExpiryTimer, SIGNAL(timeout()), this, SLOT(expireStrategy())); } @@ -153,7 +152,7 @@ public slots: void retrievalTerminated(); void intervalCheck(); void queueMailCheck(QMailFolderId folderId); - void queueFlagsChangedCheck(); + void queueFlagsChangedCheck(QMailFolderId folderId); void resetExpiryTimer(); void expireStrategy(); void emitActionSuccessfullyCompleted(); @@ -170,14 +169,14 @@ private: enum MailCheckPhase { RetrieveFolders = 0, RetrieveMessages, CheckFlags }; ImapService *_service; - bool _flagsCheckQueued; bool _queuedMailCheckInProgress; MailCheckPhase _mailCheckPhase; QMailFolderId _mailCheckFolderId; bool _unavailable; bool _synchronizing; QTimer _intervalTimer; - QList<QMailFolderId> _queuedFolders; + QList<QMailFolderId> _queuedFolders; // require new mail check + QList<QMailFolderId> _queuedFoldersFullCheck; // require flags check also quint64 _setMask; quint64 _unsetMask; QList<QPair<ImapStrategy*, QLatin1String> > _pendingStrategies; @@ -1156,7 +1155,14 @@ void ImapService::Source::retrievalCompleted() if (_queuedMailCheckInProgress) { if (_mailCheckPhase == RetrieveFolders) { _mailCheckPhase = RetrieveMessages; - retrieveMessageList(_service->accountId(), _mailCheckFolderId, 1, QMailMessageSortKey()); + // full check including flags if interval checking, or flags have changed on server for this folder + int minimum = 1; + if (!_mailCheckFolderId.isValid() || _queuedFoldersFullCheck.contains(_mailCheckFolderId)) { + minimum = INT_MAX; // zero means retrieve all mail + } + _queuedFoldersFullCheck.removeAll(_mailCheckFolderId); + + retrieveMessageList(_service->accountId(), _mailCheckFolderId, minimum, QMailMessageSortKey()); return; } else { // Push email must be established @@ -1184,18 +1190,14 @@ void ImapService::Source::retrievalCompleted() if (!_queuedFolders.isEmpty()) { queueMailCheck(_queuedFolders.first()); } - if (_flagsCheckQueued) { - queueFlagsChangedCheck(); - } } // Interval mail checking timer has expired, perform mail check on all folders void ImapService::Source::intervalCheck() { - _flagsCheckQueued = true; // Convenient for user to check for flag changes on server also _service->_client->requestRapidClose(); exportUpdates(_service->accountId()); // Convenient for user to export pending changes also - queueMailCheck(QMailFolderId()); + queueMailCheck(QMailFolderId()); // Full check including flags } void ImapService::Source::queueMailCheck(QMailFolderId folderId) @@ -1221,27 +1223,12 @@ void ImapService::Source::queueMailCheck(QMailFolderId folderId) } } -void ImapService::Source::queueFlagsChangedCheck() +void ImapService::Source::queueFlagsChangedCheck(QMailFolderId folderId) { - if (_service->_client->strategyContext()->updateMessagesFlagsStrategy.selectedMails().isEmpty()) - return; // No flags previously checked, nothing to do - - if (_unavailable) { - _flagsCheckQueued = true; - return; + if (!_queuedFoldersFullCheck.contains(folderId)) { + _queuedFoldersFullCheck.append(folderId); } - - _flagsCheckQueued = false; - _queuedMailCheckInProgress = true; - _mailCheckPhase = CheckFlags; - - emit _service->availabilityChanged(false); - _service->_client->requestRapidClose(); - - // Check same messages as last time - appendStrategy(&_service->_client->strategyContext()->updateMessagesFlagsStrategy); - if(!_unavailable) - initiateStrategy(); + queueMailCheck(folderId); } void ImapService::Source::retrievalTerminated() @@ -1256,7 +1243,7 @@ void ImapService::Source::retrievalTerminated() // Just give up if an error occurs _queuedFolders.clear(); - _flagsCheckQueued = false; + _queuedFoldersFullCheck.clear(); } void ImapService::Source::resetExpiryTimer() |