File indexing completed on 2025-03-23 09:57:50
0001 /* 0002 SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org> 0003 0004 Based on code of the SmartCursor/Range by: 0005 SPDX-FileCopyrightText: 2003-2005 Hamish Rodda <rodda@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef KATE_TEXTCURSOR_H 0011 #define KATE_TEXTCURSOR_H 0012 0013 #include <ktexteditor/movingcursor.h> 0014 0015 #include "katetextblock.h" 0016 #include <ktexteditor_export.h> 0017 0018 namespace Kate 0019 { 0020 class TextBuffer; 0021 class TextBlock; 0022 class TextRange; 0023 0024 /** 0025 * Class representing a 'clever' text cursor. 0026 * It will automagically move if the text inside the buffer it belongs to is modified. 0027 * By intention no subclass of KTextEditor::Cursor, must be converted manually. 0028 */ 0029 class KTEXTEDITOR_EXPORT TextCursor final : public KTextEditor::MovingCursor 0030 { 0031 // range wants direct access to some internals 0032 friend class TextRange; 0033 0034 // this is a friend, because this is needed to efficiently transfer cursors from on to an other block 0035 friend class TextBlock; 0036 0037 private: 0038 /** 0039 * Construct a text cursor with given range as parent, private, used by TextRange constructor only. 0040 * @param buffer text buffer this cursor belongs to 0041 * @param range text range this cursor is part of 0042 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor 0043 * @param insertBehavior behavior of this cursor on insert of text at its position 0044 */ 0045 KTEXTEDITOR_NO_EXPORT 0046 TextCursor(TextBuffer &buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior); 0047 0048 public: 0049 /** 0050 * Construct a text cursor. 0051 * @param buffer text buffer this cursor belongs to 0052 * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor 0053 * @param insertBehavior behavior of this cursor on insert of text at its position 0054 */ 0055 TextCursor(TextBuffer &buffer, const KTextEditor::Cursor position, InsertBehavior insertBehavior); 0056 0057 /** 0058 * Destruct the text cursor 0059 */ 0060 ~TextCursor() override; 0061 0062 /** 0063 * Set insert behavior. 0064 * @param insertBehavior new insert behavior 0065 */ 0066 void setInsertBehavior(InsertBehavior insertBehavior) override 0067 { 0068 m_moveOnInsert = insertBehavior == MoveOnInsert; 0069 } 0070 0071 /** 0072 * Get current insert behavior. 0073 * @return current insert behavior 0074 */ 0075 InsertBehavior insertBehavior() const override 0076 { 0077 return m_moveOnInsert ? MoveOnInsert : StayOnInsert; 0078 } 0079 0080 /** 0081 * Gets the document to which this cursor is bound. 0082 * \return a pointer to the document 0083 */ 0084 KTextEditor::Document *document() const override; 0085 0086 /** 0087 * Fast way to set the current cursor position to \e position. 0088 * 0089 * \param position new cursor position 0090 */ 0091 void setPosition(const TextCursor &position); 0092 0093 /** 0094 * Set the current cursor position to \e position. 0095 * 0096 * \param position new cursor position 0097 */ 0098 void setPosition(const KTextEditor::Cursor &position) override; 0099 0100 /** 0101 * \overload 0102 * 0103 * Set the cursor position to \e line and \e column. 0104 * 0105 * \param line new cursor line 0106 * \param column new cursor column 0107 */ 0108 void setPosition(int line, int column) 0109 { 0110 KTextEditor::MovingCursor::setPosition(line, column); 0111 } 0112 0113 /** 0114 * Retrieve the line on which this cursor is situated. 0115 * \return line number, where 0 is the first line. 0116 */ 0117 int line() const override; 0118 0119 /** 0120 * Non-virtual version of line(), which is faster. 0121 * Inlined for fast access (especially in KateTextBuffer::rangesForLine 0122 * \return line number, where 0 is the first line. 0123 */ 0124 int lineInternal() const 0125 { 0126 // invalid cursor have no block 0127 if (!m_block) { 0128 return -1; 0129 } 0130 0131 // else, calculate real line 0132 return m_block->startLine() + m_line; 0133 } 0134 0135 /** 0136 * Retrieve the column on which this cursor is situated. 0137 * \return column number, where 0 is the first column. 0138 */ 0139 int column() const override 0140 { 0141 return m_column; 0142 } 0143 0144 /** 0145 * Non-virtual version of column(), which is faster. 0146 * \return column number, where 0 is the first column. 0147 * */ 0148 int columnInternal() const 0149 { 0150 return m_column; 0151 } 0152 0153 /** 0154 * Get range this cursor belongs to, if any 0155 * @return range this pointer is part of, else 0 0156 */ 0157 KTextEditor::MovingRange *range() const override; 0158 0159 /** 0160 * Get range this cursor belongs to, if any 0161 * @return range this pointer is part of, else 0 0162 */ 0163 Kate::TextRange *kateRange() const 0164 { 0165 return m_range; 0166 } 0167 0168 /** 0169 * Get block this cursor belongs to, if any 0170 * @return block this pointer is part of, else 0 0171 */ 0172 TextBlock *block() const 0173 { 0174 return m_block; 0175 } 0176 0177 /** 0178 * Get offset into block this cursor belongs to, if any 0179 * @return offset into block this pointer is part of, else -1 0180 */ 0181 int lineInBlock() const 0182 { 0183 if (m_block) { 0184 return m_line; 0185 } 0186 return -1; 0187 } 0188 0189 private: 0190 /** 0191 * no copy constructor, don't allow this to be copied. 0192 */ 0193 TextCursor(const TextCursor &); 0194 0195 /** 0196 * no assignment operator, no copying around. 0197 */ 0198 TextCursor &operator=(const TextCursor &); 0199 0200 /** 0201 * Set the current cursor position to \e position. 0202 * Internal helper to allow the same code be used for constructor and 0203 * setPosition. 0204 * 0205 * @param position new cursor position 0206 * @param init is this the initial setup of the position in the constructor? 0207 */ 0208 KTEXTEDITOR_NO_EXPORT 0209 void setPosition(const KTextEditor::Cursor &position, bool init); 0210 0211 private: 0212 /** 0213 * parent text buffer 0214 * is a reference, and no pointer, as this must always exist and can't change 0215 */ 0216 TextBuffer &m_buffer; 0217 0218 /** 0219 * range this cursor belongs to 0220 * may be null, then no range owns this cursor 0221 * can not change after initial assignment 0222 */ 0223 TextRange *const m_range; 0224 0225 /** 0226 * parent text block, valid cursors always belong to a block, else they are invalid. 0227 */ 0228 TextBlock *m_block; 0229 0230 /** 0231 * line, offset in block, or -1 0232 */ 0233 int m_line; 0234 0235 /** 0236 * column 0237 */ 0238 int m_column; 0239 0240 /** 0241 * should this cursor move on insert 0242 */ 0243 bool m_moveOnInsert; 0244 }; 0245 0246 } 0247 0248 #endif