1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2012 Dawit Alemayehu <adawit@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "askuseractioninterface.h"
9#include "usernotificationhandler_p.h"
10
11#include "job_p.h"
12#include "kiocoredebug.h"
13#include "worker_p.h"
14#include "workerbase.h"
15
16#include <QTimer>
17
18using namespace KIO;
19
20QString UserNotificationHandler::Request::key() const
21{
22 QString key;
23 if (worker) {
24 key = worker->protocol();
25 key += worker->host();
26 key += worker->port();
27 key += QLatin1Char('-');
28 key += QChar(type);
29 }
30 return key;
31}
32
33UserNotificationHandler::UserNotificationHandler(QObject *parent)
34 : QObject(parent)
35{
36}
37
38UserNotificationHandler::~UserNotificationHandler()
39{
40 qDeleteAll(c: m_pendingRequests);
41}
42
43void UserNotificationHandler::requestMessageBox(WorkerInterface *iface, int type, const QHash<MessageBoxDataType, QVariant> &data)
44{
45 Request *r = new Request;
46 r->type = type;
47 r->worker = qobject_cast<KIO::Worker *>(object: iface);
48 r->data = data;
49
50 m_pendingRequests.append(t: r);
51 if (m_pendingRequests.count() == 1) {
52 QTimer::singleShot(interval: 0, receiver: this, slot: &UserNotificationHandler::processRequest);
53 }
54}
55
56void UserNotificationHandler::processRequest()
57{
58 if (m_pendingRequests.isEmpty()) {
59 return;
60 }
61
62 int result = -1;
63 Request *r = m_pendingRequests.first();
64
65 if (r->worker) {
66 const QString key = r->key();
67
68 if (m_cachedResults.contains(key)) {
69 result = *(m_cachedResults[key]);
70 } else {
71 KIO::SimpleJob *job = r->worker->job();
72 AskUserActionInterface *askUserIface = job ? KIO::delegateExtension<KIO::AskUserActionInterface *>(job) : nullptr;
73
74 if (askUserIface) {
75 connect(sender: askUserIface, signal: &AskUserActionInterface::messageBoxResult, context: this, slot: &UserNotificationHandler::slotProcessRequest, type: Qt::UniqueConnection);
76
77 const auto type = [r]() -> AskUserActionInterface::MessageDialogType {
78 switch (r->type) {
79 case WorkerBase::QuestionTwoActions:
80 return AskUserActionInterface::QuestionTwoActions;
81 case WorkerBase::WarningTwoActions:
82 return AskUserActionInterface::WarningTwoActions;
83 case WorkerBase::WarningContinueCancel:
84 case WorkerBase::WarningContinueCancelDetailed:
85 return AskUserActionInterface::WarningContinueCancel;
86 case WorkerBase::WarningTwoActionsCancel:
87 return AskUserActionInterface::WarningTwoActionsCancel;
88 case WorkerBase::Information:
89 return AskUserActionInterface::Information;
90 default:
91 Q_UNREACHABLE();
92 return AskUserActionInterface::MessageDialogType{};
93 }
94 }();
95
96 askUserIface->requestUserMessageBox(type,
97 text: r->data.value(key: MSG_TEXT).toString(),
98 title: r->data.value(key: MSG_TITLE).toString(),
99 primaryActionText: r->data.value(key: MSG_PRIMARYACTION_TEXT).toString(),
100 secondatyActionText: r->data.value(key: MSG_SECONDARYACTION_TEXT).toString(),
101 primaryActionIconName: r->data.value(key: MSG_PRIMARYACTION_ICON).toString(),
102 secondatyActionIconName: r->data.value(key: MSG_SECONDARYACTION_ICON).toString(),
103 dontAskAgainName: r->data.value(key: MSG_DONT_ASK_AGAIN).toString(),
104 details: r->data.value(key: MSG_DETAILS).toString());
105 return;
106 }
107 }
108 } else {
109 qCWarning(KIO_CORE) << "Cannot prompt user because the requesting KIO worker died!" << r->worker;
110 }
111
112 slotProcessRequest(result);
113}
114
115void UserNotificationHandler::slotProcessRequest(int result)
116{
117 Request *request = m_pendingRequests.takeFirst();
118 m_cachedResults.insert(key: request->key(), object: new int(result));
119
120 request->worker->sendMessageBoxAnswer(result);
121 delete request;
122
123 if (m_pendingRequests.isEmpty()) {
124 m_cachedResults.clear();
125 } else {
126 processRequest();
127 }
128}
129
130void UserNotificationHandler::sslError(WorkerInterface *iface, const QVariantMap &sslErrorData)
131{
132 KIO::SimpleJob *job = qobject_cast<KIO::Worker *>(object: iface)->job();
133 AskUserActionInterface *askUserIface = job ? KIO::delegateExtension<KIO::AskUserActionInterface *>(job) : nullptr;
134
135 if (askUserIface) {
136 askUserIface->askIgnoreSslErrors(sslErrorData, parent: nullptr);
137
138 connect(sender: askUserIface, signal: &AskUserActionInterface::askIgnoreSslErrorsResult, context: this, slot: [iface](int result) {
139 iface->sendSslErrorAnswer(result);
140 });
141 }
142}
143#include "moc_usernotificationhandler_p.cpp"
144

source code of kio/src/core/usernotificationhandler.cpp