1 | /* |
2 | SPDX-FileCopyrightText: 2013 Christoph Cullmann <cullmann@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #ifndef KATE_TEXTHISTORY_H |
8 | #define KATE_TEXTHISTORY_H |
9 | |
10 | #include <vector> |
11 | |
12 | #include <ktexteditor/movingcursor.h> |
13 | #include <ktexteditor/movingrange.h> |
14 | #include <ktexteditor/range.h> |
15 | |
16 | namespace Kate |
17 | { |
18 | class TextBuffer; |
19 | |
20 | /** |
21 | * Class representing the editing history of a TextBuffer |
22 | */ |
23 | class TextHistory |
24 | { |
25 | friend class TextBuffer; |
26 | friend class TextBlock; |
27 | |
28 | public: |
29 | /** |
30 | * Current revision, just relay the revision of the buffer |
31 | * @return current revision |
32 | */ |
33 | qint64 revision() const; |
34 | |
35 | /** |
36 | * Last revision the buffer got successful saved |
37 | * @return last revision buffer got saved, -1 if none |
38 | */ |
39 | qint64 lastSavedRevision() const |
40 | { |
41 | return m_lastSavedRevision; |
42 | } |
43 | |
44 | /** |
45 | * Lock a revision, this will keep it around until released again. |
46 | * But all revisions will always be cleared on buffer clear() (and therefor load()) |
47 | * @param revision revision to lock |
48 | */ |
49 | void lockRevision(qint64 revision); |
50 | |
51 | /** |
52 | * Release a revision. |
53 | * @param revision revision to release |
54 | */ |
55 | void unlockRevision(qint64 revision); |
56 | |
57 | /** |
58 | * Transform a cursor from one revision to an other. |
59 | * @param line line number of the cursor to transform |
60 | * @param column column number of the cursor to transform |
61 | * @param insertBehavior behavior of this cursor on insert of text at its position |
62 | * @param fromRevision from this revision we want to transform |
63 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
64 | */ |
65 | void transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1); |
66 | |
67 | /** |
68 | * Transform a range from one revision to an other. |
69 | * @param range range to transform |
70 | * @param insertBehaviors behavior of this range on insert of text at its position |
71 | * @param emptyBehavior behavior on becoming empty |
72 | * @param fromRevision from this revision we want to transform |
73 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
74 | */ |
75 | void transformRange(KTextEditor::Range &range, |
76 | KTextEditor::MovingRange::InsertBehaviors insertBehaviors, |
77 | KTextEditor::MovingRange::EmptyBehavior emptyBehavior, |
78 | qint64 fromRevision, |
79 | qint64 toRevision = -1); |
80 | |
81 | private: |
82 | /** |
83 | * Class representing one entry in the editing history. |
84 | */ |
85 | class Entry |
86 | { |
87 | public: |
88 | /** |
89 | * transform cursor for this history entry |
90 | * @param line line number of the cursor to transform |
91 | * @param column column number of the cursor to transform |
92 | * @param moveOnInsert behavior of this cursor on insert of text at its position |
93 | */ |
94 | void transformCursor(int &line, int &column, bool moveOnInsert) const; |
95 | |
96 | /** |
97 | * reverse transform cursor for this history entry |
98 | * @param line line number of the cursor to transform |
99 | * @param column column number of the cursor to transform |
100 | * @param moveOnInsert behavior of this cursor on insert of text at its position |
101 | */ |
102 | void reverseTransformCursor(int &line, int &column, bool moveOnInsert) const; |
103 | |
104 | /** |
105 | * Types of entries, matching editing primitives of buffer and placeholder |
106 | */ |
107 | enum Type { NoChange, WrapLine, UnwrapLine, InsertText, RemoveText }; |
108 | |
109 | /** |
110 | * Default Constructor, invalidates all fields |
111 | */ |
112 | Entry() |
113 | { |
114 | } |
115 | |
116 | /** |
117 | * Reference counter, how often ist this entry referenced from the outside? |
118 | */ |
119 | unsigned int referenceCounter = 0; |
120 | |
121 | /** |
122 | * Type of change |
123 | */ |
124 | Type type = NoChange; |
125 | |
126 | /** |
127 | * line the change occurred |
128 | */ |
129 | int line = -1; |
130 | |
131 | /** |
132 | * column the change occurred |
133 | */ |
134 | int column = -1; |
135 | |
136 | /** |
137 | * length of change (length of insert or removed text) |
138 | */ |
139 | int length = -1; |
140 | |
141 | /** |
142 | * old line length (needed for unwrap and insert) |
143 | */ |
144 | int oldLineLength = -1; |
145 | }; |
146 | |
147 | /** |
148 | * Construct an empty text history. |
149 | * @param buffer buffer this text history belongs to |
150 | */ |
151 | |
152 | explicit TextHistory(TextBuffer &buffer); |
153 | |
154 | /** |
155 | * Destruct the text history |
156 | */ |
157 | |
158 | ~TextHistory(); |
159 | |
160 | /** |
161 | * Clear the edit history, this is done on clear() in buffer. |
162 | */ |
163 | |
164 | void clear(); |
165 | |
166 | /** |
167 | * Set current revision as last saved revision |
168 | */ |
169 | |
170 | void setLastSavedRevision(); |
171 | |
172 | /** |
173 | * Notify about wrap line at given cursor position. |
174 | * @param position line/column as cursor where to wrap |
175 | */ |
176 | |
177 | void wrapLine(const KTextEditor::Cursor position); |
178 | |
179 | /** |
180 | * Notify about unwrap given line. |
181 | * @param line line to unwrap |
182 | * @param oldLineLength text length of the line in front of this one before this unwrap |
183 | */ |
184 | |
185 | void unwrapLine(int line, int oldLineLength); |
186 | |
187 | /** |
188 | * Notify about insert text at given cursor position. |
189 | * @param position position where to insert text |
190 | * @param length text length to be inserted |
191 | * @param oldLineLength text length of the line before this insert |
192 | */ |
193 | |
194 | void insertText(const KTextEditor::Cursor position, int length, int oldLineLength); |
195 | |
196 | /** |
197 | * Notify about remove text at given range. |
198 | * @param range range of text to remove, must be on one line only. |
199 | * @param oldLineLength text length of the line before this remove |
200 | */ |
201 | |
202 | void removeText(KTextEditor::Range range, int oldLineLength); |
203 | |
204 | /** |
205 | * Generic function to add a entry to the history. Is used by the above functions for the different editing primitives. |
206 | * @param entry new entry to add |
207 | */ |
208 | |
209 | void addEntry(const Entry &entry); |
210 | |
211 | private: |
212 | /** |
213 | * TextBuffer this history belongs to |
214 | */ |
215 | TextBuffer &m_buffer; |
216 | |
217 | /** |
218 | * Last revision the buffer got saved |
219 | */ |
220 | qint64 m_lastSavedRevision; |
221 | |
222 | /** |
223 | * history of edits |
224 | * needs no sharing, small entries |
225 | */ |
226 | std::vector<Entry> m_historyEntries; |
227 | |
228 | /** |
229 | * offset for the first entry in m_history, to which revision it really belongs? |
230 | */ |
231 | qint64 m_firstHistoryEntryRevision; |
232 | }; |
233 | |
234 | } |
235 | |
236 | #endif |
237 | |