File indexing completed on 2024-05-05 16:13:28

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 "slave.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 (slave) {
0024         key = slave->protocol();
0025         key += slave->host();
0026         key += slave->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(SlaveInterface *iface, int type, const QHash<MessageBoxDataType, QVariant> &data)
0044 {
0045     Request *r = new Request;
0046     r->type = type;
0047     r->slave = qobject_cast<KIO::Slave *>(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->slave) {
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->slave->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                     case WorkerBase::SSLMessageBox:
0091                         return AskUserActionInterface::SSLMessageBox;
0092                     default:
0093                         Q_UNREACHABLE();
0094                         return AskUserActionInterface::MessageDialogType{};
0095                     }
0096                 }();
0097 
0098                 askUserIface->requestUserMessageBox(type,
0099                                                     r->data.value(MSG_TEXT).toString(),
0100                                                     r->data.value(MSG_TITLE).toString(),
0101                                                     r->data.value(MSG_PRIMARYACTION_TEXT).toString(),
0102                                                     r->data.value(MSG_SECONDARYACTION_TEXT).toString(),
0103                                                     r->data.value(MSG_PRIMARYACTION_ICON).toString(),
0104                                                     r->data.value(MSG_SECONDARYACTION_ICON).toString(),
0105                                                     r->data.value(MSG_DONT_ASK_AGAIN).toString(),
0106                                                     r->data.value(MSG_DETAILS).toString(),
0107                                                     r->data.value(MSG_META_DATA).toMap());
0108                 return;
0109             }
0110         }
0111     } else {
0112         qCWarning(KIO_CORE) << "Cannot prompt user because the requesting KIO worker died!" << r->slave;
0113     }
0114 
0115     slotProcessRequest(result);
0116 }
0117 
0118 void UserNotificationHandler::slotProcessRequest(int result)
0119 {
0120     Request *request = m_pendingRequests.takeFirst();
0121     m_cachedResults.insert(request->key(), new int(result));
0122 
0123     request->slave->sendMessageBoxAnswer(result);
0124     delete request;
0125 
0126     if (m_pendingRequests.isEmpty()) {
0127         m_cachedResults.clear();
0128     } else {
0129         processRequest();
0130     }
0131 }
0132 
0133 #include "moc_usernotificationhandler_p.cpp"