Skip to content

Commit

Permalink
Merge branch 'jb50162' into 'master'
Browse files Browse the repository at this point in the history
Apply folder sync policy

See merge request mer-core/messagingframework!43
  • Loading branch information
llewelld committed Jul 16, 2020
2 parents 2c7fc20 + 7595628 commit c64be58
Show file tree
Hide file tree
Showing 3 changed files with 515 additions and 0 deletions.
388 changes: 388 additions & 0 deletions rpm/0023-Retrieve-message-lists-based-on-the-folder-sync-poli.patch
@@ -0,0 +1,388 @@
From 315a8a1c60150145a42c21023095e878bc1f4a9b Mon Sep 17 00:00:00 2001
From: David Llewellyn-Jones <david.llewellyn-jones@jolla.com>
Date: Wed, 8 Jul 2020 15:51:08 +0000
Subject: [PATCH] Retrieve message lists based on the folder sync policy

Uses the folder sync policy extracted from the account and applies it
when downloading messages from different folders.

Also captures the sync policy as part of the QMailAccount structure.
---
src/libraries/qmfclient/qmailaccount.cpp | 10 ++++
src/libraries/qmfclient/qmailaccount.h | 10 ++++
src/libraries/qmfclient/qmailstore_p.cpp | 47 +++++++++++++++++++
src/libraries/qmfclient/qmailstore_p.h | 3 ++
.../messageservices/imap/imapservice.cpp | 21 ++++++---
.../messageservices/imap/imapstrategy.cpp | 45 ++++++++++++++++--
.../messageservices/imap/imapstrategy.h | 7 +--
.../messageservices/pop/popservice.cpp | 7 +++
8 files changed, 138 insertions(+), 12 deletions(-)

diff --git a/src/libraries/qmfclient/qmailaccount.cpp b/src/libraries/qmfclient/qmailaccount.cpp
index b477e907..5163e370 100644
--- a/src/libraries/qmfclient/qmailaccount.cpp
+++ b/src/libraries/qmfclient/qmailaccount.cpp
@@ -89,6 +89,7 @@ public:
QStringList _sinks;
QMap<QMailFolder::StandardFolder, QMailFolderId> _standardFolders;
QString _iconPath;
+ QMailAccount::FolderSyncPolicy _folderSyncPolicy;

QMap<QString, QString> _customFields;
bool _customFieldsModified;
@@ -780,3 +781,12 @@ void QMailAccount::addMessageSink(const QString &sink)
d->_sinks.append(sink);
}

+QMailAccount::FolderSyncPolicy QMailAccount::folderSyncPolicy() const
+{
+ return d->_folderSyncPolicy;
+}
+
+void QMailAccount::setFolderSyncPolicy(QMailAccount::FolderSyncPolicy policy)
+{
+ d->_folderSyncPolicy = policy;
+}
diff --git a/src/libraries/qmfclient/qmailaccount.h b/src/libraries/qmfclient/qmailaccount.h
index 9306dd9c..933cfa0c 100644
--- a/src/libraries/qmfclient/qmailaccount.h
+++ b/src/libraries/qmfclient/qmailaccount.h
@@ -79,6 +79,13 @@ public:
static const quint64 &HasPersistentConnection;
static const quint64 &UseCryptoSignatureByDefault;

+ enum FolderSyncPolicy {
+ SyncSelectedFolders,
+ SyncInboxOnly,
+ SyncInboxAndSubfolders,
+ SyncEverything
+ };
+
QMailAccount();
explicit QMailAccount(const QMailAccountId& id);
QMailAccount(const QMailAccount& other);
@@ -121,6 +128,9 @@ public:

const QMap<QMailFolder::StandardFolder, QMailFolderId> &standardFolders() const;

+ FolderSyncPolicy folderSyncPolicy() const;
+ void setFolderSyncPolicy(FolderSyncPolicy policy);
+
quint64 status() const;
void setStatus(quint64 newStatus);
void setStatus(quint64 mask, bool set);
diff --git a/src/libraries/qmfclient/qmailstore_p.cpp b/src/libraries/qmfclient/qmailstore_p.cpp
index a6913276..d21a7e19 100644
--- a/src/libraries/qmfclient/qmailstore_p.cpp
+++ b/src/libraries/qmfclient/qmailstore_p.cpp
@@ -3702,6 +3702,42 @@ bool QMailStorePrivate::messageExists(const QString &serveruid, const QMailAccou
}

#ifdef USE_ACCOUNTS_QT
+QString const QMailStorePrivate::folderSyncPolicyToString(QMailAccount::FolderSyncPolicy policy)
+{
+ QString folderSyncPolicy;
+ switch (policy) {
+ case QMailAccount::SyncInboxAndSubfolders:
+ folderSyncPolicy = QStringLiteral("inbox-and-subfolders");
+ break;
+ case QMailAccount::SyncEverything:
+ folderSyncPolicy = QStringLiteral("ignore-flags");
+ break;
+ case QMailAccount::SyncSelectedFolders:
+ folderSyncPolicy = QStringLiteral("follow-flags");
+ break;
+ case QMailAccount::SyncInboxOnly:
+ default:
+ folderSyncPolicy = QStringLiteral("inbox-only");
+ break;
+ }
+
+ return folderSyncPolicy;
+}
+
+QMailAccount::FolderSyncPolicy QMailStorePrivate::folderSyncPolicyToEnum(QString const &policy)
+{
+ QMailAccount::FolderSyncPolicy result = QMailAccount::SyncInboxOnly;
+ if (policy == QStringLiteral("follow-flags")) {
+ result = QMailAccount::SyncSelectedFolders;
+ } else if (policy == QStringLiteral("inbox-and-subfolders")) {
+ result = QMailAccount::SyncInboxAndSubfolders;
+ } else if (policy == QStringLiteral("ignore-flags")) {
+ result = QMailAccount::SyncEverything;
+ }
+
+ return result;
+}
+
QMailAccount QMailStorePrivate::extractAccount(const QSharedPointer<Accounts::Account>& ssoAccount)
{
Q_ASSERT(ssoAccount);
@@ -3719,6 +3755,8 @@ QMailAccount QMailStorePrivate::extractAccount(const QSharedPointer<Accounts::Ac

ssoAccount->selectService();
const bool& enabled = ssoAccount->enabled();
+ result.setFolderSyncPolicy(folderSyncPolicyToEnum(ssoAccount->valueAsString("folderSyncPolicy")));
+
ssoAccount->selectService(service);
const bool& isDefault = ssoAccount->valueAsBool("email/default");
const bool& canTransmit = ssoAccount->valueAsBool("canTransmit", true);
@@ -6223,6 +6261,9 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptAddAccount(QMailAccou
ssoAccount->setDisplayName(account->name());
ssoAccount->setEnabled(account->status() & QMailAccount::Enabled);

+ ssoAccount->selectService();
+ ssoAccount->setValue("folderSyncPolicy", folderSyncPolicyToString(account->folderSyncPolicy()));
+
Accounts::ServiceList services = ssoAccount->services("e-mail");
if (!services.count()) {
qMailLog(Messaging) << "E-mail Services not found, make sure that *.service and *.provider files are properly installed.";
@@ -7017,6 +7058,11 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateAccount(QMailAc
if (!ssoAccount)
return Failure;

+ if (account) {
+ ssoAccount->selectService();
+ ssoAccount->setValue("folderSyncPolicy", folderSyncPolicyToString(account->folderSyncPolicy()));
+ }
+
Accounts::ServiceList services = ssoAccount->enabledServices();
Q_ASSERT (services.count() == 1);
Accounts::Service service = services.first();
@@ -7066,6 +7112,7 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateAccount(QMailAc
ssoAccount->setValue("email/default", isDefault);
ssoAccount->setValue("canTransmit", canTransmit);
ssoAccount->setValue("iconPath", account->iconPath());
+
#else
QString properties(QLatin1String("type=?, name=?, emailaddress=?, status=?, signature=?, lastsynchronized=?, iconpath=?"));
QVariantList propertyValues;
diff --git a/src/libraries/qmfclient/qmailstore_p.h b/src/libraries/qmfclient/qmailstore_p.h
index 3d083d0f..fea94c53 100644
--- a/src/libraries/qmfclient/qmailstore_p.h
+++ b/src/libraries/qmfclient/qmailstore_p.h
@@ -246,6 +246,9 @@ public:
enum AttemptResult { Success = 0, Failure, DatabaseFailure };

#ifdef USE_ACCOUNTS_QT
+ static QString const folderSyncPolicyToString(QMailAccount::FolderSyncPolicy policy);
+ static QMailAccount::FolderSyncPolicy folderSyncPolicyToEnum(QString const &policy);
+
QMailAccountIdList searchSSOAccounts(const QMailAccountKey& key, const QMailAccountSortKey& sortKey = QMailAccountSortKey()) const;
#endif

diff --git a/src/plugins/messageservices/imap/imapservice.cpp b/src/plugins/messageservices/imap/imapservice.cpp
index 86b88a2c..71664b84 100644
--- a/src/plugins/messageservices/imap/imapservice.cpp
+++ b/src/plugins/messageservices/imap/imapservice.cpp
@@ -228,7 +228,7 @@ bool ImapService::Source::retrieveFolderList(const QMailAccountId &accountId, co
_service->_client->strategyContext()->foldersOnlyStrategy.setBase(folderId);
_service->_client->strategyContext()->foldersOnlyStrategy.setQuickList(!folderId.isValid());
_service->_client->strategyContext()->foldersOnlyStrategy.setDescending(descending);
- _service->_client->strategyContext()->foldersOnlyStrategy.setIgnoreSyncFlag(true);
+ _service->_client->strategyContext()->foldersOnlyStrategy.setFolderSyncPolicy(QMailAccount::SyncEverything);
appendStrategy(&_service->_client->strategyContext()->foldersOnlyStrategy);
if(!_unavailable)
return initiateStrategy();
@@ -257,10 +257,10 @@ bool ImapService::Source::retrieveMessageList(const QMailAccountId &accountId, c
{
Q_ASSERT(!_unavailable);
if (folderId.isValid()) {
- return retrieveMessageLists(accountId, QMailFolderIdList() << folderId, minimum, sort, true /* Full check */);
+ return retrieveMessageLists(accountId, QMailFolderIdList() << folderId, minimum, sort, true /* accountCheck */);
}

- return retrieveMessageLists(accountId, QMailFolderIdList(), minimum, sort, true /* Full check */);
+ return retrieveMessageLists(accountId, QMailFolderIdList(), minimum, sort, true /* accountCheck */);
}

bool ImapService::Source::retrieveNewMessages(const QMailAccountId &accountId, const QMailFolderIdList &folderIds)
@@ -304,6 +304,9 @@ bool ImapService::Source::retrieveMessageLists(const QMailAccountId &accountId,
qWarning() << "IMAP Search sorting not yet implemented!";
}

+ QMailAccount account(accountId);
+ QMailAccount::FolderSyncPolicy folderSyncPolicy = account.folderSyncPolicy();
+
QMailFolderIdList folderIds;
uint adjustedMinimum = minimum ? minimum : INT_MAX; // zero means retrieve all mail
_service->_client->strategyContext()->retrieveMessageListStrategy.clearSelection();
@@ -323,7 +326,7 @@ bool ImapService::Source::retrieveMessageLists(const QMailAccountId &accountId,

_service->_client->strategyContext()->retrieveMessageListStrategy.setOperation(_service->_client->strategyContext(), QMailRetrievalAction::Auto);
_service->_client->strategyContext()->retrieveMessageListStrategy.selectedFoldersAppend(folderIds);
- _service->_client->strategyContext()->retrieveMessageListStrategy.setIgnoreSyncFlag(!_folderIds.isEmpty());
+ _service->_client->strategyContext()->retrieveMessageListStrategy.setFolderSyncPolicy(folderSyncPolicy);
appendStrategy(&_service->_client->strategyContext()->retrieveMessageListStrategy);
if(!_unavailable)
return initiateStrategy();
@@ -526,12 +529,15 @@ bool ImapService::Source::retrieveAll(const QMailAccountId &accountId)
return false;
}

+ QMailAccount account(accountId);
+ QMailAccount::FolderSyncPolicy folderSyncPolicy = account.folderSyncPolicy();
+
_service->_client->strategyContext()->retrieveAllStrategy.clearSelection();
_service->_client->strategyContext()->retrieveAllStrategy.setBase(QMailFolderId());
_service->_client->strategyContext()->retrieveAllStrategy.setQuickList(false);
_service->_client->strategyContext()->retrieveAllStrategy.setDescending(true);
_service->_client->strategyContext()->retrieveAllStrategy.setOperation(_service->_client->strategyContext(), QMailRetrievalAction::Auto);
- _service->_client->strategyContext()->retrieveAllStrategy.setIgnoreSyncFlag(false);
+ _service->_client->strategyContext()->retrieveAllStrategy.setFolderSyncPolicy(folderSyncPolicy);
appendStrategy(&_service->_client->strategyContext()->retrieveAllStrategy);
if(!_unavailable)
return initiateStrategy();
@@ -603,6 +609,9 @@ bool ImapService::Source::synchronize(const QMailAccountId &accountId)
return false;
}

+ QMailAccount account(accountId);
+ QMailAccount::FolderSyncPolicy folderSyncPolicy = account.folderSyncPolicy();
+
queueDisconnectedOperations(accountId);

_service->_client->strategyContext()->synchronizeAccountStrategy.clearSelection();
@@ -610,7 +619,7 @@ bool ImapService::Source::synchronize(const QMailAccountId &accountId)
_service->_client->strategyContext()->synchronizeAccountStrategy.setQuickList(false);
_service->_client->strategyContext()->synchronizeAccountStrategy.setDescending(true);
_service->_client->strategyContext()->synchronizeAccountStrategy.setOperation(_service->_client->strategyContext(), QMailRetrievalAction::Auto);
- _service->_client->strategyContext()->synchronizeAccountStrategy.setIgnoreSyncFlag(false);
+ _service->_client->strategyContext()->synchronizeAccountStrategy.setFolderSyncPolicy(folderSyncPolicy);
appendStrategy(&_service->_client->strategyContext()->synchronizeAccountStrategy);
if(!_unavailable)
return initiateStrategy();
diff --git a/src/plugins/messageservices/imap/imapstrategy.cpp b/src/plugins/messageservices/imap/imapstrategy.cpp
index 142fd0c7..7511336b 100644
--- a/src/plugins/messageservices/imap/imapstrategy.cpp
+++ b/src/plugins/messageservices/imap/imapstrategy.cpp
@@ -2362,14 +2362,53 @@ void ImapSynchronizeBaseStrategy::previewDiscoveredMessages(ImapStrategyContextB
}
}

-void ImapSynchronizeBaseStrategy::setIgnoreSyncFlag(bool ignoreSyncFlag)
+void ImapSynchronizeBaseStrategy::setFolderSyncPolicy(QMailAccount::FolderSyncPolicy policy)
{
- _ignoreSyncFlag = ignoreSyncFlag;
+ _folderSyncPolicy = policy;
}

bool ImapSynchronizeBaseStrategy::synchronizationEnabled(const QMailFolder &folder) const
{
- return _ignoreSyncFlag || (folder.status() & QMailFolder::SynchronizationEnabled);
+ bool result = true;
+
+ QMailFolderId inbox;
+ if ((_folderSyncPolicy == QMailAccount::SyncInboxOnly) || (_folderSyncPolicy == QMailAccount::SyncInboxAndSubfolders)) {
+ // Find the inbox if we're going to need it
+ inbox = QMailAccount(folder.parentAccountId()).standardFolder(QMailFolder::InboxFolder);
+ }
+
+ switch (_folderSyncPolicy) {
+ default:
+ case QMailAccount::SyncSelectedFolders:
+ result = (folder.status() & QMailFolder::SynchronizationEnabled) != 0;
+ break;
+ case QMailAccount::SyncInboxOnly:
+ result = (folder.id() == inbox);
+ break;
+ case QMailAccount::SyncInboxAndSubfolders: {
+ QMailFolder check = folder;
+ result = false;
+ while (!result && check.id().isValid()) {
+ if (check.id() == inbox) {
+ result = true;
+ }
+ else {
+ if (check.parentFolderId().isValid()) {
+ check = QMailFolder(check.parentFolderId());
+ }
+ else {
+ check = QMailFolder();
+ }
+ }
+ }
+ }
+ break;
+ case QMailAccount::SyncEverything:
+ // Do nothing;
+ break;
+ }
+
+ return result;
}

bool ImapSynchronizeBaseStrategy::nextFolder()
diff --git a/src/plugins/messageservices/imap/imapstrategy.h b/src/plugins/messageservices/imap/imapstrategy.h
index 260fd580..2fe13d1f 100644
--- a/src/plugins/messageservices/imap/imapstrategy.h
+++ b/src/plugins/messageservices/imap/imapstrategy.h
@@ -36,6 +36,7 @@

#include "imapprotocol.h"
#include "integerregion.h"
+#include "qmailaccount.h"
#include <qstring.h>
#include <qstringlist.h>
#include <qlist.h>
@@ -456,14 +457,14 @@ private:
class ImapSynchronizeBaseStrategy : public ImapFolderListStrategy
{
public:
- ImapSynchronizeBaseStrategy() : _ignoreSyncFlag(false) {}
+ ImapSynchronizeBaseStrategy() : _folderSyncPolicy(QMailAccount::SyncSelectedFolders) {}
virtual ~ImapSynchronizeBaseStrategy() {}

virtual void newConnection(ImapStrategyContextBase *context);

virtual bool messageFetched(ImapStrategyContextBase *context, QMailMessage &message);
virtual void messageFlushed(ImapStrategyContextBase *context, QMailMessage &message);
- virtual void setIgnoreSyncFlag(bool ignoreSyncFlag);
+ virtual void setFolderSyncPolicy(QMailAccount::FolderSyncPolicy policy);

protected:
virtual void handleLogin(ImapStrategyContextBase *context);
@@ -489,7 +490,7 @@ protected:
int _outstandingPreviews;

private:
- bool _ignoreSyncFlag;
+ QMailAccount::FolderSyncPolicy _folderSyncPolicy;
uint _progress;
uint _total;
};
diff --git a/src/plugins/messageservices/pop/popservice.cpp b/src/plugins/messageservices/pop/popservice.cpp
index 3b8663a7..7b6492ab 100644
--- a/src/plugins/messageservices/pop/popservice.cpp
+++ b/src/plugins/messageservices/pop/popservice.cpp
@@ -96,6 +96,7 @@ private:
bool _unavailable;
bool _mailCheckQueued;
bool _queuedMailCheckInProgress;
+ QMailAccount::FolderSyncPolicy _folderSyncPolicy;
QTimer _intervalTimer;
};

@@ -146,6 +147,9 @@ bool PopService::Source::retrieveMessageList(const QMailAccountId &accountId, co
return false;
}

+ QMailAccount account(accountId);
+ _folderSyncPolicy = account.folderSyncPolicy();
+
QMailMessageKey countKey(QMailMessageKey::parentAccountId(accountId));
countKey &= ~QMailMessageKey::status(QMailMessage::Temporary);
uint existing = QMailStore::instance()->countMessages(countKey);
@@ -208,6 +212,9 @@ bool PopService::Source::retrieveAll(const QMailAccountId &accountId)
return false;
}

+ QMailAccount account(accountId);
+ _folderSyncPolicy = account.folderSyncPolicy();
+
_service->_client.setOperation(QMailRetrievalAction::MetaData);
_service->_client.newConnection();
_unavailable = true;
--
2.26.2

0 comments on commit c64be58

Please sign in to comment.