File indexing completed on 2023-09-24 04:09:30

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2020 Ahmad Samir <a.samirh78@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "widgetsaskuseractionhandler.h"
0009 
0010 #include <KConfig>
0011 #include <KConfigGroup>
0012 #include <KGuiItem>
0013 #include <KIO/WorkerBase>
0014 #include <KJob>
0015 #include <KJobWidgets>
0016 #include <KLocalizedString>
0017 #include <KMessageDialog>
0018 #include <KSharedConfig>
0019 #include <KSslInfoDialog>
0020 #include <KStandardGuiItem>
0021 #include <kio_widgets_debug.h>
0022 
0023 #include <QApplication>
0024 #include <QDialogButtonBox>
0025 #include <QRegularExpression>
0026 #include <QUrl>
0027 
0028 class KIO::WidgetsAskUserActionHandlerPrivate
0029 {
0030 public:
0031     explicit WidgetsAskUserActionHandlerPrivate(WidgetsAskUserActionHandler *qq)
0032         : q(qq)
0033     {
0034     }
0035 
0036     // Creates a KSslInfoDialog or falls back to a generic Information dialog
0037     void sslMessageBox(const QString &text, const KIO::MetaData &metaData, QWidget *parent);
0038 
0039     bool gotPersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type, const KConfigGroup &cg, const QString &dontAskAgainName);
0040     void savePersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type, KConfigGroup &cg, const QString &dontAskAgainName, int result);
0041 
0042     WidgetsAskUserActionHandler *const q;
0043     QWidget *m_parentWidget = nullptr;
0044 };
0045 
0046 bool KIO::WidgetsAskUserActionHandlerPrivate::gotPersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type,
0047                                                                      const KConfigGroup &cg,
0048                                                                      const QString &dontAskAgainName)
0049 {
0050     // storage values matching the logic of FrameworkIntegration's KMessageBoxDontAskAgainConfigStorage
0051     switch (type) {
0052     case KIO::AskUserActionInterface::QuestionTwoActions:
0053     case KIO::AskUserActionInterface::QuestionTwoActionsCancel:
0054     case KIO::AskUserActionInterface::WarningTwoActions:
0055     case KIO::AskUserActionInterface::WarningTwoActionsCancel: {
0056         // storage holds "true" if persistent reply is "Yes", "false" for persistent "No",
0057         // otherwise no persistent reply is present
0058         const QString value = cg.readEntry(dontAskAgainName, QString());
0059         if ((value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0) || (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0)) {
0060             Q_EMIT q->messageBoxResult(KIO::WorkerBase::PrimaryAction);
0061             return true;
0062         }
0063         if ((value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0) || (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0)) {
0064             Q_EMIT q->messageBoxResult(KIO::WorkerBase::SecondaryAction);
0065             return true;
0066         }
0067         break;
0068     }
0069     case KIO::AskUserActionInterface::WarningContinueCancel: {
0070         // storage holds "false" if persistent reply is "Continue"
0071         // otherwise no persistent reply is present
0072         const bool value = cg.readEntry(dontAskAgainName, true);
0073         if (value == false) {
0074             Q_EMIT q->messageBoxResult(KIO::WorkerBase::Continue);
0075             return true;
0076         }
0077         break;
0078     }
0079     default:
0080         break;
0081     }
0082 
0083     return false;
0084 }
0085 
0086 void KIO::WidgetsAskUserActionHandlerPrivate::savePersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type,
0087                                                                       KConfigGroup &cg,
0088                                                                       const QString &dontAskAgainName,
0089                                                                       int result)
0090 {
0091     // see gotPersistentUserReply for values stored and why
0092     switch (type) {
0093     case KIO::AskUserActionInterface::QuestionTwoActions:
0094     case KIO::AskUserActionInterface::QuestionTwoActionsCancel:
0095     case KIO::AskUserActionInterface::WarningTwoActions:
0096     case KIO::AskUserActionInterface::WarningTwoActionsCancel:
0097         cg.writeEntry(dontAskAgainName, result == KIO::WorkerBase::PrimaryAction);
0098         cg.sync();
0099         break;
0100     case KIO::AskUserActionInterface::WarningContinueCancel:
0101         cg.writeEntry(dontAskAgainName, false);
0102         cg.sync();
0103         break;
0104     default:
0105         break;
0106     }
0107 }
0108 
0109 KIO::WidgetsAskUserActionHandler::WidgetsAskUserActionHandler(QObject *parent)
0110     : KIO::AskUserActionInterface(parent)
0111     , d(new WidgetsAskUserActionHandlerPrivate(this))
0112 {
0113 }
0114 
0115 KIO::WidgetsAskUserActionHandler::~WidgetsAskUserActionHandler()
0116 {
0117 }
0118 
0119 void KIO::WidgetsAskUserActionHandler::askUserRename(KJob *job,
0120                                                      const QString &title,
0121                                                      const QUrl &src,
0122                                                      const QUrl &dest,
0123                                                      KIO::RenameDialog_Options options,
0124                                                      KIO::filesize_t sizeSrc,
0125                                                      KIO::filesize_t sizeDest,
0126                                                      const QDateTime &ctimeSrc,
0127                                                      const QDateTime &ctimeDest,
0128                                                      const QDateTime &mtimeSrc,
0129                                                      const QDateTime &mtimeDest)
0130 {
0131     QWidget *parentWidget = nullptr;
0132 
0133     if (job) {
0134         parentWidget = KJobWidgets::window(job);
0135     }
0136 
0137     if (!parentWidget) {
0138         parentWidget = d->m_parentWidget;
0139     }
0140 
0141     if (!parentWidget) {
0142         parentWidget = qApp->activeWindow();
0143     }
0144 
0145     QMetaObject::invokeMethod(qGuiApp, [=] {
0146         auto *dlg = new KIO::RenameDialog(parentWidget, title, src, dest, options, sizeSrc, sizeDest, ctimeSrc, ctimeDest, mtimeSrc, mtimeDest);
0147 
0148         dlg->setAttribute(Qt::WA_DeleteOnClose);
0149         dlg->setWindowModality(Qt::WindowModal);
0150 
0151         connect(job, &KJob::finished, dlg, &QDialog::reject);
0152         connect(dlg, &QDialog::finished, this, [this, job, dlg](const int exitCode) {
0153             KIO::RenameDialog_Result result = static_cast<RenameDialog_Result>(exitCode);
0154             const QUrl newUrl = result == Result_AutoRename ? dlg->autoDestUrl() : dlg->newDestUrl();
0155             Q_EMIT askUserRenameResult(result, newUrl, job);
0156         });
0157 
0158         dlg->show();
0159     });
0160 }
0161 
0162 void KIO::WidgetsAskUserActionHandler::askUserSkip(KJob *job, KIO::SkipDialog_Options options, const QString &errorText)
0163 {
0164     QWidget *parentWidget = nullptr;
0165 
0166     if (job) {
0167         parentWidget = KJobWidgets::window(job);
0168     }
0169 
0170     if (!parentWidget) {
0171         parentWidget = d->m_parentWidget;
0172     }
0173 
0174     if (!parentWidget) {
0175         parentWidget = qApp->activeWindow();
0176     }
0177 
0178     QMetaObject::invokeMethod(qGuiApp, [=] {
0179         auto *dlg = new KIO::SkipDialog(parentWidget, options, errorText);
0180         dlg->setAttribute(Qt::WA_DeleteOnClose);
0181         dlg->setWindowModality(Qt::WindowModal);
0182 
0183         connect(job, &KJob::finished, dlg, &QDialog::reject);
0184         connect(dlg, &QDialog::finished, this, [this, job](const int exitCode) {
0185             Q_EMIT askUserSkipResult(static_cast<KIO::SkipDialog_Result>(exitCode), job);
0186         });
0187 
0188         dlg->show();
0189     });
0190 }
0191 
0192 struct ProcessAskDeleteResult {
0193     QStringList prettyList;
0194     KMessageDialog::Type dialogType = KMessageDialog::QuestionTwoActions;
0195     KGuiItem acceptButton;
0196     QString text;
0197     QIcon icon;
0198     QString title = i18n("Delete Permanently");
0199     bool isSingleUrl = false;
0200 };
0201 
0202 using AskIface = KIO::AskUserActionInterface;
0203 static ProcessAskDeleteResult processAskDelete(const QList<QUrl> &urls, AskIface::DeletionType deletionType)
0204 {
0205     ProcessAskDeleteResult res;
0206     res.prettyList.reserve(urls.size());
0207     std::transform(urls.cbegin(), urls.cend(), std::back_inserter(res.prettyList), [](const auto &url) {
0208         if (url.scheme() == QLatin1String("trash")) {
0209             QString path = url.path();
0210             // HACK (#98983): remove "0-foo". Note that it works better than
0211             // displaying KFileItem::name(), for files under a subdir.
0212             static const QRegularExpression re(QStringLiteral("^/[0-9]+-"));
0213             path.remove(re);
0214             return path;
0215         } else {
0216             return url.toDisplayString(QUrl::PreferLocalFile);
0217         }
0218     });
0219 
0220     const int urlCount = res.prettyList.size();
0221     res.isSingleUrl = urlCount == 1;
0222 
0223     switch (deletionType) {
0224     case AskIface::Delete: {
0225         res.dialogType = KMessageDialog::QuestionTwoActions; // Using Question* so the Delete button is pre-selected. Bug 462845
0226         res.icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
0227         if (res.isSingleUrl) {
0228             res.text = xi18nc("@info",
0229                               "Do you really want to permanently delete this item?<nl/><nl/>"
0230                               "<filename>%1</filename><nl/><nl/>"
0231                               "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0232                               res.prettyList.at(0));
0233         } else {
0234             res.text = xi18ncp("@info",
0235                                "Do you really want to permanently delete this %1 item?<nl/><nl/>"
0236                                "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0237                                "Do you really want to permanently delete these %1 items?<nl/><nl/>"
0238                                "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0239                                urlCount);
0240         }
0241         res.acceptButton = KGuiItem(i18nc("@action:button", "Delete Permanently"), QStringLiteral("edit-delete"));
0242         break;
0243     }
0244     case AskIface::DeleteInsteadOfTrash: {
0245         res.dialogType = KMessageDialog::WarningTwoActions;
0246         if (res.isSingleUrl) {
0247             res.text = xi18nc("@info",
0248                               "Moving this item to Trash failed as it is too large."
0249                               " Permanently delete it instead?<nl/><nl/>"
0250                               "<filename>%1</filename><nl/><nl/>"
0251                               "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0252                               res.prettyList.at(0));
0253         } else {
0254             res.text = xi18ncp("@info",
0255                                "Moving this %1 item to Trash failed as it is too large."
0256                                " Permanently delete it instead?<nl/>"
0257                                "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0258                                "Moving these %1 items to Trash failed as they are too large."
0259                                " Permanently delete them instead?<nl/><nl/>"
0260                                "<emphasis strong='true'>This action cannot be undone.</emphasis>",
0261                                urlCount);
0262         }
0263         res.acceptButton = KGuiItem(i18nc("@action:button", "Delete Permanently"), QStringLiteral("edit-delete"));
0264         break;
0265     }
0266     case AskIface::EmptyTrash: {
0267         res.dialogType = KMessageDialog::QuestionTwoActions; // Using Question* so the Delete button is pre-selected.
0268         res.icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
0269         res.text = xi18nc("@info",
0270                           "Do you want to permanently delete all items from the Trash?<nl/><nl/>"
0271                           "<emphasis strong='true'>This action cannot be undone.</emphasis>");
0272         res.acceptButton = KGuiItem(i18nc("@action:button", "Empty Trash"), QStringLiteral("user-trash"));
0273         break;
0274     }
0275     case AskIface::Trash: {
0276         if (res.isSingleUrl) {
0277             res.text = xi18nc("@info",
0278                               "Do you really want to move this item to the Trash?<nl/>"
0279                               "<filename>%1</filename>",
0280                               res.prettyList.at(0));
0281         } else {
0282             res.text =
0283                 xi18ncp("@info", "Do you really want to move this %1 item to the Trash?", "Do you really want to move these %1 items to the Trash?", urlCount);
0284         }
0285         res.title = i18n("Move to Trash");
0286         res.acceptButton = KGuiItem(res.title, QStringLiteral("user-trash"));
0287         break;
0288     }
0289     default:
0290         break;
0291     }
0292     return res;
0293 }
0294 
0295 void KIO::WidgetsAskUserActionHandler::askUserDelete(const QList<QUrl> &urls, DeletionType deletionType, ConfirmationType confirmationType, QWidget *parent)
0296 {
0297     QString keyName;
0298     bool ask = (confirmationType == ForceConfirmation);
0299     if (!ask) {
0300         // The default value for confirmations is true for delete and false
0301         // for trash. If you change this, please also update:
0302         //      dolphin/src/settings/general/confirmationssettingspage.cpp
0303         bool defaultValue = true;
0304 
0305         switch (deletionType) {
0306         case DeleteInsteadOfTrash:
0307         case Delete:
0308             keyName = QStringLiteral("ConfirmDelete");
0309             break;
0310         case Trash:
0311             keyName = QStringLiteral("ConfirmTrash");
0312             defaultValue = false;
0313             break;
0314         case EmptyTrash:
0315             keyName = QStringLiteral("ConfirmEmptyTrash");
0316             break;
0317         }
0318 
0319         KSharedConfigPtr kioConfig = KSharedConfig::openConfig(QStringLiteral("kiorc"), KConfig::NoGlobals);
0320         ask = kioConfig->group("Confirmations").readEntry(keyName, defaultValue);
0321     }
0322 
0323     if (!ask) {
0324         Q_EMIT askUserDeleteResult(true, urls, deletionType, parent);
0325         return;
0326     }
0327 
0328     QMetaObject::invokeMethod(qGuiApp, [=] {
0329         const auto &[prettyList, dialogType, acceptButton, text, icon, title, singleUrl] = processAskDelete(urls, deletionType);
0330         KMessageDialog *dlg = new KMessageDialog(dialogType, text, parent);
0331         dlg->setAttribute(Qt::WA_DeleteOnClose);
0332         dlg->setCaption(title);
0333         dlg->setIcon(icon);
0334         dlg->setButtons(acceptButton, KStandardGuiItem::cancel());
0335         if (!singleUrl) {
0336             dlg->setListWidgetItems(prettyList);
0337         }
0338         dlg->setDontAskAgainText(i18nc("@option:checkbox", "Do not ask again"));
0339         // If we get here, !ask must be false
0340         dlg->setDontAskAgainChecked(!ask);
0341 
0342         connect(dlg, &QDialog::finished, this, [=](const int buttonCode) {
0343             const bool isDelete = (buttonCode == KMessageDialog::PrimaryAction);
0344 
0345             Q_EMIT askUserDeleteResult(isDelete, urls, deletionType, parent);
0346 
0347             if (isDelete) {
0348                 KSharedConfigPtr kioConfig = KSharedConfig::openConfig(QStringLiteral("kiorc"), KConfig::NoGlobals);
0349                 KConfigGroup cg = kioConfig->group("Confirmations");
0350                 cg.writeEntry(keyName, !dlg->isDontAskAgainChecked());
0351                 cg.sync();
0352             }
0353         });
0354 
0355         dlg->setWindowModality(Qt::WindowModal);
0356         dlg->show();
0357     });
0358 }
0359 
0360 void KIO::WidgetsAskUserActionHandler::requestUserMessageBox(MessageDialogType type,
0361                                                              const QString &text,
0362                                                              const QString &title,
0363                                                              const QString &primaryActionText,
0364                                                              const QString &secondaryActionText,
0365                                                              const QString &primaryActionIconName,
0366                                                              const QString &secondaryActionIconName,
0367                                                              const QString &dontAskAgainName,
0368                                                              const QString &details,
0369                                                              const KIO::MetaData &metaData,
0370                                                              QWidget *parent)
0371 {
0372     if (d->gotPersistentUserReply(type, KSharedConfig::openConfig(QStringLiteral("kioslaverc"))->group("Notification Messages"), dontAskAgainName)) {
0373         return;
0374     }
0375 
0376     QWidget *parentWidget = parent;
0377 
0378     if (!parentWidget) {
0379         parentWidget = d->m_parentWidget;
0380     }
0381 
0382     if (!parentWidget) {
0383         parentWidget = qApp->activeWindow();
0384     }
0385 
0386     const KGuiItem primaryActionButton(primaryActionText, primaryActionIconName);
0387     const KGuiItem secondaryActionButton(secondaryActionText, secondaryActionIconName);
0388 
0389     // It's "Do not ask again" every where except with Information
0390     QString dontAskAgainText = i18nc("@option:check", "Do not ask again");
0391 
0392     KMessageDialog::Type dlgType;
0393     bool hasCancelButton = false;
0394 
0395     switch (type) {
0396     case AskUserActionInterface::QuestionTwoActions:
0397         dlgType = KMessageDialog::QuestionTwoActions;
0398         break;
0399     case AskUserActionInterface::QuestionTwoActionsCancel:
0400         dlgType = KMessageDialog::QuestionTwoActionsCancel;
0401         hasCancelButton = true;
0402         break;
0403     case AskUserActionInterface::WarningTwoActions:
0404         dlgType = KMessageDialog::WarningTwoActions;
0405         break;
0406     case AskUserActionInterface::WarningTwoActionsCancel:
0407         dlgType = KMessageDialog::WarningTwoActionsCancel;
0408         hasCancelButton = true;
0409         break;
0410     case AskUserActionInterface::WarningContinueCancel:
0411         dlgType = KMessageDialog::WarningContinueCancel;
0412         hasCancelButton = true;
0413         break;
0414     case AskUserActionInterface::SSLMessageBox:
0415         d->sslMessageBox(text, metaData, parentWidget);
0416         return;
0417     case AskUserActionInterface::Information:
0418         dlgType = KMessageDialog::Information;
0419         dontAskAgainText = i18nc("@option:check", "Do not show this message again");
0420         break;
0421 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 97)
0422     case AskUserActionInterface::Sorry:
0423 #if KWIDGETSADDONS_BUILD_DEPRECATED_SINCE(5, 97)
0424         QT_WARNING_PUSH
0425         QT_WARNING_DISABLE_DEPRECATED
0426         dlgType = KMessageDialog::Sorry;
0427         QT_WARNING_POP
0428         dontAskAgainText = QString{}; // No dontAskAgain checkbox
0429         break;
0430 #else
0431 #error "Cannot build KIOCore with KIO::AskUserActionInterface::Sorry with KMessageDialog::Sorry disabled"
0432 #endif
0433 #endif
0434     case AskUserActionInterface::Error:
0435         dlgType = KMessageDialog::Error;
0436         dontAskAgainText = QString{}; // No dontAskAgain checkbox
0437         break;
0438     default:
0439         qCWarning(KIO_WIDGETS) << "Unknown message dialog type" << type;
0440         return;
0441     }
0442 
0443     QMetaObject::invokeMethod(qGuiApp, [=]() {
0444         auto cancelButton = hasCancelButton ? KStandardGuiItem::cancel() : KGuiItem();
0445         auto *dialog = new KMessageDialog(dlgType, text, parentWidget);
0446 
0447         dialog->setAttribute(Qt::WA_DeleteOnClose);
0448         dialog->setCaption(title);
0449         dialog->setIcon(QIcon{});
0450         dialog->setButtons(primaryActionButton, secondaryActionButton, cancelButton);
0451         dialog->setDetails(details);
0452         dialog->setDontAskAgainText(dontAskAgainText);
0453         dialog->setDontAskAgainChecked(false);
0454         dialog->setOpenExternalLinks(true); // Allow opening external links in the text labels
0455 
0456         connect(dialog, &QDialog::finished, this, [=](const int result) {
0457             KIO::WorkerBase::ButtonCode btnCode;
0458             switch (result) {
0459             case KMessageDialog::PrimaryAction:
0460                 if (dlgType == KMessageDialog::WarningContinueCancel) {
0461                     btnCode = KIO::WorkerBase::Continue;
0462                 } else {
0463                     btnCode = KIO::WorkerBase::PrimaryAction;
0464                 }
0465                 break;
0466             case KMessageDialog::SecondaryAction:
0467                 btnCode = KIO::WorkerBase::SecondaryAction;
0468                 break;
0469             case KMessageDialog::Cancel:
0470                 btnCode = KIO::WorkerBase::Cancel;
0471                 break;
0472             case KMessageDialog::Ok:
0473                 btnCode = KIO::WorkerBase::Ok;
0474                 break;
0475             default:
0476                 qCWarning(KIO_WIDGETS) << "Unknown message dialog result" << result;
0477                 return;
0478             }
0479 
0480             Q_EMIT messageBoxResult(btnCode);
0481 
0482             if ((result != KMessageDialog::Cancel) && dialog->isDontAskAgainChecked()) {
0483                 KSharedConfigPtr reqMsgConfig = KSharedConfig::openConfig(QStringLiteral("kioslaverc"));
0484                 KConfigGroup cg = reqMsgConfig->group("Notification Messages");
0485                 d->savePersistentUserReply(type, cg, dontAskAgainName, result);
0486             }
0487         });
0488 
0489         dialog->show();
0490     });
0491 }
0492 
0493 void KIO::WidgetsAskUserActionHandlerPrivate::sslMessageBox(const QString &text, const KIO::MetaData &metaData, QWidget *parent)
0494 {
0495     QWidget *parentWidget = parent;
0496 
0497     if (!parentWidget) {
0498         parentWidget = m_parentWidget;
0499     }
0500 
0501     if (!parentWidget) {
0502         parentWidget = qApp->activeWindow();
0503     }
0504 
0505     const QStringList sslList = metaData.value(QStringLiteral("ssl_peer_chain")).split(QLatin1Char('\x01'), Qt::SkipEmptyParts);
0506 
0507     QList<QSslCertificate> certChain;
0508     bool decodedOk = true;
0509     for (const QString &str : sslList) {
0510         certChain.append(QSslCertificate(str.toUtf8()));
0511         if (certChain.last().isNull()) {
0512             decodedOk = false;
0513             break;
0514         }
0515     }
0516 
0517     QMetaObject::invokeMethod(qGuiApp, [=] {
0518         if (decodedOk) { // Use KSslInfoDialog
0519             KSslInfoDialog *ksslDlg = new KSslInfoDialog(parentWidget);
0520             ksslDlg->setSslInfo(certChain,
0521                                 metaData.value(QStringLiteral("ssl_peer_ip")),
0522                                 text, // The URL
0523                                 metaData.value(QStringLiteral("ssl_protocol_version")),
0524                                 metaData.value(QStringLiteral("ssl_cipher")),
0525                                 metaData.value(QStringLiteral("ssl_cipher_used_bits")).toInt(),
0526                                 metaData.value(QStringLiteral("ssl_cipher_bits")).toInt(),
0527                                 KSslInfoDialog::certificateErrorsFromString(metaData.value(QStringLiteral("ssl_cert_errors"))));
0528 
0529             // KSslInfoDialog deletes itself by setting Qt::WA_DeleteOnClose
0530 
0531             QObject::connect(ksslDlg, &QDialog::finished, q, [this]() {
0532                 // KSslInfoDialog only has one button, QDialogButtonBox::Close
0533                 Q_EMIT q->messageBoxResult(KIO::WorkerBase::Cancel);
0534             });
0535 
0536             ksslDlg->show();
0537             return;
0538         }
0539 
0540         // Fallback to a generic message box
0541         auto *dialog = new KMessageDialog(KMessageDialog::Information, i18n("The peer SSL certificate chain appears to be corrupt."), parentWidget);
0542 
0543         dialog->setAttribute(Qt::WA_DeleteOnClose);
0544         dialog->setCaption(i18n("SSL"));
0545         // KMessageDialog will set a proper icon
0546         dialog->setIcon(QIcon{});
0547         dialog->setButtons(KStandardGuiItem::ok());
0548 
0549         QObject::connect(dialog, &QDialog::finished, q, [this](const int result) {
0550             Q_EMIT q->messageBoxResult(result == KMessageDialog::Ok ? KIO::WorkerBase::Ok : KIO::WorkerBase::Cancel);
0551         });
0552 
0553         dialog->show();
0554     });
0555 }
0556 
0557 void KIO::WidgetsAskUserActionHandler::setWindow(QWidget *window)
0558 {
0559     d->m_parentWidget = window;
0560 }
0561 
0562 #include "moc_widgetsaskuseractionhandler.cpp"