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
36 Q_DISABLE_COPY(TextCursor)
37
38private:
39 /**
40 * Construct a text cursor with given range as parent, private, used by TextRange constructor only.
41 * @param buffer text buffer this cursor belongs to
42 * @param range text range this cursor is part of
43 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor
44 * @param insertBehavior behavior of this cursor on insert of text at its position
45 */
46 TextCursor(TextBuffer &buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior);
47
48public:
49 /**
50 * Construct a text cursor.
51 * @param buffer text buffer this cursor belongs to
52 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor
53 * @param insertBehavior behavior of this cursor on insert of text at its position
54 */
55 TextCursor(TextBuffer &buffer, const KTextEditor::Cursor position, InsertBehavior insertBehavior);
56
57 /**
58 * Destruct the text cursor
59 */
60 ~TextCursor() override;
61
62 /**
63 * Set insert behavior.
64 * @param insertBehavior new insert behavior
65 */
66 void setInsertBehavior(InsertBehavior insertBehavior) override
67 {
68 m_moveOnInsert = insertBehavior == MoveOnInsert;
69 }
70
71 /**
72 * Get current insert behavior.
73 * @return current insert behavior
74 */
75 InsertBehavior insertBehavior() const override
76 {
77 return m_moveOnInsert ? MoveOnInsert : StayOnInsert;
78 }
79
80 /**
81 * Gets the document to which this cursor is bound.
82 * \return a pointer to the document
83 */
84 KTextEditor::Document *document() const override;
85
86 /**
87 * Fast way to set the current cursor position to \e position.
88 *
89 * \param position new cursor position
90 */
91 void setPosition(const TextCursor &position);
92
93 /**
94 * Set the current cursor position to \e position.
95 *
96 * \param position new cursor position
97 */
98 void setPosition(KTextEditor::Cursor position) override;
99
100 /**
101 * \overload
102 *
103 * Set the cursor position to \e line and \e column.
104 *
105 * \param line new cursor line
106 * \param column new cursor column
107 */
108 void setPosition(int line, int column);
109
110 /**
111 * Retrieve the line on which this cursor is situated.
112 * \return line number, where 0 is the first line.
113 */
114 int line() const override
115 {
116 return lineInternal();
117 }
118
119 /**
120 * Non-virtual version of line(), which is faster.
121 * Inlined for fast access (especially in KateTextBuffer::rangesForLine
122 * \return line number, where 0 is the first line or -1 if invalid.
123 */
124 int lineInternal() const
125 {
126 if (m_block) {
127 return m_block->startLine() + m_line;
128 }
129 return -1;
130 }
131
132 /**
133 * Retrieve the column on which this cursor is situated.
134 * \return column number, where 0 is the first column.
135 */
136 int column() const override
137 {
138 return m_column;
139 }
140
141 /**
142 * Non-virtual version of column(), which is faster.
143 * \return column number, where 0 is the first column.
144 * */
145 int columnInternal() const
146 {
147 return m_column;
148 }
149
150 /**
151 * Get range this cursor belongs to, if any
152 * @return range this pointer is part of, else 0
153 */
154 KTextEditor::MovingRange *range() const override;
155
156 /**
157 * Get range this cursor belongs to, if any
158 * @return range this pointer is part of, else 0
159 */
160 Kate::TextRange *kateRange() const
161 {
162 return m_range;
163 }
164
165 /**
166 * Get offset into block this cursor belongs to, if any
167 * @return offset into block this pointer is part of, else -1
168 */
169 int lineInBlock() const
170 {
171 if (m_block) {
172 return m_line;
173 }
174 return -1;
175 }
176
177private:
178 /**
179 * Set the current cursor position to \e position.
180 * Internal helper to allow the same code be used for constructor and
181 * setPosition.
182 *
183 * @param position new cursor position
184 * @param init is this the initial setup of the position in the constructor?
185 */
186 void setPosition(KTextEditor::Cursor position, bool init);
187
188private:
189 /**
190 * parent text buffer
191 * is a reference, and no pointer, as this must always exist and can't change
192 */
193 TextBuffer &m_buffer;
194
195 /**
196 * range this cursor belongs to
197 * may be null, then no range owns this cursor
198 * can not change after initial assignment
199 */
200 TextRange *const m_range = nullptr;
201
202 /**
203 * parent text block, valid cursors always belong to a block, else they are invalid.
204 */
205 TextBlock *m_block = nullptr;
206
207 /**
208 * line, offset in block, or -1
209 */
210 int m_line = -1;
211
212 /**
213 * column
214 */
215 int m_column = -1;
216
217 /**
218 * should this cursor move on insert
219 */
220 bool m_moveOnInsert;
221};
222
223}
224
225#endif
226

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