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
17namespace KTextEditor
18{
19class View;
20}
21
22namespace Kate
23{
24class TextBuffer;
25class TextCursor;
26class TextRange;
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 */
33class TextBlock
34{
35 friend class TextBuffer;
36
37public:
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 rangesForLine(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
199private:
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

source code of ktexteditor/src/buffer/katetextblock.h