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 | |
36 | Q_DISABLE_COPY(TextCursor) |
37 | |
38 | private: |
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 | (TextBuffer &buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior); |
47 | |
48 | public: |
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 | |
177 | private: |
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 | |
188 | private: |
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 | |