File indexing completed on 2024-06-23 05:21:16

0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
0002 
0003    This file is part of the Trojita Qt IMAP e-mail client,
0004    http://trojita.flaska.net/
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public License as
0008    published by the Free Software Foundation; either version 2 of
0009    the License or (at your option) version 3 or any later version
0010    accepted by the membership of KDE e.V. (or its successor approved
0011    by the membership of KDE e.V.), which shall act as a proxy
0012    defined in Section 14 of version 3 of the license.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    You should have received a copy of the GNU General Public License
0020    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 
0024 #include "ThreadTask.h"
0025 #include "Imap/Model/ItemRoles.h"
0026 #include "Imap/Model/Model.h"
0027 #include "Imap/Model/MailboxTree.h"
0028 #include "KeepMailboxOpenTask.h"
0029 
0030 namespace Imap
0031 {
0032 namespace Mailbox
0033 {
0034 
0035 
0036 ThreadTask::ThreadTask(Model *model, const QModelIndex &mailbox, const QByteArray &algorithm, const QStringList &searchCriteria,
0037                        const ThreadingIncrementalMode incrementalMode):
0038     ImapTask(model), mailboxIndex(mailbox), algorithm(algorithm), searchCriteria(searchCriteria),
0039     m_incrementalMode(incrementalMode == THREADING_INCREMENTAL)
0040 {
0041     conn = model->findTaskResponsibleFor(mailbox);
0042     conn->addDependentTask(this);
0043 }
0044 
0045 void ThreadTask::perform()
0046 {
0047     parser = conn->parser;
0048     markAsActiveTask();
0049 
0050     IMAP_TASK_CHECK_ABORT_DIE;
0051 
0052     if (! mailboxIndex.isValid()) {
0053         _failed(tr("Mailbox vanished before we could ask for threading info"));
0054         return;
0055     }
0056 
0057     if (m_incrementalMode) {
0058         tag = parser->uidEThread(algorithm, "utf-8", searchCriteria, QStringList() << QStringLiteral("INCTHREAD"));
0059     } else {
0060         tag = parser->uidThread(algorithm, "utf-8", searchCriteria);
0061     }
0062 }
0063 
0064 bool ThreadTask::handleStateHelper(const Imap::Responses::State *const resp)
0065 {
0066     if (resp->tag.isEmpty())
0067         return false;
0068 
0069     if (resp->tag == tag) {
0070         if (resp->kind == Responses::OK) {
0071             if (!m_incrementalMode)
0072                 emit model->threadingAvailable(mailboxIndex, algorithm, searchCriteria, mapping);
0073             _completed();
0074         } else {
0075             _failed(tr("Threading command has failed"));
0076         }
0077         mapping.clear();
0078         return true;
0079     } else {
0080         return false;
0081     }
0082 }
0083 
0084 bool ThreadTask::handleThread(const Imap::Responses::Thread *const resp)
0085 {
0086     mapping = resp->rootItems;
0087     return true;
0088 }
0089 
0090 bool ThreadTask::handleESearch(const Responses::ESearch *const resp)
0091 {
0092     if (resp->tag != tag)
0093         return false;
0094 
0095     if (resp->seqOrUids != Imap::Responses::ESearch::UIDS)
0096         throw UnexpectedResponseReceived("ESEARCH response to a UID THREAD command with matching tag uses "
0097                                          "sequence numbers instead of UIDs", *resp);
0098 
0099     if (m_incrementalMode) {
0100         emit incrementalThreadingAvailable(resp->incThreadData);
0101         return true;
0102     }
0103 
0104     throw UnexpectedResponseReceived("ESEARCH response to UID THREAD received outside of the incremental mode");
0105 }
0106 
0107 QVariant ThreadTask::taskData(const int role) const
0108 {
0109     return role == RoleTaskCompactName ? QVariant(tr("Fetching conversations")) : QVariant();
0110 }
0111 
0112 void ThreadTask::_failed(const QString &errorMessage)
0113 {
0114     // FIXME: show this in the GUI
0115     emit model->threadingFailed(mailboxIndex, algorithm, searchCriteria);
0116     ImapTask::_failed(errorMessage);
0117 }
0118 
0119 }
0120 }