File indexing completed on 2025-01-05 04:49:51

0001 /*
0002    SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "selectimaploadfoldersjob.h"
0008 #include "imapfoldercompletionplugin_debug.h"
0009 #include "sessionuiproxy.h"
0010 #include <KIMAP/LoginJob>
0011 #include <KIMAP/Session>
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 #include <QStandardItemModel>
0015 
0016 SelectImapLoadFoldersJob::SelectImapLoadFoldersJob(QStandardItemModel *model, QObject *parent)
0017     : QObject(parent)
0018     , mModel(model)
0019 {
0020 }
0021 
0022 SelectImapLoadFoldersJob::~SelectImapLoadFoldersJob() = default;
0023 
0024 void SelectImapLoadFoldersJob::start()
0025 {
0026     if (mModel && mSieveImapAccount.isValid()) {
0027         mSession = new KIMAP::Session(mSieveImapAccount.serverName(), mSieveImapAccount.port(), this);
0028         mSession->setUiProxy(SessionUiProxy::Ptr(new SessionUiProxy));
0029 
0030         auto login = new KIMAP::LoginJob(mSession);
0031         login->setUserName(mSieveImapAccount.userName());
0032         login->setPassword(mSieveImapAccount.password());
0033         login->setAuthenticationMode(static_cast<KIMAP::LoginJob::AuthenticationMode>(mSieveImapAccount.authenticationType()));
0034         login->setEncryptionMode(static_cast<KIMAP::LoginJob::EncryptionMode>(mSieveImapAccount.encryptionMode()));
0035         connect(login, &KIMAP::LoginJob::result, this, &SelectImapLoadFoldersJob::slotLoginDone);
0036         login->start();
0037     } else {
0038         qCWarning(IMAPFOLDERCOMPLETIONPLUGIN_LOG) << "SieveImapAccountSettings invalid";
0039         Q_EMIT finished(false, mModel);
0040         deleteLater();
0041     }
0042 }
0043 
0044 void SelectImapLoadFoldersJob::setSieveImapAccountSettings(const KSieveCore::SieveImapAccountSettings &account)
0045 {
0046 #if 0
0047     qDebug() << " void SelectImapFolderWidget::setSieveImapAccountSettings(const KSieveUi::SieveImapAccountSettings &account)" << account.serverName()
0048              << " port : " << account.port()
0049              << " password :" << account.password()
0050              << "authentication :" << account.authenticationType()
0051              << "encryption : " << account.encryptionMode();
0052 #endif
0053     mSieveImapAccount = account;
0054 }
0055 
0056 void SelectImapLoadFoldersJob::slotLoginDone(KJob *job)
0057 {
0058     if (!job->error()) {
0059         slotReloadRequested();
0060     } else {
0061         Q_EMIT finished(false, mModel);
0062         deleteLater();
0063     }
0064 }
0065 
0066 void SelectImapLoadFoldersJob::slotReloadRequested()
0067 {
0068     mItemsMap.clear();
0069     mModel->clear();
0070 
0071     if (!mSession || mSession->state() != KIMAP::Session::Authenticated) {
0072         qCWarning(IMAPFOLDERCOMPLETIONPLUGIN_LOG) << "SelectImapLoadFoldersJob - got no connection";
0073         Q_EMIT finished(false, mModel);
0074         deleteLater();
0075         return;
0076     }
0077 
0078     auto list = new KIMAP::ListJob(mSession);
0079     list->setOption(KIMAP::ListJob::IncludeUnsubscribed);
0080     connect(list, &KIMAP::ListJob::mailBoxesReceived, this, &SelectImapLoadFoldersJob::slotMailBoxesReceived);
0081     connect(list, &KIMAP::ListJob::result, this, &SelectImapLoadFoldersJob::slotFullListingDone);
0082     list->start();
0083 }
0084 
0085 void SelectImapLoadFoldersJob::slotMailBoxesReceived(const QList<KIMAP::MailBoxDescriptor> &mailBoxes, const QList<QList<QByteArray>> &flags)
0086 {
0087     const int numberOfMailBoxes(mailBoxes.size());
0088     for (int i = 0; i < numberOfMailBoxes; i++) {
0089         KIMAP::MailBoxDescriptor mailBox = mailBoxes[i];
0090 
0091         const QStringList pathParts = mailBox.name.split(mailBox.separator);
0092         const QString separator = mailBox.separator;
0093         Q_ASSERT(separator.size() == 1); // that's what the spec says
0094 
0095         QString parentPath;
0096         QString currentPath;
0097         for (int j = 0; j < pathParts.size(); ++j) {
0098             const QString pathPart = pathParts.at(j);
0099             currentPath += separator + pathPart;
0100             const bool isSelectable = !flags[i].contains("\\noselect");
0101             if (mItemsMap.contains(currentPath)) {
0102                 // nothing
0103             } else if (!parentPath.isEmpty()) {
0104                 Q_ASSERT(mItemsMap.contains(parentPath));
0105 
0106                 QStandardItem *parentItem = mItemsMap[parentPath];
0107 
0108                 auto item = new QStandardItem(pathPart);
0109                 Qt::ItemFlags itemflags = Qt::ItemIsEnabled;
0110                 if (isSelectable) {
0111                     itemflags |= Qt::ItemIsSelectable;
0112                 }
0113                 item->setFlags(itemflags);
0114                 item->setData(currentPath.mid(1), PathRole);
0115                 parentItem->appendRow(item);
0116                 mItemsMap[currentPath] = item;
0117             } else {
0118                 auto item = new QStandardItem(pathPart);
0119                 Qt::ItemFlags itemflags = Qt::ItemIsEnabled;
0120                 if (isSelectable) {
0121                     itemflags |= Qt::ItemIsSelectable;
0122                 }
0123                 item->setFlags(itemflags);
0124                 item->setData(currentPath.mid(1), PathRole);
0125                 mModel->appendRow(item);
0126                 mItemsMap[currentPath] = item;
0127             }
0128 
0129             parentPath = currentPath;
0130         }
0131     }
0132 }
0133 
0134 void SelectImapLoadFoldersJob::slotFullListingDone(KJob *job)
0135 {
0136     if (job->error()) {
0137         KMessageBox::error(nullptr, i18n("Error during loading folders: %1", job->errorString()), i18nc("@title:window", "Load Folders"));
0138         qCWarning(IMAPFOLDERCOMPLETIONPLUGIN_LOG) << "Error during full listing : " << job->errorString();
0139         Q_EMIT finished(false, mModel);
0140     } else {
0141         Q_EMIT finished(true, mModel);
0142     }
0143     deleteLater();
0144 }
0145 
0146 #include "moc_selectimaploadfoldersjob.cpp"