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
32namespace Kate {
33
34class TextBuffer;
35class TextBlock;
36class TextRange;
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 */
43class 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 TextCursor (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