22#include "kimap_debug.h"
24#include <QtCore/QDate>
37 Private(): isFuzzy(false), isNegated(false), isNull(false) {}
45 : d(new
Term::Private)
50Term::Term(Term::Relation relation,
const QVector<Term> &subterms)
51 : d(new
Term::Private)
53 if (subterms.
size() >= 2) {
54 if (relation == KIMAP2::Term::Or) {
55 for (int i = 0; i < subterms.size() - 1; ++i) {
56 d->command +=
"(OR " + subterms[i].serialize() +
" ";
58 d->command += subterms.back().serialize();
59 for (int i = 0; i < subterms.size() - 1; ++i) {
64 for (const Term &t : subterms) {
65 d->command += t.serialize() +
' ';
72 }
else if (subterms.
size() == 1) {
73 d->command += subterms.first().serialize();
79Term::Term(Term::SearchKey key,
const QString &value)
80 : d(new
Term::Private)
99 d->command +=
"KEYWORD";
102 d->command +=
"SUBJECT";
105 d->command +=
"TEXT";
117 : d(new
Term::Private)
119 d->command +=
"HEADER";
124Term::Term(Term::BooleanSearchKey key)
125 : d(new
Term::Private)
129 d->command =
"ANSWERED";
132 d->command =
"DELETED";
135 d->command =
"DRAFT";
138 d->command =
"FLAGGED";
147 d->command =
"RECENT";
157 static const char* names[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
161Term::Term(Term::DateSearchKey key,
const QDate &date)
162 : d(new
Term::Private)
166 d->command =
"BEFORE";
172 d->command =
"SENTBEFORE";
175 d->command =
"SENTON";
178 d->command =
"SENTSINCE";
181 d->command =
"SINCE";
186 d->command += monthName(date.
month()) +
'-';
191Term::Term(Term::NumberSearchKey key,
int value)
192 : d(new
Term::Private)
196 d->command =
"LARGER";
199 d->command =
"SMALLER";
205Term::Term(Term::SequenceSearchKey key,
const ImapSet &set)
206 : d(new
Term::Private)
215 auto optimizedSet = set;
217 d->command +=
" " + optimizedSet.toImapSequenceSet();
220Term::Term(
const Term &other)
221 : d(new
Term::Private)
226Term &Term::operator=(
const Term &other)
232bool Term::operator==(
const Term &other)
const
234 return d->command == other.d->command &&
235 d->isNegated == other.d->isNegated &&
236 d->isFuzzy == other.d->isFuzzy;
248 return command + d->command;
251Term &Term::setFuzzy(
bool fuzzy)
257Term &Term::setNegated(
bool negated)
259 d->isNegated = negated;
263bool Term::isNull()
const
270class SearchJobPrivate :
public JobPrivate
273 SearchJobPrivate(
Session *session,
const QString &name) : JobPrivate(session,
name), logic(SearchJob::And)
275 criteriaMap[SearchJob::All] =
"ALL";
276 criteriaMap[SearchJob::Answered] =
"ANSWERED";
277 criteriaMap[SearchJob::BCC] =
"BCC";
278 criteriaMap[SearchJob::Before] =
"BEFORE";
279 criteriaMap[SearchJob::Body] =
"BODY";
280 criteriaMap[SearchJob::CC] =
"CC";
281 criteriaMap[SearchJob::Deleted] =
"DELETED";
282 criteriaMap[SearchJob::Draft] =
"DRAFT";
283 criteriaMap[SearchJob::Flagged] =
"FLAGGED";
284 criteriaMap[SearchJob::From] =
"FROM";
285 criteriaMap[SearchJob::Header] =
"HEADER";
286 criteriaMap[SearchJob::Keyword] =
"KEYWORD";
287 criteriaMap[SearchJob::Larger] =
"LARGER";
288 criteriaMap[SearchJob::New] =
"NEW";
289 criteriaMap[SearchJob::Old] =
"OLD";
290 criteriaMap[SearchJob::On] =
"ON";
291 criteriaMap[SearchJob::Recent] =
"RECENT";
292 criteriaMap[SearchJob::Seen] =
"SEEN";
293 criteriaMap[SearchJob::SentBefore] =
"SENTBEFORE";
294 criteriaMap[SearchJob::SentOn] =
"SENTON";
295 criteriaMap[SearchJob::SentSince] =
"SENTSINCE";
296 criteriaMap[SearchJob::Since] =
"SINCE";
297 criteriaMap[SearchJob::Smaller] =
"SMALLER";
298 criteriaMap[SearchJob::Subject] =
"SUBJECT";
299 criteriaMap[SearchJob::Text] =
"TEXT";
300 criteriaMap[SearchJob::To] =
"TO";
301 criteriaMap[SearchJob::Uid] =
"UID";
302 criteriaMap[SearchJob::Unanswered] =
"UNANSWERED";
303 criteriaMap[SearchJob::Undeleted] =
"UNDELETED";
304 criteriaMap[SearchJob::Undraft] =
"UNDRAFT";
305 criteriaMap[SearchJob::Unflagged] =
"UNFLAGGED";
306 criteriaMap[SearchJob::Unkeyword] =
"UNKEYWORD";
307 criteriaMap[SearchJob::Unseen] =
"UNSEEN";
326 ~SearchJobPrivate() { }
332 SearchJob::SearchLogic logic;
341using namespace KIMAP2;
343SearchJob::SearchJob(
Session *session)
344 : Job(*new SearchJobPrivate(session,
"Search"))
348SearchJob::~SearchJob()
352void SearchJob::setTerm(
const Term &term)
358void SearchJob::doStart()
364 if (!d->charset.isEmpty()) {
365 searchKey =
"CHARSET " + d->charset;
368 if (!d->term.isNull()) {
371 searchKey += term.
mid(1, term.
size() - 2);
377 if (d->logic == SearchJob::Not) {
379 }
else if (d->logic == SearchJob::Or && d->criterias.size() > 1) {
383 if (d->logic == SearchJob::And) {
384 for (
int i = 0; i < d->criterias.size(); i++) {
392 for (
int i = 0; i < d->criterias.size(); i++) {
397 searchKey +=
'(' + key +
')';
404 command =
"UID " + command;
407 d->sendCommand(command, searchKey);
410void SearchJob::handleResponse(
const Message &response)
414 if (handleErrorReplies(response) == NotHandled) {
415 if (response.content.size() >= 1 && response.content[0].toString() ==
"+") {
416 if (d->term.isNull()) {
417 d->sessionInternal()->sendData(d->contents[d->nextContent]);
419 qCWarning(KIMAP2_LOG) <<
"The term API only supports inline strings.";
422 }
else if (response.content.size() >= 2 && response.content[1].toString() ==
"SEARCH") {
423 for (
int i = 2; i < response.content.size(); i++) {
424 d->results.append(response.content[i].toString().toInt());
430void SearchJob::setCharset(
const QByteArray &charset)
433 d->charset = charset;
438 Q_D(
const SearchJob);
442void SearchJob::setUidBased(
bool uidBased)
445 d->uidBased = uidBased;
448bool SearchJob::isUidBased()
const
450 Q_D(
const SearchJob);
456 Q_D(
const SearchJob);
Represents a set of natural numbers (1->∞) in a as compact as possible form.
void optimize()
Optimizes the ImapSet by sorting and merging overlapping intervals.
AKONADI_MIME_EXPORT const char Answered[]
AKONADI_MIME_EXPORT const char Seen[]
AKONADI_MIME_EXPORT const char Deleted[]
AKONADI_MIME_EXPORT const char Flagged[]
AKONADI_MIME_EXPORT const char Body[]
QString name(StandardAction id)
char at(qsizetype i) const const
const char * constData() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
QByteArray number(double n, char format, int precision)
qsizetype size() const const
bool startsWith(QByteArrayView bv) const const
bool isEmpty() const const
qsizetype size() const const
QByteArray toUtf8() const const