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 we are about to remove those files. 88 * Return true if we should proceed with deleting them. 89 * Deprecated since 5.79, no longer called. 90 */ 91 virtual bool confirmDeletion(const QList<QUrl> &files); 92 93 /** 94 * Called when dest was modified since it was copied from src. 95 * Note that this is called after confirmDeletion. 96 * Return true if we should proceed with deleting dest. 97 */ 98 virtual bool copiedFileWasModified(const QUrl &src, const QUrl &dest, const QDateTime &srcTime, const QDateTime &destTime); 99 100 // TODO KF6 replace hook with virtual AskUserActionInterface* askUserActionInterface(); // (does not take ownership) 101 enum { HookGetAskUserActionInterface = 1 }; 102 /** 103 * \internal, for future extensions 104 */ 105 virtual void virtual_hook(int id, void *data); 106 107 private: 108 class UiInterfacePrivate; 109 UiInterfacePrivate *d; 110 }; 111 112 /** 113 * Set a new UiInterface implementation. 114 * This deletes the previous one. 115 * @param ui the UiInterface instance, which becomes owned by the undo manager. 116 */ 117 void setUiInterface(UiInterface *ui); 118 119 /** 120 * @return the UiInterface instance passed to setUiInterface. 121 * This is useful for calling setParentWidget on it. Never delete it! 122 */ 123 UiInterface *uiInterface() const; 124 125 /** 126 * The type of job. 127 * 128 * Put: @since 4.7, represents the creation of a file from data in memory. 129 * Used when pasting data from clipboard or drag-n-drop. 130 * Mkpath: @since 5.4, represents a KIO::mkpath() job. 131 * BatchRename: @since 5.42, represents a KIO::batchRename() job. Used when 132 * renaming multiple files. 133 */ 134 enum CommandType { Copy, Move, Rename, Link, Mkdir, Trash, Put, Mkpath, BatchRename }; 135 136 /** 137 * Record this job while it's happening and add a command for it so that the user can undo it. 138 * The signal jobRecordingStarted() is emitted. 139 * @param op the type of job - which is also the type of command that will be created for it 140 * @param src list of source urls. This is empty for Mkdir, Mkpath, Put operations. 141 * @param dst destination url 142 * @param job the job to record 143 */ 144 void recordJob(CommandType op, const QList<QUrl> &src, const QUrl &dst, KIO::Job *job); 145 146 /** 147 * Record this CopyJob while it's happening and add a command for it so that the user can undo it. 148 * The signal jobRecordingStarted() is emitted. 149 */ 150 void recordCopyJob(KIO::CopyJob *copyJob); 151 152 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79) 153 /** 154 * @return true if undo is possible. Usually used for enabling/disabling the undo action. 155 * 156 * @deprecated since 5.79, use KIO::FileUndoManager::isUndoAvailable() 157 */ 158 KIOWIDGETS_DEPRECATED_VERSION(5, 79, "Use KIO::FileUndoManager::isUndoAvailable()") 159 bool undoAvailable() const; // clazy:exclude=overloaded-signal 160 #endif 161 162 /** 163 * @return true if undo is possible. Usually used for enabling/disabling the undo action. 164 * 165 * @since 5.79 166 */ 167 bool isUndoAvailable() const; 168 169 /** 170 * @return the current text for the undo action. 171 */ 172 QString undoText() const; 173 174 /** 175 * These two functions are useful when wrapping FileUndoManager and adding custom commands. 176 * Each command has a unique ID. You can get a new serial number for a custom command 177 * with newCommandSerialNumber(), and then when you want to undo, check if the command 178 * FileUndoManager would undo is newer or older than your custom command. 179 */ 180 quint64 newCommandSerialNumber(); 181 quint64 currentCommandSerialNumber() const; 182 183 public Q_SLOTS: 184 /** 185 * Undoes the last command 186 * Remember to call uiInterface()->setParentWidget(parentWidget) first, 187 * if you have multiple mainwindows. 188 * 189 * This operation is asynchronous. 190 * undoJobFinished will be emitted once the undo is complete. 191 */ 192 void undo(); // TODO pass QWindow*, for askUserInterface->askUserDelete and error handling etc. 193 194 Q_SIGNALS: 195 /// Emitted when the value of isUndoAvailable() changes 196 void undoAvailable(bool avail); // clazy:exclude=overloaded-signal 197 198 /// Emitted when the value of undoText() changes 199 void undoTextChanged(const QString &text); 200 201 /// Emitted when an undo job finishes. Used for unit testing. 202 void undoJobFinished(); 203 204 /** 205 * Emitted when a job recording has been started by FileUndoManager::recordJob() 206 * or FileUndoManager::recordCopyJob(). After the job recording has been finished, 207 * the signal jobRecordingFinished() will be emitted. 208 * @since 4.2 209 */ 210 void jobRecordingStarted(CommandType op); 211 212 /** 213 * Emitted when a job that has been recorded by FileUndoManager::recordJob() 214 * or FileUndoManager::recordCopyJob has been finished. The command 215 * is now available for an undo-operation. 216 * @since 4.2 217 */ 218 // TODO KF6 signal arg should be fully-qualified 219 void jobRecordingFinished(CommandType op); // clazy:exclude=fully-qualified-moc-types 220 221 private: 222 FileUndoManager(); 223 ~FileUndoManager() override; 224 friend class FileUndoManagerSingleton; 225 226 friend class UndoJob; 227 friend class CommandRecorder; 228 229 friend class FileUndoManagerPrivate; 230 std::unique_ptr<FileUndoManagerPrivate> d; 231 }; 232 233 } // namespace 234 235 #endif 236