File indexing completed on 2024-07-14 03:54:00

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2012 Dawit Alemayehu <adawit@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include "askuseractioninterface.h"
0009 #include "usernotificationhandler_p.h"
0010 
0011 #include "job_p.h"
0012 #include "kiocoredebug.h"
0013 #include "worker_p.h"
0014 #include "workerbase.h"
0015 
0016 #include <QTimer>
0017 
0018 using namespace KIO;
0019 
0020 QString UserNotificationHandler::Request::key() const
0021 {
0022     QString key;
0023     if (worker) {
0024         key = worker->protocol();
0025         key += worker->host();
0026         key += worker->port();
0027         key += QLatin1Char('-');
0028         key += QChar(type);
0029     }
0030     return key;
0031 }
0032 
0033 UserNotificationHandler::UserNotificationHandler(QObject *parent)
0034     : QObject(parent)
0035 {
0036 }
0037 
0038 UserNotificationHandler::~UserNotificationHandler()
0039 {
0040     qDeleteAll(m_pendingRequests);
0041 }
0042 
0043 void UserNotificationHandler::requestMessageBox(WorkerInterface *iface, int type, const QHash<MessageBoxDataType, QVariant> &data)
0044 {
0045     Request *r = new Request;
0046     r->type = type;
0047     r->worker = qobject_cast<KIO::Worker *>(iface);
0048     r->data = data;
0049 
0050     m_pendingRequests.append(r);
0051     if (m_pendingRequests.count() == 1) {
0052         QTimer::singleShot(0, this, &UserNotificationHandler::processRequest);
0053     }
0054 }
0055 
0056 void UserNotificationHandler::processRequest()
0057 {
0058     if (m_pendingRequests.isEmpty()) {
0059         return;
0060     }
0061 
0062     int result = -1;
0063     Request *r = m_pendingRequests.first();
0064 
0065     if (r->worker) {
0066         const QString key = r->key();
0067 
0068         if (m_cachedResults.contains(key)) {
0069             result = *(m_cachedResults[key]);
0070         } else {
0071             KIO::SimpleJob *job = r->worker->job();
0072             AskUserActionInterface *askUserIface = job ? KIO::delegateExtension<KIO::AskUserActionInterface *>(job) : nullptr;
0073 
0074             if (askUserIface) {
0075                 connect(askUserIface, &AskUserActionInterface::messageBoxResult, this, &UserNotificationHandler::slotProcessRequest, Qt::UniqueConnection);
0076 
0077                 const auto type = [r]() -> AskUserActionInterface::MessageDialogType {
0078                     switch (r->type) {
0079                     case WorkerBase::QuestionTwoActions:
0080                         return AskUserActionInterface::QuestionTwoActions;
0081                     case WorkerBase::WarningTwoActions:
0082                         return AskUserActionInterface::WarningTwoActions;
0083                     case WorkerBase::WarningContinueCancel:
0084                     case WorkerBase::WarningContinueCancelDetailed:
0085                         return AskUserActionInterface::WarningContinueCancel;
0086                     case WorkerBase::WarningTwoActionsCancel:
0087                         return AskUserActionInterface::WarningTwoActionsCancel;
0088                     case WorkerBase::Information:
0089                         return AskUserActionInterface::Information;
0090                     default:
0091                         Q_UNREACHABLE();
0092                         return AskUserActionInterface::MessageDialogType{};
0093                     }
0094                 }();
0095 
0096                 askUserIface->requestUserMessageBox(type,
0097                                                     r->data.value(MSG_TEXT).toString(),
0098                                                     r->data.value(MSG_TITLE).toString(),
0099                                                     r->data.value(MSG_PRIMARYACTION_TEXT).toString(),
0100                                                     r->data.value(MSG_SECONDARYACTION_TEXT).toString(),
0101                                                     r->data.value(MSG_PRIMARYACTION_ICON).toString(),
0102                                                     r->data.value(MSG_SECONDARYACTION_ICON).toString(),
0103                                                     r->data.value(MSG_DONT_ASK_AGAIN).toString(),
0104                                                     r->data.value(MSG_DETAILS).toString());
0105                 return;
0106             }
0107         }
0108     } else {
0109         qCWarning(KIO_CORE) << "Cannot prompt user because the requesting KIO worker died!" << r->worker;
0110     }
0111 
0112     slotProcessRequest(result);
0113 }
0114 
0115 void UserNotificationHandler::slotProcessRequest(int result)
0116 {
0117     Request *request = m_pendingRequests.takeFirst();
0118     m_cachedResults.insert(request->key(), new int(result));
0119 
0120     request->worker->sendMessageBoxAnswer(result);
0121     delete request;
0122 
0123     if (m_pendingRequests.isEmpty()) {
0124         m_cachedResults.clear();
0125     } else {
0126         processRequest();
0127     }
0128 }
0129 
0130 void UserNotificationHandler::sslError(WorkerInterface *iface, const QVariantMap &sslErrorData)
0131 {
0132     KIO::SimpleJob *job = qobject_cast<KIO::Worker *>(iface)->job();
0133     AskUserActionInterface *askUserIface = job ? KIO::delegateExtension<KIO::AskUserActionInterface *>(job) : nullptr;
0134 
0135     if (askUserIface) {
0136         askUserIface->askIgnoreSslErrors(sslErrorData, nullptr);
0137 
0138         connect(askUserIface, &AskUserActionInterface::askIgnoreSslErrorsResult, this, [iface](int result) {
0139             iface->sendSslErrorAnswer(result);
0140         });
0141     }
0142 }
0143 #include "moc_usernotificationhandler_p.cpp"