1/*
2 SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org>
3
4 Based on code of the SmartCursor/Range by:
5 SPDX-FileCopyrightText: 2003-2005 Hamish Rodda <rodda@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef KATE_TEXTCURSOR_H
11#define KATE_TEXTCURSOR_H
12
13#include <ktexteditor/movingcursor.h>
14
15#include "katetextblock.h"
16
17namespace Kate
18{
19class TextBuffer;
20class TextBlock;
21class TextRange;
22
23/**
24 * Class representing a 'clever' text cursor.
25 * It will automagically move if the text inside the buffer it belongs to is modified.
26 * By intention no subclass of KTextEditor::Cursor, must be converted manually.
27 */
28class TextCursor final : public KTextEditor::MovingCursor
29{
30 // range wants direct access to some internals
31 friend class TextRange;
32
33 // this is a friend, because this is needed to efficiently transfer cursors from on to an other block
34 friend class TextBlock;
35 friend class TextBuffer;
36
37 Q_DISABLE_COPY(TextCursor)
38
39private:
40 /**
41 * Construct a text cursor with given range as parent, private, used by TextRange constructor only.
42 * @param buffer text buffer this cursor belongs to
43 * @param range text range this cursor is part of
44 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor
45 * @param insertBehavior behavior of this cursor on insert of text at its position
46 */
47 TextCursor(TextBuffer *buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior);
48
49public:
50 /**
51 * Construct a text cursor.
52 * @param buffer text buffer this cursor belongs to
53 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor
54 * @param insertBehavior behavior of this cursor on insert of text at its position
55 */
56 TextCursor(TextBuffer *buffer, const KTextEditor::Cursor position, InsertBehavior insertBehavior);
57
58 /**
59 * Destruct the text cursor
60 */
61 ~TextCursor() override;
62
63 /**
64 * Set insert behavior.
65 * @param insertBehavior new insert behavior
66 */
67 void setInsertBehavior(InsertBehavior insertBehavior) override
68 {
69 m_moveOnInsert = insertBehavior == MoveOnInsert;
70 }
71
72 /**
73 * Get current insert behavior.
74 * @return current insert behavior
75 */
76 InsertBehavior insertBehavior() const override
77 {
78 return m_moveOnInsert ? MoveOnInsert : StayOnInsert;
79 }
80
81 /**
82 * Gets the document to which this cursor is bound.
83 * \return a pointer to the document
84 */
85 KTextEditor::Document *document() const override;
86
87 /**
88 * Fast way to set the current cursor position to \e position.
89 *
90 * \param position new cursor position
91 */
92 void setPosition(const TextCursor &position);
93
94 /**
95 * Set the current cursor position to \e position.
96 *
97 * \param position new cursor position
98 */
99 void setPosition(KTextEditor::Cursor position) override;
100
101 /**
102 * \overload
103 *
104 * Set the cursor position to \e line and \e column.
105 *
106 * \param line new cursor line
107 * \param column new cursor column
108 */
109 void setPosition(int line, int column);
110
111 /**
112 * Retrieve the line on which this cursor is situated.
113 * \return line number, where 0 is the first line.
114 */
115 int line() const override
116 {
117 return lineInternal();
118 }
119
120 /**
121 * Non-virtual version of line(), which is faster.
122 * Inlined for fast access (especially in KateTextBuffer::rangesForLine
123 * \return line number, where 0 is the first line or -1 if invalid.
124 */
125 int lineInternal() const
126 {
127 if (m_block) {
128 return m_block->startLine() + m_line;
129 }
130 return -1;
131 }
132
133 /**
134 * Retrieve the column on which this cursor is situated.
135 * \return column number, where 0 is the first column.
136 */
137 int column() const override
138 {
139 return m_column;
140 }
141
142 /**
143 * Non-virtual version of column(), which is faster.
144 * \return column number, where 0 is the first column.
145 * */
146 int columnInternal() const
147 {
148 return m_column;
149 }
150
151 /**
152 * Get range this cursor belongs to, if any
153 * @return range this pointer is part of, else 0
154 */
155 KTextEditor::MovingRange *range() const override;
156
157 /**
158 * Get range this cursor belongs to, if any
159 * @return range this pointer is part of, else 0
160 */
161 Kate::TextRange *kateRange() const
162 {
163 return m_range;
164 }
165
166 /**
167 * Get offset into block this cursor belongs to, if any
168 * @return offset into block this pointer is part of, else -1
169 */
170 int lineInBlock() const
171 {
172 if (m_block) {
173 return m_line;
174 }
175 return -1;
176 }
177
178private:
179 /**
180 * Set the current cursor position to \e position.
181 * Internal helper to allow the same code be used for constructor and
182 * setPosition.
183 *
184 * @param position new cursor position
185 * @param init is this the initial setup of the position in the constructor?
186 */
187 void setPosition(KTextEditor::Cursor position, bool init);
188
189private:
190 /**
191 * parent text buffer
192 * is a reference, and no pointer, as this must always exist and can't change
193 */
194 TextBuffer *m_buffer;
195
196 /**
197 * range this cursor belongs to
198 * may be null, then no range owns this cursor
199 * can not change after initial assignment
200 */
201 TextRange *const m_range = nullptr;
202
203 /**
204 * parent text block, valid cursors always belong to a block, else they are invalid.
205 */
206 TextBlock *m_block = nullptr;
207
208 /**
209 * line, offset in block, or -1
210 */
211 int m_line = -1;
212
213 /**
214 * column
215 */
216 int m_column = -1;
217
218 /**
219 * should this cursor move on insert
220 */
221 bool m_moveOnInsert;
222};
223
224}
225
226#endif
227

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