9#include "kimap_debug.h"
13#include "response_p.h"
17#include <KLocalizedString>
24class SelectJobPrivate :
public JobPrivate
27 SelectJobPrivate(SelectJob *q,
Session *session,
const QString &name)
28 : JobPrivate(session,
name)
38 if (pendingMessages.
empty()) {
42 Q_EMIT q->modified(pendingMessages);
43 pendingMessages.
clear();
47 bool readOnly =
false;
54 int messageCount = -1;
56 int firstUnseenIndex = -1;
57 qint64 uidValidity = -1;
59 quint64 highestmodseq = 0;
60 qint64 lastUidvalidity = -1;
61 quint64 lastModseq = 0;
64 bool condstoreEnabled =
false;
72SelectJob::SelectJob(
Session *session)
73 : Job(*new SelectJobPrivate(this, session,
i18nc(
"name of the select job",
"Select")))
77SelectJob::~SelectJob()
81void SelectJob::setMailBox(
const QString &mailBox)
87QString SelectJob::mailBox()
const
93void SelectJob::setOpenReadOnly(
bool readOnly)
96 d->readOnly = readOnly;
99bool SelectJob::isOpenReadOnly()
const
101 Q_D(
const SelectJob);
107 Q_D(
const SelectJob);
113 Q_D(
const SelectJob);
114 return d->permanentFlags;
117int SelectJob::messageCount()
const
119 Q_D(
const SelectJob);
120 return d->messageCount;
123int SelectJob::recentCount()
const
125 Q_D(
const SelectJob);
126 return d->recentCount;
129int SelectJob::firstUnseenIndex()
const
131 Q_D(
const SelectJob);
132 return d->firstUnseenIndex;
135qint64 SelectJob::uidValidity()
const
137 Q_D(
const SelectJob);
138 return d->uidValidity;
141qint64 SelectJob::nextUid()
const
143 Q_D(
const SelectJob);
147quint64 SelectJob::highestModSequence()
const
149 Q_D(
const SelectJob);
150 return d->highestmodseq;
153void SelectJob::setCondstoreEnabled(
bool enable)
156 d->condstoreEnabled = enable;
159bool SelectJob::condstoreEnabled()
const
161 Q_D(
const SelectJob);
162 return d->condstoreEnabled;
165void SelectJob::setQResync(qint64 lastUidvalidity, quint64 lastModseq,
const ImapSet &knownUids)
168 d->lastUidvalidity = lastUidvalidity;
169 d->lastModseq = lastModseq;
170 d->knownUids = knownUids;
171 setCondstoreEnabled(
true);
174void SelectJob::doStart()
185 if (d->condstoreEnabled) {
187 if (d->lastUidvalidity == -1 && d->lastModseq == 0) {
188 params +=
" (CONDSTORE)";
191 if (!d->knownUids.isEmpty()) {
192 params +=
" " + d->knownUids.toImapSequenceSet();
198 d->emitPendingsTimer.start(100);
199 d->tags << d->sessionInternal()->sendCommand(command, params);
202void SelectJob::handleResponse(
const Response &response)
209 if (!response.content.isEmpty() && d->tags.contains(response.content.first().toString())) {
210 if (response.responseCode.size() >= 1 && response.responseCode[0].toString() ==
"READ-ONLY") {
217 if (!response.content.isEmpty() && d->tags.size() == 1 && d->tags.contains(response.content.first().toString())) {
218 d->emitPendingsTimer.stop();
222 if (handleErrorReplies(response) == NotHandled) {
223 if (response.content.size() >= 2) {
224 QByteArray code = response.content[1].toString();
227 if (response.responseCode.size() < 2) {
231 code = response.responseCode[0].toString();
232 if (code ==
"PERMANENTFLAGS") {
233 d->permanentFlags = response.responseCode[1].toList();
234 }
else if (code ==
"HIGHESTMODSEQ") {
236 quint64 value = response.responseCode[1].toString().toULongLong(&isInt);
240 d->highestmodseq = value;
243 qint64 value = response.responseCode[1].toString().toLongLong(&isInt);
247 if (code ==
"UIDVALIDITY") {
248 d->uidValidity = value;
249 }
else if (code ==
"UNSEEN") {
250 d->firstUnseenIndex = value;
251 }
else if (code ==
"UIDNEXT") {
255 }
else if (code ==
"FLAGS") {
256 d->flags = response.content[2].toList();
257 }
else if (code ==
"VANISHED" && response.content.size() == 4) {
259 Q_EMIT vanished(vanishedSet);
262 int value = response.content[1].toString().toInt(&isInt);
263 if (!isInt || response.content.size() < 3) {
267 code = response.content[2].toString();
268 if (code ==
"FETCH") {
270 const auto content = response.content[3].toList();
271 for (
auto it = content.cbegin(), end = content.cend(); it != end; ++it) {
272 const auto name = *it;
275 if (it == content.constEnd()) {
276 qCWarning(KIMAP_LOG) <<
"SELECT reply got truncated, skipping.";
281 msg.uid = it->toLongLong();
282 }
else if (name ==
"FLAGS") {
283 if ((*it).startsWith(
'(') && (*it).endsWith(
')')) {
287 const auto flags = str.
split(
' ');
292 }
else if (name ==
"MODSEQ") {
303 d->pendingMessages.insert(value, msg);
304 }
else if (code ==
"EXISTS") {
305 d->messageCount = value;
306 }
else if (code ==
"RECENT") {
307 d->recentCount = value;
311 qCDebug(KIMAP_LOG) << response.toString();
314 Q_ASSERT(
error() || d->m_session->selectedMailBox() == d->mailBox);
318#include "moc_selectjob.cpp"
Represents a set of natural numbers (1->∞) in a as compact as possible form.
static ImapSet fromImapSequenceSet(const QByteArray &sequence)
Return the set corresponding to the given IMAP-compatible QByteArray representation.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString name(StandardAction id)
bool endsWith(QByteArrayView bv) const const
QByteArray & insert(qsizetype i, QByteArrayView data)
QByteArray number(double n, char format, int precision)
QByteArray & remove(qsizetype pos, qsizetype len)
QList< QByteArray > split(char sep) const const
bool startsWith(QByteArrayView bv) const const
qulonglong toULongLong(bool *ok, int base) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
This file is part of the IMAP support library and defines the RfcCodecs class.
KIMAP_EXPORT QByteArray encodeImapFolderName(const QByteArray &src)
Converts an Unicode IMAP mailbox to a QByteArray which can be used in IMAP communication.