KTextEditor

katetextblock.h
1 /*
2  SPDX-FileCopyrightText: 2010 Christoph Cullmann <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef KATE_TEXTBLOCK_H
8 #define KATE_TEXTBLOCK_H
9 
10 #include "katetextline.h"
11 
12 #include <unordered_map>
13 #include <unordered_set>
14 
15 #include <QSet>
16 #include <QVarLengthArray>
17 #include <QVector>
18 
19 #include <ktexteditor/cursor.h>
20 #include <ktexteditor_export.h>
21 
22 namespace KTextEditor
23 {
24 class View;
25 }
26 
27 namespace Kate
28 {
29 class TextBuffer;
30 class TextCursor;
31 class TextRange;
32 class TextLineData;
33 typedef std::shared_ptr<TextLineData> TextLine;
34 
35 /**
36  * Class representing a text block.
37  * This is used to build up a Kate::TextBuffer.
38  * This class should only be used by TextBuffer/Cursor/Range.
39  */
40 class KTEXTEDITOR_EXPORT TextBlock
41 {
42 public:
43  /**
44  * Construct an empty text block.
45  * @param buffer parent text buffer
46  * @param startLine start line of this block
47  */
48  TextBlock(TextBuffer *buffer, int startLine);
49 
50  /**
51  * Destruct the text block
52  */
53  ~TextBlock();
54 
55  /**
56  * Start line of this block.
57  * @return start line of this block
58  */
59  int startLine() const
60  {
61  return m_startLine;
62  }
63 
64  /**
65  * Set start line of this block.
66  * @param startLine new start line of this block
67  */
68  void setStartLine(int startLine);
69 
70  /**
71  * Retrieve a text line.
72  * @param line wanted line number
73  * @return text line
74  */
75  TextLine line(int line) const;
76 
77  /**
78  * Retrieve length for @p line.
79  * @param line wanted line number
80  * @return length of line
81  */
82  int lineLength(int line) const
83  {
84  Q_ASSERT(line >= startLine() && (line - startLine()) < lines());
85  return m_lines[line - startLine()]->length();
86  }
87 
88  /**
89  * Append a new line with given text.
90  * @param textOfLine text of the line to append
91  */
92  void appendLine(const QString &textOfLine);
93 
94  /**
95  * Clear the lines.
96  */
97  void clearLines();
98 
99  /**
100  * Number of lines in this block.
101  * @return number of lines
102  */
103  int lines() const
104  {
105  return static_cast<int>(m_lines.size());
106  }
107 
108  /**
109  * Retrieve text of block.
110  * @param text for this block, lines separated by '\n'
111  */
112  void text(QString &text) const;
113 
114  /**
115  * Wrap line at given cursor position.
116  * @param position line/column as cursor where to wrap
117  * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block
118  */
119  void wrapLine(const KTextEditor::Cursor position, int fixStartLinesStartIndex);
120 
121  /**
122  * Unwrap given line.
123  * @param line line to unwrap
124  * @param previousBlock previous block, if any, if we unwrap first line in block, we need to have this
125  * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block or the previous one
126  */
127  void unwrapLine(int line, TextBlock *previousBlock, int fixStartLinesStartIndex);
128 
129  /**
130  * Insert text at given cursor position.
131  * @param position position where to insert text
132  * @param text text to insert
133  */
134  void insertText(const KTextEditor::Cursor position, const QString &text);
135 
136  /**
137  * Remove text at given range.
138  * @param range range of text to remove, must be on one line only.
139  * @param removedText will be filled with removed text
140  */
141  void removeText(KTextEditor::Range range, QString &removedText);
142 
143  /**
144  * Debug output, print whole block content with line numbers and line length
145  * @param blockIndex index of this block in buffer
146  */
147  void debugPrint(int blockIndex) const;
148 
149  /**
150  * Split given block. A new block will be created and all lines starting from the given index will
151  * be moved to it, together with the cursors belonging to it.
152  * @param fromLine line from which to split
153  * @return new block containing the lines + cursors removed from this one
154  */
155  TextBlock *splitBlock(int fromLine);
156 
157  /**
158  * Merge this block with given one, the given one must be a direct predecessor.
159  * @param targetBlock block to merge with
160  */
161  void mergeBlock(TextBlock *targetBlock);
162 
163  /**
164  * Delete the block content, delete all lines and delete all cursors not bound to ranges.
165  * This is used in destructor of TextBuffer, for fast cleanup. Only stuff remaining afterwards are cursors which are
166  * part of a range, TextBuffer will delete them itself...
167  */
168  void deleteBlockContent();
169 
170  /**
171  * Clear the block content, delete all lines, move all cursors not bound to range to given block at 0,0.
172  * This is used by clear() of TextBuffer.
173  * @param targetBlock empty target block for cursors
174  */
175  void clearBlockContent(TextBlock *targetBlock);
176 
177  /**
178  * Return all ranges in this block which might intersect the given line.
179  * @param line line to check intersection
180  * @param view only return ranges associated with given view
181  * @param rangesWithAttributeOnly ranges with attributes only?
182  * @return list of possible candidate ranges
183  */
184  QVector<TextRange *> rangesForLine(int line, KTextEditor::View *view, bool rangesWithAttributeOnly) const;
185 
186  /**
187  * Is the given range contained in this block?
188  * @param range range to check for
189  * @return contained in this blocks mapping?
190  */
191  bool containsRange(TextRange *range) const
192  {
193  return m_cachedLineForRanges.find(range) != m_cachedLineForRanges.end() || m_uncachedRanges.contains(range);
194  }
195 
196  /**
197  * Flag all modified text lines as saved on disk.
198  */
199  void markModifiedLinesAsSaved();
200 
201  /**
202  * Insert cursor into this block.
203  * @param cursor cursor to insert
204  */
206  {
207  m_cursors.insert(cursor);
208  }
209 
210  /**
211  * Remove cursor from this block.
212  * @param cursor cursor to remove
213  */
215  {
216  m_cursors.erase(cursor);
217  }
218 
219  /**
220  * Update a range from this block.
221  * Will move the range to right set, either cached for one-line ranges or not.
222  * @param range range to update
223  */
224  void updateRange(TextRange *range);
225 
226  /**
227  * Remove a range from this block.
228  * @param range range to remove
229  */
230  void removeRange(TextRange *range);
231 
232  /**
233  * Return all ranges in this block which might intersect the given line and only span one line.
234  * For them an internal fast lookup cache is hold.
235  * @param line line to check intersection
236  * @return set of ranges
237  */
239  {
240  line -= m_startLine;
241  if (line >= 0 && (size_t)line < m_cachedRangesForLine.size()) {
242  return m_cachedRangesForLine[line];
243  } else {
244  return QSet<TextRange *>();
245  }
246  }
247 
248 private:
249  /**
250  * parent text buffer
251  */
252  TextBuffer *m_buffer;
253 
254  /**
255  * Lines contained in this buffer. These are shared pointers.
256  * We need no sharing, use STL.
257  */
258  std::vector<Kate::TextLine> m_lines;
259 
260  /**
261  * Startline of this block
262  */
263  int m_startLine;
264 
265  /**
266  * Set of cursors for this block.
267  * We need no sharing, use STL.
268  */
269  std::unordered_set<TextCursor *> m_cursors;
270 
271  /**
272  * Contains for each line-offset the ranges that were cached into it.
273  * These ranges are fully contained by the line.
274  */
275  std::vector<QSet<TextRange *>> m_cachedRangesForLine;
276 
277  /**
278  * Maps for each cached range the line into which the range was cached.
279  */
280  std::unordered_map<TextRange *, int> m_cachedLineForRanges;
281 
282  /**
283  * This contains all the ranges that are not cached.
284  */
285  QVarLengthArray<TextRange *, 1> m_uncachedRanges;
286 };
287 
288 }
289 
290 #endif
QSet< TextRange * > cachedRangesForLine(int line) const
Return all ranges in this block which might intersect the given line and only span one line.
Class representing a 'clever' text cursor.
void insertCursor(Kate::TextCursor *cursor)
Insert cursor into this block.
Class representing a text buffer.
An object representing a section of text, from one Cursor to another.
The Cursor represents a position in a Document.
Definition: cursor.h:71
A text widget with KXMLGUIClient that represents a Document.
Definition: view.h:146
int lines() const
Number of lines in this block.
int lineLength(int line) const
Retrieve length for line.
Definition: katetextblock.h:82
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
Definition: katetextblock.h:22
Class representing a 'clever' text range.
Definition: katetextrange.h:36
Class representing a text block.
Definition: katetextblock.h:40
int startLine() const
Start line of this block.
Definition: katetextblock.h:59
void removeCursor(Kate::TextCursor *cursor)
Remove cursor from this block.
bool containsRange(TextRange *range) const
Is the given range contained in this block?
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 03:48:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.