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 | |
18 | using namespace KIO; |
19 | |
20 | QString 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 | |
33 | UserNotificationHandler::UserNotificationHandler(QObject *parent) |
34 | : QObject(parent) |
35 | { |
36 | } |
37 | |
38 | UserNotificationHandler::~UserNotificationHandler() |
39 | { |
40 | qDeleteAll(c: m_pendingRequests); |
41 | } |
42 | |
43 | void 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 | |
56 | void 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 | |
115 | void 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 | |
130 | void 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 | |