File indexing completed on 2025-04-20 09:44:17
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2000 Simon Hausmann <hausmann@kde.org> 0004 SPDX-FileCopyrightText: 2006, 2008 David Faure <faure@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef FILEUNDOMANAGER_P_H 0010 #define FILEUNDOMANAGER_P_H 0011 0012 #include "fileundomanager.h" 0013 #include <QDateTime> 0014 #include <QQueue> 0015 #include <QStack> 0016 0017 class KJob; 0018 0019 namespace KIO 0020 { 0021 class FileUndoManagerAdaptor; 0022 0023 struct BasicOperation { 0024 enum Type { 0025 File, 0026 Link, 0027 Directory, 0028 /** 0029 * Used with BatchRenameJob, it doesn't stat the files/dirs it's renaming, 0030 * so the file/dir distinction isn't available 0031 */ 0032 Item, 0033 }; 0034 0035 // for QDataStream deserialization 0036 BasicOperation() 0037 { 0038 } 0039 BasicOperation(Type type, bool renamed, const QUrl &src, const QUrl &dst, const QDateTime &mtime, const QString &target = {}) 0040 : m_valid(true) 0041 , m_renamed(renamed) 0042 , m_type(type) 0043 , m_src(src) 0044 , m_dst(dst) 0045 , m_target(target) 0046 , m_mtime(mtime) 0047 { 0048 } 0049 0050 bool m_valid = false; 0051 bool m_renamed; 0052 0053 Type m_type : 2; 0054 0055 QUrl m_src; 0056 QUrl m_dst; 0057 QString m_target; 0058 QDateTime m_mtime; 0059 }; 0060 0061 class UndoCommand 0062 { 0063 public: 0064 UndoCommand() = default; 0065 0066 UndoCommand(FileUndoManager::CommandType type, const QList<QUrl> &src, const QUrl &dst, qint64 serialNumber) 0067 : m_valid(true) 0068 , m_type(type) 0069 , m_src(src) 0070 , m_dst(dst) 0071 , m_serialNumber(serialNumber) 0072 { 0073 } 0074 0075 // TODO: is ::TRASH missing? 0076 bool isMoveOrRename() const 0077 { 0078 return m_type == FileUndoManager::Move || m_type == FileUndoManager::Rename; 0079 } 0080 0081 bool m_valid = false; 0082 FileUndoManager::CommandType m_type; 0083 QQueue<BasicOperation> m_opQueue; 0084 QList<QUrl> m_src; 0085 QUrl m_dst; 0086 quint64 m_serialNumber = 0; 0087 }; 0088 0089 // This class listens to a job, collects info while it's running (for copyjobs) 0090 // and when the job terminates, on success, it calls addCommand in the undomanager. 0091 class CommandRecorder : public QObject 0092 { 0093 Q_OBJECT 0094 public: 0095 CommandRecorder(FileUndoManager::CommandType op, const QList<QUrl> &src, const QUrl &dst, KIO::Job *job); 0096 0097 private Q_SLOTS: 0098 void slotResult(KJob *job); 0099 0100 void slotCopyingDone(KIO::Job *, const QUrl &from, const QUrl &to, const QDateTime &, bool directory, bool renamed); 0101 void slotCopyingLinkDone(KIO::Job *, const QUrl &from, const QString &target, const QUrl &to); 0102 void slotDirectoryCreated(const QUrl &url); 0103 void slotBatchRenamingDone(const QUrl &from, const QUrl &to); 0104 0105 private: 0106 UndoCommand m_cmd; 0107 }; 0108 0109 enum UndoState { 0110 MAKINGDIRS = 0, 0111 MOVINGFILES, 0112 STATINGFILE, 0113 REMOVINGDIRS, 0114 REMOVINGLINKS, 0115 }; 0116 0117 // The private class is, exceptionally, a real QObject 0118 // so that it can be the class with the DBUS adaptor forwarding its signals. 0119 class FileUndoManagerPrivate : public QObject 0120 { 0121 Q_OBJECT 0122 public: 0123 explicit FileUndoManagerPrivate(FileUndoManager *qq); 0124 0125 ~FileUndoManagerPrivate() override = default; 0126 0127 void pushCommand(const UndoCommand &cmd); 0128 0129 void addDirToUpdate(const QUrl &url); 0130 0131 void startUndo(); 0132 void stepMakingDirectories(); 0133 void stepMovingFiles(); 0134 void stepRemovingLinks(); 0135 void stepRemovingDirectories(); 0136 0137 /// called by FileUndoManagerAdaptor 0138 QByteArray get() const; 0139 0140 friend class UndoJob; 0141 /// called by UndoJob 0142 void stopUndo(bool step); 0143 0144 friend class UndoCommandRecorder; 0145 /// called by UndoCommandRecorder 0146 void addCommand(const UndoCommand &cmd); 0147 0148 QStack<UndoCommand> m_commands; 0149 0150 KIO::Job *m_currentJob = nullptr; 0151 QStack<QUrl> m_dirStack; 0152 QStack<QUrl> m_dirCleanupStack; 0153 QStack<QUrl> m_fileCleanupStack; // files and links 0154 QList<QUrl> m_dirsToUpdate; 0155 std::unique_ptr<FileUndoManager::UiInterface> m_uiInterface; 0156 0157 UndoJob *m_undoJob = nullptr; 0158 quint64 m_nextCommandIndex = 0; 0159 0160 FileUndoManager *const q; 0161 0162 UndoCommand m_currentCmd; 0163 UndoState m_undoState; 0164 bool m_lock = false; 0165 bool m_connectedToAskUserInterface = false; 0166 0167 // DBUS interface 0168 Q_SIGNALS: 0169 /// DBUS signal 0170 void push(const QByteArray &command); 0171 /// DBUS signal 0172 void pop(); 0173 /// DBUS signal 0174 void lock(); 0175 /// DBUS signal 0176 void unlock(); 0177 0178 public Q_SLOTS: 0179 // Those four slots are connected to DBUS signals 0180 void slotPush(QByteArray); 0181 void slotPop(); 0182 void slotLock(); 0183 void slotUnlock(); 0184 0185 void undoStep(); 0186 void slotResult(KJob *); 0187 }; 0188 0189 } // namespace 0190 0191 #endif /* FILEUNDOMANAGER_P_H */