1 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "Common/InvokeMethod.h"
25 #include "Imap/Model/Model.h"
26 #include "Imap/Model/TaskPresentationModel.h"
27 #include "KeepMailboxOpenTask.h"
34 ImapTask::ImapTask(Model
*model
) :
35 QObject(model
), parser(0), parentTask(0), model(model
), _finished(false), _dead(false), _aborted(false)
37 connect(this, &QObject::destroyed
, model
, &Model::slotTaskDying
);
45 /** @short Schedule another task to get a go when this one completes
47 This function informs the current task (this) that when it terminates successfully, the dependant task (@arg task) shall be started.
48 Subclasses are free to reimplement this method (@see KeepMailboxOpenTask), but they must not forget to update the parentTask of
51 void ImapTask::addDependentTask(ImapTask
*task
)
55 dependentTasks
.append(task
);
56 task
->updateParentTask(this);
60 /** @short Set this task's parent to the specified value */
61 void ImapTask::updateParentTask(ImapTask
*newParent
)
63 Q_ASSERT(!parentTask
);
65 parentTask
= newParent
;
67 model
->m_taskModel
->slotTaskGotReparented(this);
69 Q_ASSERT(!model
->accessParser(parser
).activeTasks
.contains(this));
70 //log(tr("Reparented to %1").arg(newParent->debugIdentification()));
75 /** @short Tells the Model that we're from now on an active task */
76 void ImapTask::markAsActiveTask(const TaskActivatingPosition place
)
82 model
->accessParser(parser
).activeTasks
.append(this);
85 model
->accessParser(parser
).activeTasks
.prepend(this);
89 parentTask
->dependentTasks
.removeAll(this);
91 // As we're an active task, we no longer have a parent task
93 model
->m_taskModel
->slotTaskGotReparented(this);
95 if (model
->accessParser(parser
).maintainingTask
&& model
->accessParser(parser
).maintainingTask
!= this) {
96 // Got to inform the currently responsible maintaining task about our demise
97 connect(this, &QObject::destroyed
, model
->accessParser(parser
).maintainingTask
.data(), &KeepMailboxOpenTask::slotTaskDeleted
);
100 log(QStringLiteral("Activated"));
104 bool ImapTask::handleState(const Imap::Responses::State
*const resp
)
106 handleResponseCode(resp
);
107 return handleStateHelper(resp
);
110 bool ImapTask::handleStateHelper(const Imap::Responses::State
*const resp
)
116 bool ImapTask::handleCapability(const Imap::Responses::Capability
*const resp
)
122 bool ImapTask::handleNumberResponse(const Imap::Responses::NumberResponse
*const resp
)
128 bool ImapTask::handleList(const Imap::Responses::List
*const resp
)
134 bool ImapTask::handleFlags(const Imap::Responses::Flags
*const resp
)
140 bool ImapTask::handleSearch(const Imap::Responses::Search
*const resp
)
146 bool ImapTask::handleESearch(const Imap::Responses::ESearch
*const resp
)
152 bool ImapTask::handleStatus(const Imap::Responses::Status
*const resp
)
158 bool ImapTask::handleFetch(const Imap::Responses::Fetch
*const resp
)
164 bool ImapTask::handleNamespace(const Imap::Responses::Namespace
*const resp
)
170 bool ImapTask::handleSort(const Imap::Responses::Sort
*const resp
)
176 bool ImapTask::handleThread(const Imap::Responses::Thread
*const resp
)
182 bool ImapTask::handleId(const Responses::Id
*const resp
)
188 bool ImapTask::handleEnabled(const Responses::Enabled
*const resp
)
194 bool ImapTask::handleVanished(const Responses::Vanished
*const resp
)
200 bool ImapTask::handleGenUrlAuth(const Responses::GenUrlAuth
*const resp
)
206 bool ImapTask::handleSocketEncryptedResponse(const Imap::Responses::SocketEncryptedResponse
*const resp
)
212 bool ImapTask::handleSocketDisconnectedResponse(const Imap::Responses::SocketDisconnectedResponse
*const resp
)
218 bool ImapTask::handleParseErrorResponse(const Imap::Responses::ParseErrorResponse
*const resp
)
224 void ImapTask::_completed()
227 log(QStringLiteral("Completed"));
228 Q_FOREACH(ImapTask
* task
, dependentTasks
) {
229 if (!task
->isFinished())
232 emit
completed(this);
235 void ImapTask::_failed(const QString
&errorMessage
)
238 killAllPendingTasks(errorMessage
);
239 log(QString::fromUtf8("Failed: %1").arg(errorMessage
));
240 emit
failed(errorMessage
);
243 void ImapTask::killAllPendingTasks(const QString
&message
)
245 Q_FOREACH(ImapTask
*task
, dependentTasks
) {
250 void ImapTask::handleResponseCode(const Imap::Responses::State
*const resp
)
252 using namespace Imap::Responses
;
253 // Check for common stuff like ALERT and CAPABILITIES update
254 switch (resp
->respCode
) {
256 EMIT_LATER(model
, alertReceived
, Q_ARG(QString
, tr("The server sent the following ALERT:\n%1").arg(resp
->message
)));
260 const RespData
<QStringList
> *const caps
= dynamic_cast<const RespData
<QStringList
>* const>(resp
->respCodeData
.data());
262 model
->updateCapabilities(parser
, caps
->data
);
268 qDebug() << "The server was having troubles with parsing message data:" << resp
->message
;
271 // do nothing here, it must be handled later
276 bool ImapTask::isReadyToRun() const
281 void ImapTask::die(const QString
&message
)
288 void ImapTask::abort()
291 Q_FOREACH(ImapTask
* task
, dependentTasks
) {
296 QString
ImapTask::debugIdentification() const
301 void ImapTask::log(const QString
&message
, const Common::LogKind kind
)
304 QString dbg
= debugIdentification();
305 if (!dbg
.isEmpty()) {
306 dbg
.prepend(QLatin1Char(' '));
308 model
->logTrace(parser
? parser
->parserId() : 0, kind
, QString::fromUtf8(metaObject()->className()) + dbg
, message
);
309 model
->m_taskModel
->slotTaskMighHaveChanged(this);