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