File indexing completed on 2024-05-12 05:26:04
0001 #include "specialpurposepreprocessor.h" 0002 #include "query.h" 0003 #include "applicationdomaintype.h" 0004 #include "datastorequery.h" 0005 0006 using namespace Sink; 0007 0008 static QHash<QByteArray, QString> specialPurposeFolders() 0009 { 0010 QHash<QByteArray, QString> hash; 0011 //FIXME localize 0012 //TODO inbox 0013 //TODO use standardized values 0014 hash.insert(ApplicationDomain::SpecialPurpose::Mail::drafts, "Drafts"); 0015 hash.insert(ApplicationDomain::SpecialPurpose::Mail::trash, "Trash"); 0016 hash.insert(ApplicationDomain::SpecialPurpose::Mail::inbox, "Inbox"); 0017 hash.insert(ApplicationDomain::SpecialPurpose::Mail::sent, "Sent"); 0018 return hash; 0019 } 0020 0021 static QHash<QString, QByteArray> specialPurposeNames() 0022 { 0023 QHash<QString, QByteArray> hash; 0024 for (const auto &value : specialPurposeFolders().values()) { 0025 hash.insert(value.toLower(), specialPurposeFolders().key(value)); 0026 } 0027 return hash; 0028 } 0029 0030 //specialpurpose, name 0031 static QHash<QByteArray, QString> sSpecialPurposeFolders = specialPurposeFolders(); 0032 //Lowercase-name, specialpurpose 0033 static QHash<QString, QByteArray> sSpecialPurposeNames = specialPurposeNames(); 0034 0035 namespace SpecialPurpose { 0036 bool isSpecialPurposeFolderName(const QString &name) 0037 { 0038 return sSpecialPurposeNames.contains(name.toLower()); 0039 } 0040 0041 QByteArray getSpecialPurposeType(const QString &name) 0042 { 0043 return sSpecialPurposeNames.value(name.toLower()); 0044 } 0045 } 0046 0047 SpecialPurposeProcessor::SpecialPurposeProcessor() : Sink::Preprocessor() {} 0048 0049 QByteArray SpecialPurposeProcessor::findFolder(const QByteArray &specialPurpose, bool createIfMissing) 0050 { 0051 if (!mSpecialPurposeFolders.contains(specialPurpose)) { 0052 //Try to find an existing and enabled folder we can use. 0053 auto query = Sink::Query(); 0054 query.filter<ApplicationDomain::Folder::SpecialPurpose>(Query::Comparator(specialPurpose, Query::Comparator::Contains)); 0055 query.filter<ApplicationDomain::Folder::Enabled>(true); 0056 query.request<ApplicationDomain::Folder::Enabled>(); 0057 0058 DataStoreQuery dataStoreQuery{query, ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), entityStore()}; 0059 auto resultSet = dataStoreQuery.execute(); 0060 resultSet.replaySet(0, 1, [&, this](const ResultSet::Result &r) { 0061 mSpecialPurposeFolders.insert(specialPurpose, r.entity.identifier()); 0062 }); 0063 0064 //Create a new folder if we couldn't find one. We will also create a new folder if the old one was disabled for some reason. 0065 if (!mSpecialPurposeFolders.contains(specialPurpose) && createIfMissing) { 0066 SinkTrace() << "Failed to find a " << specialPurpose << " folder, creating a new one"; 0067 auto folder = ApplicationDomain::Folder::create(resourceInstanceIdentifier()); 0068 folder.setSpecialPurpose(QByteArrayList() << specialPurpose); 0069 folder.setName(sSpecialPurposeFolders.value(specialPurpose)); 0070 folder.setIcon("folder"); 0071 folder.setEnabled(true); 0072 //This processes the pipeline synchronously 0073 createEntity(folder); 0074 mSpecialPurposeFolders.insert(specialPurpose, folder.identifier()); 0075 } 0076 } 0077 return mSpecialPurposeFolders.value(specialPurpose); 0078 } 0079 0080 bool SpecialPurposeProcessor::isSpecialPurposeFolder(const QByteArray &folder) const 0081 { 0082 return mSpecialPurposeFolders.values().contains(folder); 0083 } 0084 0085 void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity) 0086 { 0087 //If we remove the draft folder move back to inbox 0088 //If we remove the trash property, move back to other specialpurpose folder or inbox 0089 //If a folder is set explicitly, clear specialpurpose flags. 0090 using namespace Sink::ApplicationDomain; 0091 auto mail = newEntity.cast<Mail>(); 0092 if (mail.getTrash()) { 0093 auto f = findFolder(ApplicationDomain::SpecialPurpose::Mail::trash, true); 0094 SinkTrace() << "Setting trash folder: " << f; 0095 mail.setFolder(f); 0096 } else if (mail.getDraft()) { 0097 SinkTrace() << "Setting drafts folder: "; 0098 mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::drafts, true)); 0099 } else if (mail.getSent()) { 0100 SinkTrace() << "Setting sent folder: "; 0101 mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::sent, true)); 0102 } else { 0103 //No longer a specialpurpose mail, so move to inbox 0104 if (isSpecialPurposeFolder(mail.getFolder()) || mail.getFolder().isEmpty()) { 0105 mail.setFolder(findFolder(ApplicationDomain::SpecialPurpose::Mail::inbox, true)); 0106 } 0107 } 0108 } 0109 0110 void SpecialPurposeProcessor::newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity) 0111 { 0112 auto mail = newEntity.cast<ApplicationDomain::Mail>(); 0113 const auto folder = mail.getFolder(); 0114 if (folder.isEmpty()) { 0115 moveToFolder(newEntity); 0116 } else { 0117 bool isDraft = findFolder(ApplicationDomain::SpecialPurpose::Mail::drafts) == folder; 0118 bool isSent = findFolder(ApplicationDomain::SpecialPurpose::Mail::sent) == folder; 0119 bool isTrash = findFolder(ApplicationDomain::SpecialPurpose::Mail::trash) == folder; 0120 mail.setDraft(isDraft); 0121 mail.setTrash(isTrash); 0122 mail.setSent(isSent); 0123 } 0124 0125 } 0126 0127 void SpecialPurposeProcessor::modifiedEntity(const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, Sink::ApplicationDomain::ApplicationDomainType &newEntity) 0128 { 0129 using namespace Sink::ApplicationDomain; 0130 auto mail = newEntity.cast<Mail>(); 0131 //If we moved the mail to a non-specialpurpose folder explicitly, also clear the flags. 0132 if (mail.changedProperties().contains(Mail::Folder::name)) { 0133 auto folder = mail.getFolder(); 0134 bool isDraft = findFolder(ApplicationDomain::SpecialPurpose::Mail::drafts) == folder; 0135 bool isSent = findFolder(ApplicationDomain::SpecialPurpose::Mail::sent) == folder; 0136 bool isTrash = findFolder(ApplicationDomain::SpecialPurpose::Mail::trash) == folder; 0137 mail.setDraft(isDraft); 0138 mail.setTrash(isTrash); 0139 mail.setSent(isSent); 0140 } else { 0141 moveToFolder(newEntity); 0142 } 0143 }