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 FILEUNDOMANAGER_P_H
10#define FILEUNDOMANAGER_P_H
11
12#include "fileundomanager.h"
13#include <QDateTime>
14#include <QQueue>
15#include <QStack>
16
17class KJob;
18
19namespace KIO
20{
21class FileUndoManagerAdaptor;
22
23struct BasicOperation {
24 enum Type {
25 File,
26 Link,
27 Directory,
28 /**
29 * Used with BatchRenameJob, it doesn't stat the files/dirs it's renaming,
30 * so the file/dir distinction isn't available
31 */
32 Item,
33 };
34
35 // for QDataStream deserialization
36 BasicOperation()
37 {
38 }
39 BasicOperation(Type type, bool renamed, const QUrl &src, const QUrl &dst, const QDateTime &mtime, const QString &target = {})
40 : m_valid(true)
41 , m_renamed(renamed)
42 , m_type(type)
43 , m_src(src)
44 , m_dst(dst)
45 , m_target(target)
46 , m_mtime(mtime)
47 {
48 }
49
50 bool m_valid = false;
51 bool m_renamed;
52
53 Type m_type : 2;
54
55 QUrl m_src;
56 QUrl m_dst;
57 QString m_target;
58 QDateTime m_mtime;
59};
60
61class UndoCommand
62{
63public:
64 UndoCommand() = default;
65
66 UndoCommand(FileUndoManager::CommandType type, const QList<QUrl> &src, const QUrl &dst, qint64 serialNumber)
67 : m_valid(true)
68 , m_type(type)
69 , m_src(src)
70 , m_dst(dst)
71 , m_serialNumber(serialNumber)
72 {
73 }
74
75 // TODO: is ::TRASH missing?
76 bool isMoveOrRename() const
77 {
78 return m_type == FileUndoManager::Move || m_type == FileUndoManager::Rename;
79 }
80
81 bool m_valid = false;
82 FileUndoManager::CommandType m_type;
83 QQueue<BasicOperation> m_opQueue;
84 QList<QUrl> m_src;
85 QUrl m_dst;
86 quint64 m_serialNumber = 0;
87};
88
89// This class listens to a job, collects info while it's running (for copyjobs)
90// and when the job terminates, on success, it calls addCommand in the undomanager.
91class CommandRecorder : public QObject
92{
93 Q_OBJECT
94public:
95 CommandRecorder(FileUndoManager::CommandType op, const QList<QUrl> &src, const QUrl &dst, KIO::Job *job);
96
97private Q_SLOTS:
98 void slotResult(KJob *job);
99
100 void slotCopyingDone(KIO::Job *, const QUrl &from, const QUrl &to, const QDateTime &, bool directory, bool renamed);
101 void slotCopyingLinkDone(KIO::Job *, const QUrl &from, const QString &target, const QUrl &to);
102 void slotDirectoryCreated(const QUrl &url);
103 void slotBatchRenamingDone(const QUrl &from, const QUrl &to);
104
105private:
106 UndoCommand m_cmd;
107};
108
109enum UndoState {
110 MAKINGDIRS = 0,
111 MOVINGFILES,
112 STATINGFILE,
113 REMOVINGDIRS,
114 REMOVINGLINKS,
115};
116
117// The private class is, exceptionally, a real QObject
118// so that it can be the class with the DBUS adaptor forwarding its signals.
119class FileUndoManagerPrivate : public QObject
120{
121 Q_OBJECT
122public:
123 explicit FileUndoManagerPrivate(FileUndoManager *qq);
124
125 ~FileUndoManagerPrivate() override = default;
126
127 void pushCommand(const UndoCommand &cmd);
128
129 void addDirToUpdate(const QUrl &url);
130
131 void startUndo();
132 void stepMakingDirectories();
133 void stepMovingFiles();
134 void stepRemovingLinks();
135 void stepRemovingDirectories();
136
137 /// called by FileUndoManagerAdaptor
138 QByteArray get() const;
139
140 friend class UndoJob;
141 /// called by UndoJob
142 void stopUndo(bool step);
143
144 friend class UndoCommandRecorder;
145 /// called by UndoCommandRecorder
146 void addCommand(const UndoCommand &cmd);
147
148 QStack<UndoCommand> m_commands;
149
150 KIO::Job *m_currentJob = nullptr;
151 QStack<QUrl> m_dirStack;
152 QStack<QUrl> m_dirCleanupStack;
153 QStack<QUrl> m_fileCleanupStack; // files and links
154 QList<QUrl> m_dirsToUpdate;
155 std::unique_ptr<FileUndoManager::UiInterface> m_uiInterface;
156
157 UndoJob *m_undoJob = nullptr;
158 quint64 m_nextCommandIndex = 0;
159
160 FileUndoManager *const q;
161
162 UndoCommand m_currentCmd;
163 UndoState m_undoState;
164 bool m_lock = false;
165 bool m_connectedToAskUserInterface = false;
166
167 // DBUS interface
168Q_SIGNALS:
169 /// DBUS signal
170 void push(const QByteArray &command);
171 /// DBUS signal
172 void pop();
173 /// DBUS signal
174 void lock();
175 /// DBUS signal
176 void unlock();
177
178public Q_SLOTS:
179 // Those four slots are connected to DBUS signals
180 void slotPush(QByteArray);
181 void slotPop();
182 void slotLock();
183 void slotUnlock();
184
185 void undoStep();
186 void slotResult(KJob *);
187};
188
189} // namespace
190
191#endif /* FILEUNDOMANAGER_P_H */
192

source code of kio/src/widgets/fileundomanager_p.h