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 addUndoCommand in the undomanager.
91class CommandRecorder : public QObject
92{
93 Q_OBJECT
94public:
95 CommandRecorder(FileUndoManager::CommandType op, const QList<QUrl> &src, const QUrl &dst, std::function<void(UndoCommand)> onFinished, 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 std::function<void(UndoCommand)> m_onFinished;
108};
109
110enum UndoState {
111 MAKINGDIRS = 0,
112 MOVINGFILES,
113 STATINGFILE,
114 MOVINGLINK,
115 TRASHINGFILES,
116 REMOVINGDIRS,
117};
118
119// The private class is, exceptionally, a real QObject
120// so that it can be the class with the DBUS adaptor forwarding its signals.
121class FileUndoManagerPrivate : public QObject
122{
123 Q_OBJECT
124public:
125 explicit FileUndoManagerPrivate(FileUndoManager *qq);
126
127 ~FileUndoManagerPrivate() override = default;
128
129 void pushUndoCommand(const UndoCommand &cmd);
130 void pushRedoCommand(const UndoCommand &cmd);
131 void popRedoCommand();
132 void clearRedoStack();
133
134 void addDirToUpdate(const QUrl &url);
135
136 void startUndoOrRedo(bool redo);
137 void stepMakingDirectories();
138 void stepTrashingFiles(bool redo);
139 void stepRemovingDirectories();
140 void undoStepMovingFiles();
141 void redoStepMovingFiles();
142
143 /// called by FileUndoManagerAdaptor
144 QByteArray get() const;
145
146 friend class UndoJob;
147 /// called by UndoJob
148 void stopUndoOrRedo(bool step);
149
150 friend class UndoCommandRecorder;
151 /// called by UndoCommandRecorder
152 void addUndoCommand(const UndoCommand &cmd);
153
154 QStack<UndoCommand> m_undoCommands;
155 QStack<UndoCommand> m_redoCommands;
156
157 KIO::Job *m_currentJob = nullptr;
158 QStack<QUrl> m_dirStack;
159 QStack<QUrl> m_dirCleanupStack;
160 QStack<QUrl> m_fileTrashStack;
161 QList<QUrl> m_dirsToUpdate;
162 std::unique_ptr<FileUndoManager::UiInterface> m_uiInterface;
163
164 UndoJob *m_undoJob = nullptr;
165 quint64 m_nextCommandIndex = 0;
166
167 FileUndoManager *const q;
168
169 UndoCommand m_currentCmd;
170 UndoCommand m_cmdToBePushed;
171 UndoState m_undoState;
172 bool m_lock = false;
173 bool m_connectedToAskUserInterface = false;
174
175 // DBUS interface
176Q_SIGNALS:
177 /// DBUS signal
178 void push(const QByteArray &command);
179 /// DBUS signal
180 void pop();
181 /// DBUS signal
182 void lock();
183 /// DBUS signal
184 void unlock();
185
186public Q_SLOTS:
187 // Those four slots are connected to DBUS signals
188 void slotPushUndoCommand(QByteArray);
189 void slotPopUndoCommand();
190 void slotLock();
191 void slotUnlock();
192
193 void processStep(bool redo);
194 void slotUndoResult(KJob *);
195 void slotRedoResult(KJob *);
196};
197
198} // namespace
199
200#endif /* FILEUNDOMANAGER_P_H */
201

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