1 | /* |
2 | SPDX-FileCopyrightText: 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #ifndef KATEUNDOMANAGER_H |
8 | #define KATEUNDOMANAGER_H |
9 | |
10 | #include "kateundo.h" |
11 | #include <QObject> |
12 | |
13 | #include <ktexteditor_export.h> |
14 | |
15 | #include <QList> |
16 | |
17 | #include <optional> |
18 | |
19 | namespace KTextEditor |
20 | { |
21 | class DocumentPrivate; |
22 | } |
23 | class KateUndo; |
24 | class KateUndoGroup; |
25 | |
26 | namespace KTextEditor |
27 | { |
28 | class Document; |
29 | class View; |
30 | class ViewPrivate; |
31 | class Cursor; |
32 | } |
33 | |
34 | /** |
35 | * KateUndoManager implements a document's history. It is in either of the two states: |
36 | * @li the default state, which allows rolling back and forth the history of a document, and |
37 | * @li a state in which a new element is being added to the history. |
38 | * |
39 | * The state of the KateUndomanager can be switched using editStart() and editEnd(). |
40 | */ |
41 | class KateUndoManager : public QObject |
42 | { |
43 | Q_OBJECT |
44 | |
45 | public: |
46 | /** |
47 | * Creates a clean undo history. |
48 | * |
49 | * @param doc the document the KateUndoManager will belong to |
50 | */ |
51 | explicit KateUndoManager(KTextEditor::DocumentPrivate *doc); |
52 | |
53 | ~KateUndoManager() override; |
54 | |
55 | KTextEditor::DocumentPrivate *document() |
56 | { |
57 | return m_document; |
58 | } |
59 | |
60 | /** |
61 | * Returns how many undo() actions can be performed. |
62 | * |
63 | * @return the number of undo groups which can be undone |
64 | */ |
65 | uint undoCount() const; |
66 | |
67 | /** |
68 | * Returns how many redo() actions can be performed. |
69 | * |
70 | * @return the number of undo groups which can be redone |
71 | */ |
72 | uint redoCount() const; |
73 | |
74 | /** |
75 | * Prevent latest KateUndoGroup from being merged with the next one. |
76 | */ |
77 | KTEXTEDITOR_EXPORT void undoSafePoint(); |
78 | |
79 | /** |
80 | * Allows or disallows merging of "complex" undo groups. |
81 | * |
82 | * When an undo group contains different types of undo items, it is considered |
83 | * a "complex" group. |
84 | * |
85 | * @param allow whether complex merging is allowed |
86 | */ |
87 | void setAllowComplexMerge(bool allow); |
88 | |
89 | bool isActive() const |
90 | { |
91 | return m_isActive; |
92 | } |
93 | |
94 | void setModified(bool modified); |
95 | void updateConfig(); |
96 | KTEXTEDITOR_EXPORT void updateLineModifications(); |
97 | |
98 | /** |
99 | * Used by the swap file recovery, this function afterwards manipulates |
100 | * the undo/redo cursors of the last KateUndoGroup. |
101 | * This function should not be used other than by Kate::SwapFile. |
102 | * @param undoCursor the undo cursor |
103 | * @param redoCursor the redo cursor |
104 | */ |
105 | void setUndoRedoCursorsOfLastGroup(const KTextEditor::Cursor undoCursor, const KTextEditor::Cursor redoCursor); |
106 | |
107 | /** |
108 | * Returns the redo cursor of the last undo group. |
109 | * Needed for the swap file recovery. |
110 | */ |
111 | KTextEditor::Cursor lastRedoCursor() const; |
112 | |
113 | public Q_SLOTS: |
114 | /** |
115 | * Undo the latest undo group. |
116 | * |
117 | * Make sure isDefaultState() is true when calling this method. |
118 | */ |
119 | void undo(); |
120 | |
121 | /** |
122 | * Redo the latest undo group. |
123 | * |
124 | * Make sure isDefaultState() is true when calling this method. |
125 | */ |
126 | void redo(); |
127 | |
128 | KTEXTEDITOR_EXPORT void clearUndo(); |
129 | KTEXTEDITOR_EXPORT void clearRedo(); |
130 | |
131 | /** |
132 | * Notify KateUndoManager about the beginning of an edit. |
133 | */ |
134 | void editStart(); |
135 | |
136 | /** |
137 | * Notify KateUndoManager about the end of an edit. |
138 | */ |
139 | void editEnd(); |
140 | |
141 | void startUndo(); |
142 | void endUndo(); |
143 | |
144 | void inputMethodStart(); |
145 | void inputMethodEnd(); |
146 | |
147 | /** |
148 | * Notify KateUndoManager that text was inserted. |
149 | */ |
150 | void slotTextInserted(int line, int col, const QString &s, const Kate::TextLine &tl); |
151 | |
152 | /** |
153 | * Notify KateUndoManager that text was removed. |
154 | */ |
155 | void slotTextRemoved(int line, int col, const QString &s, const Kate::TextLine &tl); |
156 | |
157 | /** |
158 | * Notify KateUndoManager that a line was marked as autowrapped. |
159 | */ |
160 | void slotMarkLineAutoWrapped(int line, bool autowrapped); |
161 | |
162 | /** |
163 | * Notify KateUndoManager that a line was wrapped. |
164 | */ |
165 | void slotLineWrapped(int line, int col, int length, bool newLine, const Kate::TextLine &tl); |
166 | |
167 | /** |
168 | * Notify KateUndoManager that a line was un-wrapped. |
169 | */ |
170 | void slotLineUnWrapped(int line, int col, int length, bool lineRemoved, const Kate::TextLine &tl, const Kate::TextLine &nextLine); |
171 | |
172 | /** |
173 | * Notify KateUndoManager that a line was inserted. |
174 | */ |
175 | void slotLineInserted(int line, const QString &s); |
176 | |
177 | /** |
178 | * Notify KateUndoManager that a line was removed. |
179 | */ |
180 | void slotLineRemoved(int line, const QString &s, const Kate::TextLine &tl); |
181 | |
182 | Q_SIGNALS: |
183 | void undoChanged(); |
184 | void undoStart(KTextEditor::Document *); |
185 | void undoEnd(KTextEditor::Document *); |
186 | void redoStart(KTextEditor::Document *); |
187 | void redoEnd(KTextEditor::Document *); |
188 | void isActiveChanged(bool enabled); |
189 | |
190 | private Q_SLOTS: |
191 | /** |
192 | * @short Add an undo item to the current undo group. |
193 | * |
194 | * @param undo undo item to be added, must be non-null |
195 | */ |
196 | void addUndoItem(UndoItem undo); |
197 | |
198 | void setActive(bool active); |
199 | |
200 | void updateModified(); |
201 | |
202 | void undoCancel(); |
203 | void viewCreated(KTextEditor::Document *, KTextEditor::View *newView) const; |
204 | |
205 | private: |
206 | KTEXTEDITOR_NO_EXPORT |
207 | KTextEditor::ViewPrivate *activeView(); |
208 | |
209 | private: |
210 | KTextEditor::DocumentPrivate *m_document = nullptr; |
211 | bool m_undoComplexMerge = false; |
212 | bool m_isActive = true; |
213 | std::optional<KateUndoGroup> m_editCurrentUndo; |
214 | std::vector<KateUndoGroup> undoItems; |
215 | std::vector<KateUndoGroup> redoItems; |
216 | // these two variables are for resetting the document to |
217 | // non-modified if all changes have been undone... |
218 | KateUndoGroup *lastUndoGroupWhenSaved = nullptr; |
219 | KateUndoGroup *lastRedoGroupWhenSaved = nullptr; |
220 | bool docWasSavedWhenUndoWasEmpty = true; |
221 | bool docWasSavedWhenRedoWasEmpty = true; |
222 | |
223 | // saved undo items that are used to restore state on doc reload |
224 | std::vector<KateUndoGroup> savedUndoItems; |
225 | std::vector<KateUndoGroup> savedRedoItems; |
226 | QByteArray docChecksumBeforeReload; |
227 | }; |
228 | |
229 | #endif |
230 | |