1 | /* |
2 | SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org> |
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 <QList> |
13 | |
14 | #include <ktexteditor/cursor.h> |
15 | #include <ktexteditor_export.h> |
16 | |
17 | namespace KTextEditor |
18 | { |
19 | class View; |
20 | } |
21 | |
22 | namespace Kate |
23 | { |
24 | class TextBuffer; |
25 | class TextCursor; |
26 | class ; |
27 | |
28 | /** |
29 | * Class representing a text block. |
30 | * This is used to build up a Kate::TextBuffer. |
31 | * This class should only be used by TextBuffer/Cursor/Range. |
32 | */ |
33 | class TextBlock |
34 | { |
35 | friend class TextBuffer; |
36 | |
37 | public: |
38 | /** |
39 | * Construct an empty text block. |
40 | * @param buffer parent text buffer |
41 | * @param startLine start line of this block |
42 | */ |
43 | TextBlock(TextBuffer *buffer, int blockIndex); |
44 | |
45 | /** |
46 | * Destruct the text block |
47 | */ |
48 | ~TextBlock(); |
49 | |
50 | /** |
51 | * Start line of this block. |
52 | * @return start line of this block |
53 | */ |
54 | KTEXTEDITOR_EXPORT int startLine() const; |
55 | |
56 | void setBlockIndex(int index) |
57 | { |
58 | m_blockIndex = index; |
59 | } |
60 | |
61 | /** |
62 | * Retrieve a text line. |
63 | * @param line wanted line number |
64 | * @return text line |
65 | */ |
66 | TextLine line(int line) const; |
67 | |
68 | /** |
69 | * Transfer all non text attributes for the given line from the given text line to the one in the block. |
70 | * @param line line number to set attributes |
71 | * @param textLine line reference to get attributes from |
72 | */ |
73 | void setLineMetaData(int line, const TextLine &textLine); |
74 | |
75 | /** |
76 | * Retrieve length for @p line. |
77 | * @param line wanted line number |
78 | * @return length of line |
79 | */ |
80 | int lineLength(int line) const |
81 | { |
82 | Q_ASSERT(line >= startLine() && (line - startLine()) < lines()); |
83 | return m_lines[line - startLine()].length(); |
84 | } |
85 | |
86 | /** |
87 | * Append a new line with given text. |
88 | * @param textOfLine text of the line to append |
89 | */ |
90 | void appendLine(const QString &textOfLine); |
91 | |
92 | /** |
93 | * Clear the lines. |
94 | */ |
95 | void clearLines(); |
96 | |
97 | /** |
98 | * Number of lines in this block. |
99 | * @return number of lines |
100 | */ |
101 | int lines() const |
102 | { |
103 | return static_cast<int>(m_lines.size()); |
104 | } |
105 | |
106 | /** |
107 | * Retrieve text of block. |
108 | * @param text for this block, lines separated by '\n' |
109 | */ |
110 | void text(QString &text) const; |
111 | |
112 | /** |
113 | * Wrap line at given cursor position. |
114 | * @param position line/column as cursor where to wrap |
115 | * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block |
116 | */ |
117 | void wrapLine(const KTextEditor::Cursor position, int fixStartLinesStartIndex); |
118 | |
119 | /** |
120 | * Unwrap given line. |
121 | * @param line line to unwrap |
122 | * @param previousBlock previous block, if any, if we unwrap first line in block, we need to have this |
123 | * @param fixStartLinesStartIndex start index to fix start lines, normally this is this block or the previous one |
124 | */ |
125 | void unwrapLine(int line, TextBlock *previousBlock, int fixStartLinesStartIndex); |
126 | |
127 | /** |
128 | * Insert text at given cursor position. |
129 | * @param position position where to insert text |
130 | * @param text text to insert |
131 | */ |
132 | void insertText(const KTextEditor::Cursor position, const QString &text); |
133 | |
134 | /** |
135 | * Remove text at given range. |
136 | * @param range range of text to remove, must be on one line only. |
137 | * @param removedText will be filled with removed text |
138 | */ |
139 | void removeText(KTextEditor::Range range, QString &removedText); |
140 | |
141 | /** |
142 | * Debug output, print whole block content with line numbers and line length |
143 | * @param blockIndex index of this block in buffer |
144 | */ |
145 | void debugPrint(int blockIndex) const; |
146 | |
147 | /** |
148 | * Split given block. All lines starting from @p fromLine will |
149 | * be moved to it, together with the cursors belonging to it. |
150 | * @param fromLine line from which to split |
151 | * @param newBlock The block to which the data will be moved after splitting. It shouldn't have any cursors before call. |
152 | */ |
153 | void splitBlock(int fromLine, TextBlock *newBlock); |
154 | |
155 | /** |
156 | * Merge this block with given one, the given one must be a direct predecessor. |
157 | * @param targetBlock block to merge with |
158 | */ |
159 | void mergeBlock(TextBlock *targetBlock); |
160 | |
161 | /** |
162 | * Append to outRanges addresses of all ranges in this block which might intersect the given line. |
163 | * @param line line to check intersection |
164 | * @param view only return ranges associated with given view |
165 | * @param rangesWithAttributeOnly ranges with attributes only? |
166 | * @param outRanges where to append results |
167 | */ |
168 | KTEXTEDITOR_NO_EXPORT void (int line, KTextEditor::View *view, bool rangesWithAttributeOnly, QList<TextRange *> &outRanges) const; |
169 | |
170 | /** |
171 | * Flag all modified text lines as saved on disk. |
172 | */ |
173 | void markModifiedLinesAsSaved(); |
174 | |
175 | /** |
176 | * Insert cursor into this block. |
177 | * @param cursor cursor to insert |
178 | */ |
179 | void insertCursor(Kate::TextCursor *cursor) |
180 | { |
181 | auto it = std::lower_bound(first: m_cursors.begin(), last: m_cursors.end(), val: cursor); |
182 | if (it == m_cursors.end() || cursor != *it) { |
183 | m_cursors.insert(position: it, x: cursor); |
184 | } |
185 | } |
186 | |
187 | /** |
188 | * Remove cursor from this block. |
189 | * @param cursor cursor to remove |
190 | */ |
191 | void removeCursor(Kate::TextCursor *cursor) |
192 | { |
193 | auto it = std::lower_bound(first: m_cursors.begin(), last: m_cursors.end(), val: cursor); |
194 | if (it != m_cursors.end() && cursor == *it) { |
195 | m_cursors.erase(position: it); |
196 | } |
197 | } |
198 | |
199 | private: |
200 | /** |
201 | * parent text buffer |
202 | */ |
203 | TextBuffer *m_buffer; |
204 | |
205 | /** |
206 | * The index of this block in TextBuffer::m_blocks |
207 | */ |
208 | int m_blockIndex; |
209 | |
210 | /** |
211 | * Lines contained in this buffer. |
212 | * We need no sharing, use STL. |
213 | */ |
214 | std::vector<Kate::TextLine> m_lines; |
215 | |
216 | /** |
217 | * Set of cursors for this block. |
218 | */ |
219 | std::vector<TextCursor *> m_cursors; |
220 | }; |
221 | } |
222 | |
223 | #endif |
224 | |