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

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 #include "GetAnyConnectionTask.h"
0024 #include <QTimer>
0025 #include "Imap/Model/MailboxTree.h"
0026 #include "KeepMailboxOpenTask.h"
0027 #include "OfflineConnectionTask.h"
0028 #include "OpenConnectionTask.h"
0029 
0030 namespace Imap
0031 {
0032 namespace Mailbox
0033 {
0034 
0035 GetAnyConnectionTask::GetAnyConnectionTask(Model *model) :
0036     ImapTask(model), newConn(0)
0037 {
0038     QMap<Parser *,ParserState>::iterator it = model->m_parsers.begin();
0039     while (it != model->m_parsers.end()) {
0040         if (it->connState == CONN_STATE_LOGOUT) {
0041             // We cannot possibly use this connection
0042             ++it;
0043         } else {
0044             // we've found it
0045             break;
0046         }
0047     }
0048 
0049     if (it == model->m_parsers.end()) {
0050         // We're creating a completely new connection
0051         if (model->networkPolicy() == NETWORK_OFFLINE) {
0052             // ...but we're offline -> too bad, got to fail
0053             newConn = new OfflineConnectionTask(model);
0054             newConn->addDependentTask(this);
0055         } else {
0056             newConn = model->m_taskFactory->createOpenConnectionTask(model);
0057             newConn->addDependentTask(this);
0058         }
0059     } else {
0060         parser = it.key();
0061         Q_ASSERT(parser);
0062 
0063         if (it->maintainingTask) {
0064             // The parser already has some maintaining task associated with it
0065             // We can't ignore the maintaining task, if only because of the IDLE
0066             newConn = it->maintainingTask;
0067             newConn->addDependentTask(this);
0068         } else {
0069             if (!it->activeTasks.isEmpty() && dynamic_cast<OpenConnectionTask*>(it->activeTasks.front()) &&
0070                    !it->activeTasks.front()->isFinished()) {
0071                 // The conneciton is still being set up so we cannot just jump to the middle of OpenConnectionTask's
0072                 // process (Redmine #499).
0073                 it->activeTasks.front()->addDependentTask(this);
0074             } else {
0075                 // The parser doesn't have anything associated with it and it looks like
0076                 // the conneciton is already established, authenticated and what not.
0077                 // This means that we can go ahead and register ourselves as an active task, yay!
0078                 markAsActiveTask();
0079                 QTimer::singleShot(0, model, SLOT(runReadyTasks()));
0080             }
0081         }
0082     }
0083 }
0084 
0085 void GetAnyConnectionTask::perform()
0086 {
0087     // This is special from most ImapTasks' perform(), because the activeTasks could have already been updated
0088     if (newConn) {
0089         // We're "dependent" on some connection, so we should update our parser (even though
0090         // it could be already set), and also register ourselves with the Model
0091         parser = newConn->parser;
0092         markAsActiveTask();
0093     }
0094 
0095     IMAP_TASK_CHECK_ABORT_DIE;
0096 
0097     // ... we don't really have to do any work here, just declare ourselves completed
0098     _completed();
0099 }
0100 
0101 bool GetAnyConnectionTask::isReadyToRun() const
0102 {
0103     return ! isFinished() && ! newConn;
0104 }
0105 
0106 /** @short This is an internal task, calling this function does not make much sense */
0107 QVariant GetAnyConnectionTask::taskData(const int role) const
0108 {
0109     Q_UNUSED(role);
0110     return QVariant();
0111 }
0112 
0113 }
0114 }