KIO

widgetsaskuseractionhandler.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2020 Ahmad Samir <a.samirh78@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "widgetsaskuseractionhandler.h"
9
10#include <KConfig>
11#include <KConfigGroup>
12#include <KGuiItem>
13#include <KIO/WorkerBase>
14#include <KJob>
15#include <KJobWidgets>
16#include <KLocalizedString>
17#include <KMessageDialog>
18#include <KSharedConfig>
19#include <KSslInfoDialog>
20#include <KStandardGuiItem>
21#include <kio_widgets_debug.h>
22
23#include <QApplication>
24#include <QDialogButtonBox>
25#include <QPointer>
26#include <QRegularExpression>
27#include <QUrl>
28
29class KIO::WidgetsAskUserActionHandlerPrivate
30{
31public:
32 explicit WidgetsAskUserActionHandlerPrivate(WidgetsAskUserActionHandler *qq)
33 : q(qq)
34 {
35 }
36
37 // Creates a KSslInfoDialog or falls back to a generic Information dialog
38 void sslMessageBox(const QString &text, const KIO::MetaData &metaData, QWidget *parent);
39
40 bool gotPersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type, const KConfigGroup &cg, const QString &dontAskAgainName);
41 void savePersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type, KConfigGroup &cg, const QString &dontAskAgainName, int result);
42
43 WidgetsAskUserActionHandler *const q;
44 QPointer<QWidget> m_parentWidget = nullptr;
45
46 QWidget *getParentWidget(KJob *job);
47 QWidget *getParentWidget(QWidget *widget);
48};
49
50bool KIO::WidgetsAskUserActionHandlerPrivate::gotPersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type,
51 const KConfigGroup &cg,
52 const QString &dontAskAgainName)
53{
54 // storage values matching the logic of FrameworkIntegration's KMessageBoxDontAskAgainConfigStorage
55 switch (type) {
60 // storage holds "true" if persistent reply is "Yes", "false" for persistent "No",
61 // otherwise no persistent reply is present
62 const QString value = cg.readEntry(dontAskAgainName, QString());
63 if ((value.compare(QLatin1String("yes"), Qt::CaseInsensitive) == 0) || (value.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0)) {
65 return true;
66 }
67 if ((value.compare(QLatin1String("no"), Qt::CaseInsensitive) == 0) || (value.compare(QLatin1String("false"), Qt::CaseInsensitive) == 0)) {
69 return true;
70 }
71 break;
72 }
73 case KIO::AskUserActionInterface::WarningContinueCancel: {
74 // storage holds "false" if persistent reply is "Continue"
75 // otherwise no persistent reply is present
76 const bool value = cg.readEntry(dontAskAgainName, true);
77 if (value == false) {
78 Q_EMIT q->messageBoxResult(KIO::WorkerBase::Continue);
79 return true;
80 }
81 break;
82 }
83 default:
84 break;
85 }
86
87 return false;
88}
89
90void KIO::WidgetsAskUserActionHandlerPrivate::savePersistentUserReply(KIO::AskUserActionInterface::MessageDialogType type,
91 KConfigGroup &cg,
92 const QString &dontAskAgainName,
93 int result)
94{
95 // see gotPersistentUserReply for values stored and why
96 switch (type) {
101 cg.writeEntry(dontAskAgainName, result == KIO::WorkerBase::PrimaryAction);
102 cg.sync();
103 break;
104 case KIO::AskUserActionInterface::WarningContinueCancel:
105 cg.writeEntry(dontAskAgainName, false);
106 cg.sync();
107 break;
108 default:
109 break;
110 }
111}
112
113QWidget *KIO::WidgetsAskUserActionHandlerPrivate::getParentWidget(KJob *job)
114{
115 QWidget *parentWidget = nullptr;
116
117 if (job) {
118 auto parentWindow = KJobWidgets::window(job);
119 if (parentWindow) {
120 parentWidget = parentWindow;
121 }
122 }
123
124 return getParentWidget(parentWidget);
125}
126
127QWidget *KIO::WidgetsAskUserActionHandlerPrivate::getParentWidget(QWidget *widget)
128{
129 QWidget *parentWidget = widget;
130
131 if (!parentWidget) {
132 parentWidget = this->m_parentWidget;
133 }
134
135 if (!parentWidget) {
136 parentWidget = qApp->activeWindow();
137 }
138
139 return parentWidget;
140}
141
142KIO::WidgetsAskUserActionHandler::WidgetsAskUserActionHandler(QObject *parent)
143 : KIO::AskUserActionInterface(parent)
144 , d(new WidgetsAskUserActionHandlerPrivate(this))
145{
146}
147
148KIO::WidgetsAskUserActionHandler::~WidgetsAskUserActionHandler()
149{
150}
151
153 const QString &title,
154 const QUrl &src,
155 const QUrl &dest,
157 KIO::filesize_t sizeSrc,
158 KIO::filesize_t sizeDest,
159 const QDateTime &ctimeSrc,
160 const QDateTime &ctimeDest,
161 const QDateTime &mtimeSrc,
162 const QDateTime &mtimeDest)
163{
164 QMetaObject::invokeMethod(qGuiApp, [=, this] {
165 auto *dlg = new KIO::RenameDialog(d->getParentWidget(job), title, src, dest, options, sizeSrc, sizeDest, ctimeSrc, ctimeDest, mtimeSrc, mtimeDest);
166
167 dlg->setAttribute(Qt::WA_DeleteOnClose);
168 dlg->setWindowModality(Qt::WindowModal);
169
170 connect(job, &KJob::finished, dlg, &QDialog::reject);
171 connect(dlg, &QDialog::finished, this, [this, job, dlg](const int exitCode) {
172 KIO::RenameDialog_Result result = static_cast<RenameDialog_Result>(exitCode);
173 const QUrl newUrl = result == Result_AutoRename ? dlg->autoDestUrl() : dlg->newDestUrl();
174 Q_EMIT askUserRenameResult(result, newUrl, job);
175 });
176
177 dlg->show();
178 });
179}
180
182{
183 QMetaObject::invokeMethod(qGuiApp, [=, this] {
184 auto *dlg = new KIO::SkipDialog(d->getParentWidget(job), options, errorText);
185 dlg->setAttribute(Qt::WA_DeleteOnClose);
186 dlg->setWindowModality(Qt::WindowModal);
187
188 connect(job, &KJob::finished, dlg, &QDialog::reject);
189 connect(dlg, &QDialog::finished, this, [this, job](const int exitCode) {
190 Q_EMIT askUserSkipResult(static_cast<KIO::SkipDialog_Result>(exitCode), job);
191 });
192
193 dlg->show();
194 });
195}
196
197struct ProcessAskDeleteResult {
198 QStringList prettyList;
200 KGuiItem acceptButton;
201 QString text;
202 QIcon icon;
203 QString title = i18n("Delete Permanently");
204 bool isSingleUrl = false;
205};
206
208static ProcessAskDeleteResult processAskDelete(const QList<QUrl> &urls, AskIface::DeletionType deletionType)
209{
210 ProcessAskDeleteResult res;
211 res.prettyList.reserve(urls.size());
212 std::transform(urls.cbegin(), urls.cend(), std::back_inserter(res.prettyList), [](const auto &url) {
213 if (url.scheme() == QLatin1String("trash")) {
214 QString path = url.path();
215 // HACK (#98983): remove "0-foo". Note that it works better than
216 // displaying KFileItem::name(), for files under a subdir.
217 static const QRegularExpression re(QStringLiteral("^/[0-9]+-"));
218 path.remove(re);
219 return path;
220 } else {
221 return url.toDisplayString(QUrl::PreferLocalFile);
222 }
223 });
224
225 const int urlCount = res.prettyList.size();
226 res.isSingleUrl = urlCount == 1;
227
228 switch (deletionType) {
229 case AskIface::Delete: {
230 res.dialogType = KMessageDialog::QuestionTwoActions; // Using Question* so the Delete button is pre-selected. Bug 462845
231 res.icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
232 if (res.isSingleUrl) {
233 res.text = xi18nc("@info",
234 "Do you really want to permanently delete this item?<nl/><nl/>"
235 "<filename>%1</filename><nl/><nl/>"
236 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
237 res.prettyList.at(0));
238 } else {
239 res.text = xi18ncp("@info",
240 "Do you really want to permanently delete this %1 item?<nl/><nl/>"
241 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
242 "Do you really want to permanently delete these %1 items?<nl/><nl/>"
243 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
244 urlCount);
245 }
246 res.acceptButton = KGuiItem(i18nc("@action:button", "Delete Permanently"), QStringLiteral("edit-delete"));
247 break;
248 }
250 res.dialogType = KMessageDialog::WarningTwoActions;
251 if (res.isSingleUrl) {
252 res.text = xi18nc("@info",
253 "Moving this item to Trash failed as it is too large."
254 " Permanently delete it instead?<nl/><nl/>"
255 "<filename>%1</filename><nl/><nl/>"
256 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
257 res.prettyList.at(0));
258 } else {
259 res.text = xi18ncp("@info",
260 "Moving this %1 item to Trash failed as it is too large."
261 " Permanently delete it instead?<nl/>"
262 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
263 "Moving these %1 items to Trash failed as they are too large."
264 " Permanently delete them instead?<nl/><nl/>"
265 "<emphasis strong='true'>This action cannot be undone.</emphasis>",
266 urlCount);
267 }
268 res.acceptButton = KGuiItem(i18nc("@action:button", "Delete Permanently"), QStringLiteral("edit-delete"));
269 break;
270 }
272 res.dialogType = KMessageDialog::QuestionTwoActions; // Using Question* so the Delete button is pre-selected.
273 res.icon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
274 res.text = xi18nc("@info",
275 "Do you want to permanently delete all items from the Trash?<nl/><nl/>"
276 "<emphasis strong='true'>This action cannot be undone.</emphasis>");
277 res.acceptButton = KGuiItem(i18nc("@action:button", "Empty Trash"), QStringLiteral("user-trash"));
278 break;
279 }
280 case AskIface::Trash: {
281 if (res.isSingleUrl) {
282 res.text = xi18nc("@info",
283 "Do you really want to move this item to the Trash?<nl/>"
284 "<filename>%1</filename>",
285 res.prettyList.at(0));
286 } else {
287 res.text =
288 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);
289 }
290 res.title = i18n("Move to Trash");
291 res.acceptButton = KGuiItem(res.title, QStringLiteral("user-trash"));
292 break;
293 }
294 default:
295 break;
296 }
297 return res;
298}
299
301{
302 QString keyName;
303 bool ask = (confirmationType == ForceConfirmation);
304 if (!ask) {
305 // The default value for confirmations is true for delete and false
306 // for trash. If you change this, please also update:
307 // dolphin/src/settings/general/confirmationssettingspage.cpp
308 bool defaultValue = true;
309
310 switch (deletionType) {
311 case DeleteInsteadOfTrash:
312 case Delete:
313 keyName = QStringLiteral("ConfirmDelete");
314 break;
315 case Trash:
316 keyName = QStringLiteral("ConfirmTrash");
317 defaultValue = false;
318 break;
319 case EmptyTrash:
320 keyName = QStringLiteral("ConfirmEmptyTrash");
321 break;
322 }
323
324 KSharedConfigPtr kioConfig = KSharedConfig::openConfig(QStringLiteral("kiorc"), KConfig::NoGlobals);
325 ask = kioConfig->group(QStringLiteral("Confirmations")).readEntry(keyName, defaultValue);
326 }
327
328 if (!ask) {
329 Q_EMIT askUserDeleteResult(true, urls, deletionType, parent);
330 return;
331 }
332
333 QMetaObject::invokeMethod(qGuiApp, [=, this] {
334 const auto &[prettyList, dialogType, acceptButton, text, icon, title, singleUrl] = processAskDelete(urls, deletionType);
335 KMessageDialog *dlg = new KMessageDialog(dialogType, text, parent);
337 dlg->setCaption(title);
338 dlg->setIcon(icon);
339 dlg->setButtons(acceptButton, KStandardGuiItem::cancel());
340 if (!singleUrl) {
341 dlg->setListWidgetItems(prettyList);
342 }
343 dlg->setDontAskAgainText(i18nc("@option:checkbox", "Do not ask again"));
344 // If we get here, !ask must be false
345 dlg->setDontAskAgainChecked(!ask);
346
347 connect(dlg, &QDialog::finished, this, [=, this](const int buttonCode) {
348 const bool isDelete = (buttonCode == KMessageDialog::PrimaryAction);
349
350 Q_EMIT askUserDeleteResult(isDelete, urls, deletionType, parent);
351
352 if (isDelete) {
353 KSharedConfigPtr kioConfig = KSharedConfig::openConfig(QStringLiteral("kiorc"), KConfig::NoGlobals);
354 KConfigGroup cg = kioConfig->group(QStringLiteral("Confirmations"));
355 cg.writeEntry(keyName, !dlg->isDontAskAgainChecked());
356 cg.sync();
357 }
358 });
359
361 dlg->show();
362 });
363}
364
366 const QString &text,
367 const QString &title,
368 const QString &primaryActionText,
369 const QString &secondaryActionText,
370 const QString &primaryActionIconName,
371 const QString &secondaryActionIconName,
372 const QString &dontAskAgainName,
373 const QString &details,
374 QWidget *parent)
375{
376 if (d->gotPersistentUserReply(type,
377 KSharedConfig::openConfig(QStringLiteral("kioslaverc"))->group(QStringLiteral("Notification Messages")),
378 dontAskAgainName)) {
379 return;
380 }
381
382 const KGuiItem primaryActionButton(primaryActionText, primaryActionIconName);
383 const KGuiItem secondaryActionButton(secondaryActionText, secondaryActionIconName);
384
385 // It's "Do not ask again" every where except with Information
386 QString dontAskAgainText = i18nc("@option:check", "Do not ask again");
387
388 KMessageDialog::Type dlgType;
389 bool hasCancelButton = false;
390
391 switch (type) {
394 break;
397 hasCancelButton = true;
398 break;
401 break;
404 hasCancelButton = true;
405 break;
406 case AskUserActionInterface::WarningContinueCancel:
408 hasCancelButton = true;
409 break;
410 case AskUserActionInterface::Information:
412 dontAskAgainText = i18nc("@option:check", "Do not show this message again");
413 break;
414 case AskUserActionInterface::Error:
415 dlgType = KMessageDialog::Error;
416 dontAskAgainText = QString{}; // No dontAskAgain checkbox
417 break;
418 default:
419 qCWarning(KIO_WIDGETS) << "Unknown message dialog type" << type;
420 return;
421 }
422
423 QMetaObject::invokeMethod(qGuiApp, [=, this]() {
424 auto cancelButton = hasCancelButton ? KStandardGuiItem::cancel() : KGuiItem();
425 auto *dialog = new KMessageDialog(dlgType, text, d->getParentWidget(parent));
426
427 dialog->setAttribute(Qt::WA_DeleteOnClose);
428 dialog->setCaption(title);
429 dialog->setIcon(QIcon{});
430 dialog->setButtons(primaryActionButton, secondaryActionButton, cancelButton);
431 dialog->setDetails(details);
432 dialog->setDontAskAgainText(dontAskAgainText);
433 dialog->setDontAskAgainChecked(false);
434 dialog->setOpenExternalLinks(true); // Allow opening external links in the text labels
435
436 connect(dialog, &QDialog::finished, this, [=, this](const int result) {
438 switch (result) {
441 btnCode = KIO::WorkerBase::Continue;
442 } else {
444 }
445 break;
448 break;
450 btnCode = KIO::WorkerBase::Cancel;
451 break;
453 btnCode = KIO::WorkerBase::Ok;
454 break;
455 default:
456 qCWarning(KIO_WIDGETS) << "Unknown message dialog result" << result;
457 return;
458 }
459
460 Q_EMIT messageBoxResult(btnCode);
461
462 if ((result != KMessageDialog::Cancel) && dialog->isDontAskAgainChecked()) {
463 KSharedConfigPtr reqMsgConfig = KSharedConfig::openConfig(QStringLiteral("kioslaverc"));
464 KConfigGroup cg = reqMsgConfig->group(QStringLiteral("Notification Messages"));
465 d->savePersistentUserReply(type, cg, dontAskAgainName, result);
466 }
467 });
468
469 dialog->show();
470 });
471}
472
473void KIO::WidgetsAskUserActionHandler::setWindow(QWidget *window)
474{
475 d->m_parentWidget = window;
476}
477
478void KIO::WidgetsAskUserActionHandler::askIgnoreSslErrors(const QVariantMap &sslErrorData, QWidget *parent)
479{
480 QWidget *parentWidget = d->getParentWidget(parent);
481
482 QString message = i18n("The server failed the authenticity check (%1).\n\n", sslErrorData[QLatin1String("hostname")].toString());
483
484 message += sslErrorData[QLatin1String("sslError")].toString();
485
486 auto *dialog = new KMessageDialog(KMessageDialog::WarningTwoActionsCancel, message, parentWidget);
487
488 dialog->setAttribute(Qt::WA_DeleteOnClose);
489 dialog->setCaption(i18n("Server Authentication"));
490 dialog->setIcon(QIcon{});
491 dialog->setButtons(KGuiItem{i18n("&Details"), QStringLiteral("documentinfo")}, KStandardGuiItem::cont(), KStandardGuiItem::cancel());
492
493 connect(dialog, &KMessageDialog::finished, this, [this, parentWidget, sslErrorData](int result) {
494 if (result == KMessageDialog::PrimaryAction) {
495 showSslDetails(sslErrorData, parentWidget);
496 } else if (result == KMessageDialog::SecondaryAction) {
497 // continue();
498 Q_EMIT askIgnoreSslErrorsResult(1);
499 } else if (result == KMessageDialog::Cancel) {
500 // cancel();
501 Q_EMIT askIgnoreSslErrorsResult(0);
502 }
503 });
504
505 dialog->show();
506}
507
508void KIO::WidgetsAskUserActionHandler::showSslDetails(const QVariantMap &sslErrorData, QWidget *parentWidget)
509{
510 const QStringList sslList = sslErrorData[QLatin1String("peerCertChain")].toStringList();
511
512 QList<QSslCertificate> certChain;
513 bool decodedOk = true;
514 for (const QString &str : sslList) {
515 certChain.append(QSslCertificate(str.toUtf8()));
516 if (certChain.last().isNull()) {
517 decodedOk = false;
518 break;
519 }
520 }
521
522 QMetaObject::invokeMethod(qGuiApp, [=, this] {
523 if (decodedOk) { // Use KSslInfoDialog
524 KSslInfoDialog *ksslDlg = new KSslInfoDialog(parentWidget);
525 ksslDlg->setSslInfo(
526 certChain,
527 QString(),
528 sslErrorData[QLatin1String("hostname")].toString(),
529 sslErrorData[QLatin1String("protocol")].toString(),
530 sslErrorData[QLatin1String("cipher")].toString(),
531 sslErrorData[QLatin1String("usedBits")].toInt(),
532 sslErrorData[QLatin1String("bits")].toInt(),
533 KSslInfoDialog::certificateErrorsFromString(sslErrorData[QLatin1String("certificateErrors")].toStringList().join(QLatin1Char('\n'))));
534
535 // KSslInfoDialog deletes itself by setting Qt::WA_DeleteOnClose
536
537 QObject::connect(ksslDlg, &QDialog::finished, this, [this, sslErrorData, parentWidget]() {
538 // KSslInfoDialog only has one button, QDialogButtonBox::Close
539 askIgnoreSslErrors(sslErrorData, parentWidget);
540 });
541
542 ksslDlg->show();
543 return;
544 }
545
546 // Fallback to a generic message box
547 auto *dialog = new KMessageDialog(KMessageDialog::Information, i18n("The peer SSL certificate chain appears to be corrupt."), parentWidget);
548
549 dialog->setAttribute(Qt::WA_DeleteOnClose);
550 dialog->setCaption(i18n("SSL"));
551 dialog->setButtons(KStandardGuiItem::ok());
552
553 QObject::connect(dialog, &QDialog::finished, this, [this](const int result) {
554 Q_EMIT askIgnoreSslErrorsResult(result == KMessageDialog::Ok ? 1 : 0);
555 });
556
557 dialog->show();
558 });
559}
560
561#include "moc_widgetsaskuseractionhandler.cpp"
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
bool sync() override
The AskUserActionInterface class allows a KIO::Job to prompt the user for a decision when e....
@ EmptyTrash
Move the files/directories to Trash.
@ Trash
Delete the files/directories directly, i.e. without moving them to Trash.
ConfirmationType
Deletion confirmation type.
void messageBoxResult(int result)
Implementations of this interface must emit this signal when the dialog invoked by requestUserMessage...
MetaData is a simple map of key/value strings.
The dialog shown when a CopyJob realizes that a destination file already exists, and wants to offer t...
void askUserSkip(KJob *job, KIO::SkipDialog_Options options, const QString &error_text) override
You need to connect to the askUserSkipResult signal to get the dialog's result.
void askUserDelete(const QList< QUrl > &urls, DeletionType deletionType, ConfirmationType confirmationType, QWidget *parent=nullptr) override
Ask for confirmation before moving urls (files/directories) to the Trash, emptying the Trash,...
void requestUserMessageBox(MessageDialogType type, const QString &text, const QString &title, const QString &primaryActionText, const QString &secondaryActionText, const QString &primaryActionIconName={}, const QString &secondaryActionIconName={}, const QString &dontAskAgainName={}, const QString &details={}, QWidget *parent=nullptr) override
This function allows for the delegation of user prompts from the KIO worker.
void askUserRename(KJob *job, const QString &title, const QUrl &src, const QUrl &dest, KIO::RenameDialog_Options options, KIO::filesize_t sizeSrc=KIO::filesize_t(-1), KIO::filesize_t sizeDest=KIO::filesize_t(-1), const QDateTime &ctimeSrc={}, const QDateTime &ctimeDest={}, const QDateTime &mtimeSrc={}, const QDateTime &mtimeDest={}) override
Constructs a modal, parent-less "rename" dialog, to prompt the user for a decision in case of conflic...
ButtonCode
Button codes.
Definition workerbase.h:237
void finished(KJob *job)
bool isDontAskAgainChecked() const
void setListWidgetItems(const QStringList &strlist)
void setIcon(const QIcon &icon)
void setButtons(const KGuiItem &primaryAction=KGuiItem(), const KGuiItem &secondaryAction=KGuiItem(), const KGuiItem &cancelAction=KGuiItem())
void setDontAskAgainChecked(bool isChecked)
void setDontAskAgainText(const QString &dontAskAgainText)
void setCaption(const QString &caption)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
KDE SSL Information Dialog.
void setSslInfo(const QList< QSslCertificate > &certificateChain, const QString &ip, const QString &host, const QString &sslProtocol, const QString &cipher, int usedBits, int bits, const QList< QList< QSslError::SslError > > &validationErrors)
Set information to display about the SSL connection.
static QList< QList< QSslError::SslError > > certificateErrorsFromString(const QString &errorsString)
Converts certificate errors as provided in the "ssl_cert_errors" meta data to a list of QSslError::Ss...
QString xi18ncp(const char *context, const char *singular, const char *plural, const TYPE &arg...)
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
bool KIOWIDGETS_EXPORT askIgnoreSslErrors(const KSslErrorUiData &uiData, RulesStorage storedRules=RecallAndStoreRules)
If there are errors while establishing an SSL encrypted connection to a peer, usually due to certific...
Definition sslui.cpp:16
A namespace for KIO globals.
RenameDialog_Result
The result of a rename or skip dialog.
qulonglong filesize_t
64-bit file size
Definition global.h:35
QWidget * window(QObject *job)
KGuiItem cont()
KGuiItem cancel()
void finished(int result)
virtual void reject()
QIcon fromTheme(const QString &name)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
const_iterator cbegin() const const
const_iterator cend() const const
T & last()
void reserve(qsizetype size)
qsizetype size() const const
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
CaseInsensitive
WA_DeleteOnClose
WindowModal
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setAttribute(Qt::WidgetAttribute attribute, bool on)
void show()
void setWindowModality(Qt::WindowModality windowModality)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:11:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.