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