summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Sanders <don.sanders@nokia.com>2011-08-12 19:40:33 +1000
committerDon Sanders <don.sanders@nokia.com>2011-08-12 19:40:33 +1000
commitb5300c2b7ed58f6e3c11a8eada9168821a779663 (patch)
tree0a798e147c95cb9002d32a89896f23bcec066b4f
parent4fd28721c48ac7bf0b41b4658b9dd144c3ede1ea (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.cpp4
-rw-r--r--src/plugins/messageservices/imap/imapservice.cpp49
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()