9#include "core/filter.h"
10#include "core/messageitem.h"
11#include <MessageCore/StringUtil>
12#include <TextUtils/ConvertText>
15#include <PIM/emailquery.h>
16#include <PIM/resultiterator.h>
22 generateRandomIdentifier();
25bool Filter::containString(
const QString &searchInString)
const
28 const QString searchInStringNormalize{TextUtils::ConvertText::normalize(searchInString)};
29 for (
const QString &str : std::as_const(mSearchList)) {
30 if (searchInStringNormalize.contains(TextUtils::ConvertText::normalize(str),
Qt::CaseInsensitive)) {
40const QString &Filter::iconName()
const
45void Filter::setIconName(
const QString &newIconName)
47 mIconName = newIconName;
52 mOptions = newOptions;
55const QString &Filter::filterName()
const
60void Filter::setFilterName(
const QString &newFilterName)
62 mFilterName = newFilterName;
65void Filter::setIdentifier(
const QString &newIdentifier)
67 mIdentifier = newIdentifier;
72 if (!mStatus.isEmpty()) {
80 if (!mSearchString.isEmpty()) {
81 if (mMatchingItemIds.contains(item->itemId())) {
85 bool searchMatches =
false;
86 bool searchEveryWhere = (mOptions & SearchMessageByButtons::SearchEveryWhere);
87 if (containString(item->
subject()) && ((mOptions & SearchMessageByButtons::SearchAgainstSubject) || searchEveryWhere)) {
89 }
else if (containString(item->
sender()) && ((mOptions & SearchMessageByButtons::SearchAgainstFrom) || searchEveryWhere)) {
91 }
else if (containString(item->
receiver()) && ((mOptions & SearchMessageByButtons::SearchAgainstTo) || searchEveryWhere)) {
99 if (!mTagId.isEmpty()) {
101 const bool tagMatches = item->
findTag(mTagId) !=
nullptr;
120bool Filter::isEmpty()
const
122 if (!mStatus.isEmpty()) {
126 if (!mSearchString.isEmpty()) {
130 if (!mTagId.isEmpty()) {
140 mSearchString.clear();
142 mMatchingItemIds.clear();
148 mCurrentFolder = folder;
153 return mSearchString;
161void Filter::save(
const KSharedConfig::Ptr &config,
const QString &filtername,
const QString &iconName,
int numFilter)
164 int numberFilter = (numFilter == -1) ? grp.readEntry(
"NumberFilter").toInt() : numFilter;
165 KConfigGroup newGroup(config, QStringLiteral(
"Filter_%1").arg(numberFilter++));
166 newGroup.writeEntry(
"name", filtername);
168 newGroup.writeEntry(
"iconName", iconName);
170 newGroup.writeEntry(
"searchString", mSearchString);
171 newGroup.writeEntry(
"searchOptions",
static_cast<int>(mOptions));
172 newGroup.writeEntry(
"tagId", mTagId);
173 newGroup.writeEntry(
"identifier", mIdentifier);
176 for (
const auto s : std::as_const(mStatus)) {
179 newGroup.writeEntry(
"status", lst);
181 grp.writeEntry(
"NumberFilter", numberFilter);
183 config->reparseConfiguration();
186Filter *Filter::load(
const KSharedConfig::Ptr &config,
int filternumber)
189 int numberFilter = grp.readEntry(
"NumberFilter").toInt();
190 if (filternumber < numberFilter) {
191 KConfigGroup newGroup(config, QStringLiteral(
"Filter_%1").arg(filternumber));
192 return loadFromConfigGroup(newGroup);
209 for (
const auto s : std::as_const(lst)) {
212 messageStatusLst <<
status;
214 filter->setStatus(messageStatusLst);
219void Filter::setSearchString(
const SearchLineCommand &command)
221 mMatchingItemIds.clear();
222 if (command.isEmpty()) {
228 for (
const auto &info : infos) {
230 case SearchLineCommand::Literal: {
231 QString newStr = info.argument;
233 bool needToSplitString =
false;
234 for (
const QString &text : searchListTmp) {
235 if (text.size() >= 3) {
243 needToSplitString =
true;
245 mSearchString = newStr;
246 query.matches(newStr);
247 query.setSplitSearchMatchString(needToSplitString);
250 case SearchLineCommand::Subject: {
251 mSearchString = info.argument;
252 query.subjectMatches(mSearchString);
255 case SearchLineCommand::Body: {
256 mSearchString = info.argument;
257 query.bodyMatches(mSearchString);
260 case SearchLineCommand::Unknown:
261 case SearchLineCommand::HasStateOrAttachment:
264 case SearchLineCommand::Larger:
265 case SearchLineCommand::Smaller:
266 case SearchLineCommand::OlderThan:
267 case SearchLineCommand::NewerThan:
268 case SearchLineCommand::Date:
269 case SearchLineCommand::Size:
270 case SearchLineCommand::Category:
273 case SearchLineCommand::HasAttachment: {
279 case SearchLineCommand::HasInvitation: {
285 case SearchLineCommand::IsImportant: {
291 case SearchLineCommand::IsRead: {
297 case SearchLineCommand::IsUnRead: {
304 case SearchLineCommand::IsIgnored: {
310 case SearchLineCommand::IsHam: {
316 case SearchLineCommand::IsSpam: {
322 case SearchLineCommand::IsWatched: {
328 case SearchLineCommand::IsReplied: {
334 case SearchLineCommand::IsForwarded: {
340 case SearchLineCommand::To:
341 mSearchString = info.argument;
342 query.addTo(info.argument);
344 case SearchLineCommand::Bcc:
345 mSearchString = info.argument;
346 query.addBcc(info.argument);
348 case SearchLineCommand::From:
349 mSearchString = info.argument;
350 query.addFrom(info.argument);
352 case SearchLineCommand::Cc:
353 mSearchString = info.argument;
354 query.addCc(info.argument);
359 setStatus(lstStatus);
361 if (mCurrentFolder.isValid() && !mCurrentFolder.isVirtual()) {
362 query.addCollection(mCurrentFolder.id());
367 mMatchingItemIds << it.id();
375 if ((mSearchString == trimStr) && (mOptions == options)) {
379 mSearchString = trimStr;
380 mMatchingItemIds.
clear();
382 if (mSearchString.isEmpty()) {
385 bool needToSplitString =
false;
386 QString newStr = mSearchString;
395 for (
const QString &text : searchListTmp) {
396 if (text.size() >= 3) {
404 needToSplitString =
true;
408 if (options & SearchMessageByButtons::SearchEveryWhere) {
409 query.matches(newStr);
410 query.setSplitSearchMatchString(needToSplitString);
411 }
else if (options & SearchMessageByButtons::SearchAgainstSubject) {
412 query.subjectMatches(newStr);
413 }
else if (options & SearchMessageByButtons::SearchAgainstBody) {
414 query.bodyMatches(newStr);
415 }
else if (options & SearchMessageByButtons::SearchAgainstFrom) {
416 query.setFrom(newStr);
417 }
else if (options & SearchMessageByButtons::SearchAgainstBcc) {
419 }
else if (options & SearchMessageByButtons::SearchAgainstCc) {
421 }
else if (options & SearchMessageByButtons::SearchAgainstTo) {
426 if (mCurrentFolder.isValid() && !mCurrentFolder.isVirtual()) {
427 query.addCollection(mCurrentFolder.id());
432 mMatchingItemIds << it.id();
448void Filter::generateRandomIdentifier()
453QString Filter::identifier()
const
460 d <<
"filtername " << t.filterName();
461 d <<
"identifier " << t.identifier();
463 d <<
"search option " << t.currentOptions();
464 d <<
"status " << t.
status();
468#include "moc_filter.cpp"
void setHam(bool ham=true)
void fromQInt32(qint32 status)
void setRead(bool read=true)
void setHasInvitation(bool hasInvitation=true)
void setForwarded(bool forwarded=true)
void setSpam(bool spam=true)
void setIgnored(bool ignored=true)
void setReplied(bool replied=true)
void setHasAttachment(bool hasAttachment=true)
void setImportant(bool important=true)
void setWatched(bool watched=true)
QString readEntry(const char *key, const char *aDefault=nullptr) const
This class is responsible of matching messages that should be displayed in the View.
QList< Akonadi::MessageStatus > status() const
Returns the currently set status mask.
const QString & searchString() const
Returns the currently set search string.
const QString & receiver() const
Returns the receiver associated to this item.
const Akonadi::MessageStatus & status() const
Returns the status associated to this Item.
const QString & sender() const
Returns the sender associated to this item.
const QString & subject() const
Returns the subject associated to this Item.
const Tag * findTag(const QString &szTagId) const
Returns Tag associated to this message that has the specified id or 0 if no such tag exists.
Q_SCRIPTABLE CaptureState status()
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
KCOREADDONS_EXPORT QString randomString(int length)
The implementation independent part of the MessageList library.
void append(QList< T > &&value)
qsizetype count() const const
void reserve(qsizetype size)
bool isEmpty() const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
int toInt(bool *ok, int base) const const
QString trimmed() const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)