1 | /* |
2 | This file is part of the KDE project |
3 | SPDX-FileCopyrightText: 2000 Simon Hausmann <hausmann@kde.org> |
4 | SPDX-FileCopyrightText: 2006, 2008 David Faure <faure@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #ifndef KIO_FILEUNDOMANAGER_H |
10 | #define KIO_FILEUNDOMANAGER_H |
11 | |
12 | #include <QObject> |
13 | #include <QUrl> |
14 | |
15 | #include "kiowidgets_export.h" |
16 | |
17 | #include <memory> |
18 | |
19 | class QDateTime; |
20 | |
21 | namespace KIO |
22 | { |
23 | class Job; |
24 | class CopyJob; |
25 | class FileUndoManagerPrivate; |
26 | class FileUndoManagerSingleton; |
27 | class CommandRecorder; |
28 | class UndoCommand; |
29 | class UndoJob; |
30 | |
31 | /** |
32 | * @class KIO::FileUndoManager fileundomanager.h <KIO/FileUndoManager> |
33 | * |
34 | * FileUndoManager: makes it possible to undo kio jobs. |
35 | * This class is a singleton, use self() to access its only instance. |
36 | */ |
37 | class KIOWIDGETS_EXPORT FileUndoManager : public QObject |
38 | { |
39 | Q_OBJECT |
40 | public: |
41 | /** |
42 | * @return the FileUndoManager instance |
43 | */ |
44 | static FileUndoManager *self(); |
45 | |
46 | /** |
47 | * Interface for the gui handling of FileUndoManager. |
48 | * This includes three events currently: |
49 | * - error when undoing a job |
50 | * - (until KF 5.78) confirm deletion before undoing a copy job |
51 | * - confirm deletion when the copied file has been modified afterwards |
52 | * |
53 | * By default UiInterface shows message boxes in all three cases; |
54 | * applications can reimplement this interface to provide different user interfaces. |
55 | */ |
56 | class KIOWIDGETS_EXPORT UiInterface |
57 | { |
58 | public: |
59 | UiInterface(); |
60 | virtual ~UiInterface(); |
61 | |
62 | /** |
63 | * Sets whether to show progress info when running the KIO jobs for undoing. |
64 | */ |
65 | void setShowProgressInfo(bool b); |
66 | /** |
67 | * @returns whether progress info dialogs are shown while undoing. |
68 | */ |
69 | bool showProgressInfo() const; |
70 | |
71 | /** |
72 | * Sets the parent widget to use for message boxes. |
73 | */ |
74 | void setParentWidget(QWidget *parentWidget); |
75 | |
76 | /** |
77 | * @return the parent widget passed to the last call to undo(parentWidget), or @c nullptr. |
78 | */ |
79 | QWidget *parentWidget() const; |
80 | |
81 | /** |
82 | * Called when an undo job errors; default implementation displays a message box. |
83 | */ |
84 | virtual void jobError(KIO::Job *job); |
85 | |
86 | /** |
87 | * Called when dest was modified since it was copied from src. |
88 | * Note that this is called after confirmDeletion. |
89 | * Return true if we should proceed with deleting dest. |
90 | */ |
91 | virtual bool copiedFileWasModified(const QUrl &src, const QUrl &dest, const QDateTime &srcTime, const QDateTime &destTime); |
92 | |
93 | // TODO KF6 replace hook with virtual AskUserActionInterface* askUserActionInterface(); // (does not take ownership) |
94 | enum { HookGetAskUserActionInterface = 1 }; |
95 | /** |
96 | * \internal, for future extensions |
97 | */ |
98 | virtual void virtual_hook(int id, void *data); |
99 | |
100 | private: |
101 | class UiInterfacePrivate; |
102 | UiInterfacePrivate *d; |
103 | }; |
104 | |
105 | /** |
106 | * Set a new UiInterface implementation. |
107 | * This deletes the previous one. |
108 | * @param ui the UiInterface instance, which becomes owned by the undo manager. |
109 | */ |
110 | void setUiInterface(UiInterface *ui); |
111 | |
112 | /** |
113 | * @return the UiInterface instance passed to setUiInterface. |
114 | * This is useful for calling setParentWidget on it. Never delete it! |
115 | */ |
116 | UiInterface *uiInterface() const; |
117 | |
118 | /** |
119 | * The type of job. |
120 | */ |
121 | enum CommandType { |
122 | Copy, |
123 | Move, |
124 | Rename, |
125 | Link, |
126 | Mkdir, |
127 | Trash, |
128 | Put, ///< Represents the creation of a file from data in memory. Used when pasting data from clipboard or drag-n-drop. @since 4.7 |
129 | Mkpath, ///< Represents a KIO::mkpath() job. @since 5.4 |
130 | BatchRename ///< Represents a KIO::batchRename() job. Used when renaming multiple files. @since 5.42 |
131 | }; |
132 | |
133 | /** |
134 | * Record this job while it's happening and add a command for it so that the user can undo it. |
135 | * The signal jobRecordingStarted() is emitted. |
136 | * @param op the type of job - which is also the type of command that will be created for it |
137 | * @param src list of source urls. This is empty for Mkdir, Mkpath, Put operations. |
138 | * @param dst destination url |
139 | * @param job the job to record |
140 | */ |
141 | void recordJob(CommandType op, const QList<QUrl> &src, const QUrl &dst, KIO::Job *job); |
142 | |
143 | /** |
144 | * Record this CopyJob while it's happening and add a command for it so that the user can undo it. |
145 | * The signal jobRecordingStarted() is emitted. |
146 | */ |
147 | void recordCopyJob(KIO::CopyJob *copyJob); |
148 | |
149 | /** |
150 | * @return true if undo is possible. Usually used for enabling/disabling the undo action. |
151 | * |
152 | * @since 5.79 |
153 | */ |
154 | bool isUndoAvailable() const; |
155 | |
156 | /** |
157 | * @return the current text for the undo action. |
158 | */ |
159 | QString undoText() const; |
160 | |
161 | /** |
162 | * These two functions are useful when wrapping FileUndoManager and adding custom commands. |
163 | * Each command has a unique ID. You can get a new serial number for a custom command |
164 | * with newCommandSerialNumber(), and then when you want to undo, check if the command |
165 | * FileUndoManager would undo is newer or older than your custom command. |
166 | */ |
167 | quint64 newCommandSerialNumber(); |
168 | quint64 currentCommandSerialNumber() const; |
169 | |
170 | public Q_SLOTS: |
171 | /** |
172 | * Undoes the last command |
173 | * Remember to call uiInterface()->setParentWidget(parentWidget) first, |
174 | * if you have multiple mainwindows. |
175 | * |
176 | * This operation is asynchronous. |
177 | * undoJobFinished will be emitted once the undo is complete. |
178 | */ |
179 | void undo(); // TODO pass QWindow*, for askUserInterface->askUserDelete and error handling etc. |
180 | |
181 | Q_SIGNALS: |
182 | /// Emitted when the value of isUndoAvailable() changes |
183 | void undoAvailable(bool avail); |
184 | |
185 | /// Emitted when the value of undoText() changes |
186 | void undoTextChanged(const QString &text); |
187 | |
188 | /// Emitted when an undo job finishes. Used for unit testing. |
189 | void undoJobFinished(); |
190 | |
191 | /** |
192 | * Emitted when a job recording has been started by FileUndoManager::recordJob() |
193 | * or FileUndoManager::recordCopyJob(). After the job recording has been finished, |
194 | * the signal jobRecordingFinished() will be emitted. |
195 | */ |
196 | void jobRecordingStarted(CommandType op); |
197 | |
198 | /** |
199 | * Emitted when a job that has been recorded by FileUndoManager::recordJob() |
200 | * or FileUndoManager::recordCopyJob has been finished. The command |
201 | * is now available for an undo-operation. |
202 | */ |
203 | void jobRecordingFinished(FileUndoManager::CommandType op); |
204 | |
205 | private: |
206 | KIOWIDGETS_NO_EXPORT FileUndoManager(); |
207 | KIOWIDGETS_NO_EXPORT ~FileUndoManager() override; |
208 | friend class FileUndoManagerSingleton; |
209 | |
210 | friend class UndoJob; |
211 | friend class CommandRecorder; |
212 | |
213 | friend class FileUndoManagerPrivate; |
214 | std::unique_ptr<FileUndoManagerPrivate> d; |
215 | }; |
216 | |
217 | } // namespace |
218 | |
219 | #endif |
220 | |