KIO

deleteortrashjob.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2022 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 "deleteortrashjob.h"
9
10#include "fileundomanager.h"
11#include "widgetsaskuseractionhandler.h"
12#include <kio/copyjob.h>
13#include <kio/deletejob.h>
14#include <kio/emptytrashjob.h>
15#include <kio/job.h>
16#include <kio/jobuidelegatefactory.h>
17#include <kio_widgets_debug.h>
18
19#include <KJobWidgets>
20
21namespace KIO
22{
23
24using AskIface = AskUserActionInterface;
25
26class DeleteOrTrashJobPrivate
27{
28public:
29 DeleteOrTrashJobPrivate(const QList<QUrl> &urls, //
30 AskIface::DeletionType deletionType,
32 QObject *parent,
33 DeleteOrTrashJob *qq)
34 : q(qq)
35 , m_urls(urls)
36 , m_delType(deletionType)
37 , m_confirm(confirm)
38 , m_parentWindow(qobject_cast<QWidget *>(parent))
39 {
40 // trashing an already trashed file is deleting it, BUG 459545
41 if (m_delType == AskIface::Trash && m_urls.first().scheme() == QStringLiteral("trash")) {
42 m_delType = AskIface::Delete;
43 }
44 }
45
46 void slotAskUser(bool allowDelete, const QList<QUrl> &urls, AskIface::DeletionType delType, QWidget *parentWindow);
47
48 DeleteOrTrashJob *q = nullptr;
49 QList<QUrl> m_urls;
50 AskIface::DeletionType m_delType;
52 QWidget *m_parentWindow = nullptr;
53 QMetaObject::Connection m_handlerConnection;
54};
55
56void DeleteOrTrashJobPrivate::slotAskUser(bool allowDelete, const QList<QUrl> &urls, AskIface::DeletionType delType, QWidget *parentWindow)
57{
58 if (!allowDelete) {
59 return;
60 }
61
62 KIO::Job *job = nullptr;
63 switch (delType) {
64 case AskIface::Trash:
65 Q_ASSERT(!urls.isEmpty());
66 job = KIO::trash(urls);
67 using UndoMananger = KIO::FileUndoManager;
68 UndoMananger::self()->recordJob(UndoMananger::Trash, urls, QUrl(QStringLiteral("trash:/")), job);
69 break;
71 case AskIface::Delete:
72 Q_ASSERT(!urls.isEmpty());
73 job = KIO::del(urls);
74 break;
76 job = KIO::emptyTrash();
77 break;
78 }
79
80 if (job) {
81 KJobWidgets::setWindow(job, parentWindow);
82 // showErrorMessage() is used in slotResult() instead of AutoErrorHandling,
83 // because if Trashing fails (e.g. due to size constraints), we'll re-ask the
84 // user about deleting instead of Trashing, in which case we don't want to
85 // show the "File is too large to Trash" error message
87 q->addSubjob(job);
88 }
89}
90
92 AskIface::DeletionType deletionType,
94 QObject *parent)
95 : KCompositeJob(parent)
96 , d(new DeleteOrTrashJobPrivate{urls, deletionType, confirm, parent, this})
97{
98}
99
101
103{
104 auto *askHandler = KIO::delegateExtension<AskIface *>(this);
105 if (!askHandler) {
107 auto *widgetAskHandler = new WidgetsAskUserActionHandler(uiDelegate);
108 widgetAskHandler->setWindow(d->m_parentWindow);
110 askHandler = widgetAskHandler;
111 }
112
113 Q_ASSERT(askHandler);
114
115 auto askFunc = [this](bool allowDelete, //
116 const QList<QUrl> &urls,
117 AskIface::DeletionType deletionType,
118 QWidget *window) {
119 d->slotAskUser(allowDelete, urls, deletionType, window);
120 };
121
122 // Make it a unique connection, as the same UI delegate could get re-used
123 // if e.g. Trashing failed and we're re-asking the user about deleting instead
124 // of Trashing
125 disconnect(d->m_handlerConnection);
126 d->m_handlerConnection = connect(askHandler, &AskIface::askUserDeleteResult, this, askFunc);
127 askHandler->askUserDelete(d->m_urls, d->m_delType, d->m_confirm, d->m_parentWindow);
128}
129
130void DeleteOrTrashJob::slotResult(KJob *job)
131{
132 const int errCode = job->error();
133
134 if (errCode == KIO::ERR_TRASH_FILE_TOO_LARGE) {
135 removeSubjob(job);
136 d->m_delType = AskIface::DeleteInsteadOfTrash;
137 start();
138 return;
139 }
140
141 if (errCode) {
142 setError(errCode);
143 // We're a KJob, not a KIO::Job, so build the error string here
146 }
147 emitResult();
148}
149
150} // namespace KIO
151
152#include "moc_deleteortrashjob.cpp"
virtual bool addSubjob(KJob *job)
virtual bool removeSubjob(KJob *job)
The AskUserActionInterface class allows a KIO::Job to prompt the user for a decision when e....
void askUserDeleteResult(bool allowDelete, const QList< QUrl > &urls, KIO::AskUserActionInterface::DeletionType deletionType, QWidget *parent)
Implementations of this interface must emit this signal when the dialog invoked by askUserDelete() fi...
@ 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 start() override
You must call this to actually start the job.
DeleteOrTrashJob(const QList< QUrl > &urls, AskUserActionInterface::DeletionType deletionType, AskUserActionInterface::ConfirmationType confirm, QObject *parent)
Creates a DeleteOrTrashJob.
~DeleteOrTrashJob() override
Destructor.
FileUndoManager: makes it possible to undo kio jobs.
void recordJob(CommandType op, const QList< QUrl > &src, const QUrl &dst, KIO::Job *job)
Record this job while it's happening and add a command for it so that the user can undo it.
The base class for all jobs.
Definition job_base.h:45
This implements KIO::AskUserActionInterface.
virtual void showErrorMessage()
void setAutoErrorHandlingEnabled(bool enable)
void setErrorText(const QString &errorText)
void emitResult()
int error() const
void setError(int errorCode)
KJobUiDelegate * uiDelegate() const
QString errorText() const
void setUiDelegate(KJobUiDelegate *delegate)
A namespace for KIO globals.
KIOCORE_EXPORT DeleteJob * del(const QUrl &src, JobFlags flags=DefaultFlags)
Delete a file or directory.
KIOCORE_EXPORT QString buildErrorString(int errorCode, const QString &errorText)
Returns a translated error message for errorCode using the additional error information provided by e...
Definition job_error.cpp:31
KIOCORE_EXPORT EmptyTrashJob * emptyTrash()
Empties the trash.
KIOCORE_EXPORT CopyJob * trash(const QUrl &src, JobFlags flags=DefaultFlags)
Trash a file or directory.
Definition copyjob.cpp:2679
@ ERR_TRASH_FILE_TOO_LARGE
Moving files/dirs to the Trash failed due to size constraints.
Definition global.h:215
void setWindow(QObject *job, QWidget *widget)
T & first()
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QString scheme() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Apr 27 2024 22:13:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.