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 | |
17 | namespace Kate |
18 | { |
19 | class TextBuffer; |
20 | class TextBlock; |
21 | class ; |
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 | */ |
28 | class 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 | |
39 | private: |
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 | (TextBuffer *buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior); |
48 | |
49 | public: |
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 | |
178 | private: |
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 | |
189 | private: |
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 | |