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_TEXTBLOCK_H |
22 | #define KATE_TEXTBLOCK_H |
23 | |
24 | #include <QtCore/QVector> |
25 | #include <QtCore/QSet> |
26 | |
27 | #include "katepartprivate_export.h" |
28 | #include <ktexteditor/cursor.h> |
29 | #include "katetextline.h" |
30 | |
31 | namespace Kate { |
32 | |
33 | class TextBuffer; |
34 | class TextCursor; |
35 | class ; |
36 | |
37 | /** |
38 | * Class representing a text block. |
39 | * This is used to build up a Kate::TextBuffer. |
40 | * This class should only be used by TextBuffer/Cursor/Range. |
41 | */ |
42 | class KATEPART_TESTS_EXPORT TextBlock { |
43 | public: |
44 | /** |
45 | * Construct an empty text block. |
46 | * @param buffer parent text buffer |
47 | * @param startLine start line of this block |
48 | */ |
49 | TextBlock (TextBuffer *buffer, int startLine); |
50 | |
51 | /** |
52 | * Destruct the text block |
53 | */ |
54 | ~TextBlock (); |
55 | |
56 | /** |
57 | * Start line of this block. |
58 | * @return start line of this block |
59 | */ |
60 | int startLine () const { return m_startLine; } |
61 | |
62 | /** |
63 | * Set start line of this block. |
64 | * @param startLine new start line of this block |
65 | */ |
66 | void setStartLine (int startLine); |
67 | |
68 | /** |
69 | * Retrieve a text line. |
70 | * @param line wanted line number |
71 | * @return text line |
72 | */ |
73 | TextLine line (int line) const; |
74 | |
75 | /** |
76 | * Append a new line with given text. |
77 | * @param textOfLine text of the line to append |
78 | */ |
79 | void appendLine (const QString &textOfLine); |
80 | |
81 | /** |
82 | * Clear the lines. |
83 | */ |
84 | void clearLines (); |
85 | |
86 | /** |
87 | * Number of lines in this block. |
88 | * @return number of lines |
89 | */ |
90 | int lines () const { return m_lines.size(); } |
91 | |
92 | /** |
93 | * Retrieve text of block. |
94 | * @param text for this block, lines separated by '\n' |
95 | */ |
96 | void text (QString &text) const; |
97 | |
98 | /** |
99 | * Wrap line at given cursor position. |
100 | * @param position line/column as cursor where to wrap |
101 | * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block |
102 | */ |
103 | void wrapLine (const KTextEditor::Cursor &position, int fixStartLinesStartIndex); |
104 | |
105 | /** |
106 | * Unwrap given line. |
107 | * @param line line to unwrap |
108 | * @param previousBlock previous block, if any, if we unwrap first line in block, we need to have this |
109 | * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block or the previous one |
110 | */ |
111 | void unwrapLine (int line, TextBlock *previousBlock, int fixStartLinesStartIndex); |
112 | |
113 | /** |
114 | * Insert text at given cursor position. |
115 | * @param position position where to insert text |
116 | * @param text text to insert |
117 | */ |
118 | void insertText (const KTextEditor::Cursor &position, const QString &text); |
119 | |
120 | /** |
121 | * Remove text at given range. |
122 | * @param range range of text to remove, must be on one line only. |
123 | * @param removedText will be filled with removed text |
124 | */ |
125 | void removeText (const KTextEditor::Range &range, QString &removedText); |
126 | |
127 | /** |
128 | * Debug output, print whole block content with line numbers and line length |
129 | * @param blockIndex index of this block in buffer |
130 | */ |
131 | void debugPrint (int blockIndex) const; |
132 | |
133 | /** |
134 | * Split given block. A new block will be created and all lines starting from the given index will |
135 | * be moved to it, together with the cursors belonging to it. |
136 | * @param fromLine line from which to split |
137 | * @return new block containing the lines + cursors removed from this one |
138 | */ |
139 | TextBlock *splitBlock (int fromLine); |
140 | |
141 | /** |
142 | * Merge this block with given one, the given one must be a direct predecessor. |
143 | * @param targetBlock block to merge with |
144 | */ |
145 | void mergeBlock (TextBlock *targetBlock); |
146 | |
147 | /** |
148 | * Delete the block content, delete all lines and delete all cursors not bound to ranges. |
149 | * This is used in destructor of TextBuffer, for fast cleanup. Only stuff remaining afterwards are cursors which are |
150 | * part of a range, TextBuffer will delete them itself... |
151 | */ |
152 | void deleteBlockContent (); |
153 | |
154 | /** |
155 | * Clear the block content, delete all lines, move all cursors not bound to range to given block at 0,0. |
156 | * This is used by clear() of TextBuffer. |
157 | * @param targetBlock empty target block for cursors |
158 | */ |
159 | void clearBlockContent (TextBlock *targetBlock); |
160 | |
161 | /** |
162 | * Return all ranges in this block which might intersect the given line. |
163 | * @param line line to check intersection |
164 | * @return list of sets of possible candidate ranges |
165 | */ |
166 | QList<QSet<TextRange*> > rangesForLine (int line) const { |
167 | return QList<QSet<TextRange*> >() << m_uncachedRanges << cachedRangesForLine(line); |
168 | } |
169 | |
170 | /** |
171 | * Is the given range contained in this block? |
172 | * @param range range to check for |
173 | * @return contained in this blocks mapping? |
174 | */ |
175 | bool (TextRange* range) const { |
176 | return m_cachedLineForRanges.contains(range) || m_uncachedRanges.contains(range); |
177 | } |
178 | |
179 | /** |
180 | * Flag all modified text lines as saved on disk. |
181 | */ |
182 | void markModifiedLinesAsSaved (); |
183 | |
184 | /** |
185 | * Insert cursor into this block. |
186 | * @param cursor cursor to insert |
187 | */ |
188 | void insertCursor (Kate::TextCursor *cursor) { m_cursors.insert (cursor); } |
189 | |
190 | /** |
191 | * Remove cursor from this block. |
192 | * @param cursor cursor to remove |
193 | */ |
194 | void removeCursor (Kate::TextCursor *cursor) { m_cursors.remove (cursor); } |
195 | |
196 | /** |
197 | * Update a range from this block. |
198 | * Will move the range to right set, either cached for one-line ranges or not. |
199 | * @param range range to update |
200 | */ |
201 | void (TextRange* range); |
202 | |
203 | /** |
204 | * Remove a range from this block. |
205 | * @param range range to remove |
206 | */ |
207 | void (TextRange* range); |
208 | |
209 | /** |
210 | * Return all ranges in this block which might intersect the given line and only span one line. |
211 | * For them an internal fast lookup cache is hold. |
212 | * @param line line to check intersection |
213 | * @return set of ranges |
214 | */ |
215 | QSet<TextRange*> cachedRangesForLine (int line) const { |
216 | line -= m_startLine; |
217 | if(line >= 0 && line < m_cachedRangesForLine.size()) |
218 | return m_cachedRangesForLine[line]; |
219 | else |
220 | return QSet<TextRange*>(); |
221 | } |
222 | |
223 | private: |
224 | /** |
225 | * parent text buffer |
226 | */ |
227 | TextBuffer *m_buffer; |
228 | |
229 | /** |
230 | * Lines contained in this buffer. These are shared pointers. |
231 | */ |
232 | QVector<Kate::TextLine> m_lines; |
233 | |
234 | /** |
235 | * Startline of this block |
236 | */ |
237 | int m_startLine; |
238 | |
239 | /** |
240 | * Set of cursors for this block. |
241 | */ |
242 | QSet<TextCursor *> m_cursors; |
243 | |
244 | /** |
245 | * Contains for each line-offset the ranges that were cached into it. |
246 | * These ranges are fully contained by the line. |
247 | */ |
248 | QVector<QSet<TextRange *> > m_cachedRangesForLine; |
249 | |
250 | /** |
251 | * Maps for each cached range the line into which the range was cached. |
252 | */ |
253 | QHash<TextRange *, int> m_cachedLineForRanges; |
254 | |
255 | /** |
256 | * This contains all the ranges that are not cached. |
257 | */ |
258 | QSet<TextRange *> m_uncachedRanges; |
259 | }; |
260 | |
261 | } |
262 | |
263 | #endif |
264 | |