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 q->setError(KIO::ERR_USER_CANCELED);
60 q->emitResult();
61 return;
62 }
63
64 KIO::Job *job = nullptr;
65 switch (delType) {
66 case AskIface::Trash:
67 Q_ASSERT(!urls.isEmpty());
68 job = KIO::trash(urls);
69 using UndoMananger = KIO::FileUndoManager;
70 UndoMananger::self()->recordJob(UndoMananger::Trash, urls, QUrl(QStringLiteral("trash:/")), job);
71 break;
73 case AskIface::Delete:
74 Q_ASSERT(!urls.isEmpty());
75 job = KIO::del(urls);
76 break;
78 job = KIO::emptyTrash();
79 break;
80 }
81
82 if (job) {
83 KJobWidgets::setWindow(job, parentWindow);
84 // showErrorMessage() is used in slotResult() instead of AutoErrorHandling,
85 // because if Trashing fails (e.g. due to size constraints), we'll re-ask the
86 // user about deleting instead of Trashing, in which case we don't want to
87 // show the "File is too large to Trash" error message
89 q->addSubjob(job);
90 }
91}
92
94 AskIface::DeletionType deletionType,
96 QObject *parent)
97 : KCompositeJob(parent)
98 , d(new DeleteOrTrashJobPrivate{urls, deletionType, confirm, parent, this})
99{
100}
101
103
105{
106 auto *askHandler = KIO::delegateExtension<AskIface *>(this);
107 if (!askHandler) {
109 auto *widgetAskHandler = new WidgetsAskUserActionHandler(uiDelegate);
110 widgetAskHandler->setWindow(d->m_parentWindow);
112 askHandler = widgetAskHandler;
113 }
114
115 Q_ASSERT(askHandler);
116
117 auto askFunc = [this](bool allowDelete, //
118 const QList<QUrl> &urls,
119 AskIface::DeletionType deletionType,
120 QWidget *window) {
121 d->slotAskUser(allowDelete, urls, deletionType, window);
122 };
123
124 // Make it a unique connection, as the same UI delegate could get re-used
125 // if e.g. Trashing failed and we're re-asking the user about deleting instead
126 // of Trashing
127 disconnect(d->m_handlerConnection);
128 d->m_handlerConnection = connect(askHandler, &AskIface::askUserDeleteResult, this, askFunc);
129 askHandler->askUserDelete(d->m_urls, d->m_delType, d->m_confirm, d->m_parentWindow);
130}
131
132void DeleteOrTrashJob::slotResult(KJob *job)
133{
134 const int errCode = job->error();
135
136 if (errCode == KIO::ERR_TRASH_FILE_TOO_LARGE) {
137 removeSubjob(job);
138 d->m_delType = AskIface::DeleteInsteadOfTrash;
139 start();
140 return;
141 }
142
143 if (errCode) {
144 setError(errCode);
145 // We're a KJob, not a KIO::Job, so build the error string here
148 }
149 emitResult();
150}
151
152} // namespace KIO
153
154#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.
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
T delegateExtension(KJob *job)
Returns the child of the job's uiDelegate() that implements the given extension, or nullptr if none w...
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:2710
@ 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 Mon Nov 18 2024 12:16:28 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.