1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "specialpurposepreprocessor.h"
#include "query.h"
#include "applicationdomaintype.h"
#include "datastorequery.h"
using namespace Sink;
SINK_DEBUG_AREA("SpecialPurposeProcessor")
static QHash<QByteArray, QString> specialPurposeFolders()
{
QHash<QByteArray, QString> hash;
//FIXME localize
//TODO inbox
//TODO use standardized values
hash.insert(ApplicationDomain::SpecialPurpose::Mail::drafts, "Drafts");
hash.insert(ApplicationDomain::SpecialPurpose::Mail::trash, "Trash");
hash.insert(ApplicationDomain::SpecialPurpose::Mail::inbox, "Inbox");
hash.insert(ApplicationDomain::SpecialPurpose::Mail::sent, "Sent");
return hash;
}
static QHash<QString, QByteArray> specialPurposeNames()
{
QHash<QString, QByteArray> hash;
for (const auto &value : specialPurposeFolders().values()) {
hash.insert(value.toLower(), specialPurposeFolders().key(value));
}
return hash;
}
//specialpurpose, name
static QHash<QByteArray, QString> sSpecialPurposeFolders = specialPurposeFolders();
//Lowercase-name, specialpurpose
static QHash<QString, QByteArray> sSpecialPurposeNames = specialPurposeNames();
namespace SpecialPurpose {
bool isSpecialPurposeFolderName(const QString &name)
{
return sSpecialPurposeNames.contains(name.toLower());
}
QByteArray getSpecialPurposeType(const QString &name)
{
return sSpecialPurposeNames.value(name.toLower());
}
}
SpecialPurposeProcessor::SpecialPurposeProcessor(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : mResourceType(resourceType), mResourceInstanceIdentifier(resourceInstanceIdentifier) {}
QByteArray SpecialPurposeProcessor::findFolder(const QByteArray &specialPurpose, bool createIfMissing)
{
if (!mSpecialPurposeFolders.contains(specialPurpose)) {
//Try to find an existing drafts folder
DataStoreQuery dataStoreQuery{Sink::Query().filter<ApplicationDomain::Folder::SpecialPurpose>(Query::Comparator(specialPurpose, Query::Comparator::Contains)), ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), entityStore()};
auto resultSet = dataStoreQuery.execute();
resultSet.replaySet(0, 1, [&, this](const ResultSet::Result &r) {
mSpecialPurposeFolders.insert(specialPurpose, r.entity.identifier());
});
if (!mSpecialPurposeFolders.contains(specialPurpose) && createIfMissing) {
SinkTrace() << "Failed to find a " << specialPurpose << " folder, creating a new one";
auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier);
folder.setSpecialPurpose(QByteArrayList() << specialPurpose);
folder.setName(sSpecialPurposeFolders.value(specialPurpose));
folder.setIcon("folder");
//This processes the pipeline synchronously
createEntity(folder);
mSpecialPurposeFolders.insert(specialPurpose, folder.identifier());
}
}
return mSpecialPurposeFolders.value(specialPurpose);
}
bool SpecialPurposeProcessor::isSpecialPurposeFolder(const QByteArray &folder) const
{
return mSpecialPurposeFolders.values().contains(folder);
}
void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity)
{
//If we remove the draft folder move back to inbox
//If we remove the trash property, move back to other specialpurpose folder or inbox
//If a folder is set explicitly, clear specialpurpose flags.
using namespace Sink::ApplicationDomain;
auto mail = newEntity.cast<Mail>();
if (mail.getTrash()) {
auto f = findFolder(ApplicationDomain::SpecialPurpose::Mail::trash, true);
SinkTrace() << "Setting trash folder: " << f;
mail.setFolder(f);
} else if (mail.getDraft()) {
SinkTrace() << "Setting drafts folder: ";
mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::drafts, true));
} else if (mail.getSent()) {
SinkTrace() << "Setting sent folder: ";
mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::sent, true));
} else {
//No longer a specialpurpose mail, so move to inbox
if (isSpecialPurposeFolder(mail.getFolder()) || mail.getFolder().isEmpty()) {
mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::inbox, true));
}
}
}
void SpecialPurposeProcessor::newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity)
{
moveToFolder(newEntity);
}
void SpecialPurposeProcessor::modifiedEntity(const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, Sink::ApplicationDomain::ApplicationDomainType &newEntity)
{
using namespace Sink::ApplicationDomain;
auto mail = newEntity.cast<Mail>();
//If we moved the mail to a non-specialpurpose folder explicitly, also clear the flags.
if (mail.changedProperties().contains(Mail::Folder::name)) {
auto folder = mail.getFolder();
bool isDraft = findFolder(ApplicationDomain::SpecialPurpose::Mail::drafts) == folder;
bool isSent = findFolder(ApplicationDomain::SpecialPurpose::Mail::sent) == folder;
bool isTrash = findFolder(ApplicationDomain::SpecialPurpose::Mail::trash) == folder;
mail.setDraft(isDraft);
mail.setTrash(isSent);
mail.setSent(isTrash);
} else {
moveToFolder(newEntity);
}
}
|