File indexing completed on 2024-04-21 03:57:18

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 
0017 namespace Kate
0018 {
0019 class TextBuffer;
0020 class TextBlock;
0021 class TextRange;
0022 
0023 /**
0024  * Class representing a 'clever' text cursor.
0025  * It will automagically move if the text inside the buffer it belongs to is modified.
0026  * By intention no subclass of KTextEditor::Cursor, must be converted manually.
0027  */
0028 class TextCursor final : public KTextEditor::MovingCursor
0029 {
0030     // range wants direct access to some internals
0031     friend class TextRange;
0032 
0033     // this is a friend, because this is needed to efficiently transfer cursors from on to an other block
0034     friend class TextBlock;
0035 
0036     Q_DISABLE_COPY(TextCursor)
0037 
0038 private:
0039     /**
0040      * Construct a text cursor with given range as parent, private, used by TextRange constructor only.
0041      * @param buffer text buffer this cursor belongs to
0042      * @param range text range this cursor is part of
0043      * @param position wanted cursor position, if not valid for given buffer, will lead to invalid cursor
0044      * @param insertBehavior behavior of this cursor on insert of text at its position
0045      */
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(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     /**
0111      * Retrieve the line on which this cursor is situated.
0112      * \return line number, where 0 is the first line.
0113      */
0114     int line() const override
0115     {
0116         return lineInternal();
0117     }
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 or -1 if invalid.
0123      */
0124     int lineInternal() const
0125     {
0126         if (m_block) {
0127             return m_block->startLine() + m_line;
0128         }
0129         return -1;
0130     }
0131 
0132     /**
0133      * Retrieve the column on which this cursor is situated.
0134      * \return column number, where 0 is the first column.
0135      */
0136     int column() const override
0137     {
0138         return m_column;
0139     }
0140 
0141     /**
0142      * Non-virtual version of column(), which is faster.
0143      * \return column number, where 0 is the first column.
0144      * */
0145     int columnInternal() const
0146     {
0147         return m_column;
0148     }
0149 
0150     /**
0151      * Get range this cursor belongs to, if any
0152      * @return range this pointer is part of, else 0
0153      */
0154     KTextEditor::MovingRange *range() const override;
0155 
0156     /**
0157      * Get range this cursor belongs to, if any
0158      * @return range this pointer is part of, else 0
0159      */
0160     Kate::TextRange *kateRange() const
0161     {
0162         return m_range;
0163     }
0164 
0165     /**
0166      * Get offset into block this cursor belongs to, if any
0167      * @return offset into block this pointer is part of, else -1
0168      */
0169     int lineInBlock() const
0170     {
0171         if (m_block) {
0172             return m_line;
0173         }
0174         return -1;
0175     }
0176 
0177 private:
0178     /**
0179      * Set the current cursor position to \e position.
0180      * Internal helper to allow the same code be used for constructor and
0181      * setPosition.
0182      *
0183      * @param position new cursor position
0184      * @param init is this the initial setup of the position in the constructor?
0185      */
0186     void setPosition(KTextEditor::Cursor position, bool init);
0187 
0188 private:
0189     /**
0190      * parent text buffer
0191      * is a reference, and no pointer, as this must always exist and can't change
0192      */
0193     TextBuffer &m_buffer;
0194 
0195     /**
0196      * range this cursor belongs to
0197      * may be null, then no range owns this cursor
0198      * can not change after initial assignment
0199      */
0200     TextRange *const m_range = nullptr;
0201 
0202     /**
0203      * parent text block, valid cursors always belong to a block, else they are invalid.
0204      */
0205     TextBlock *m_block = nullptr;
0206 
0207     /**
0208      * line, offset in block, or -1
0209      */
0210     int m_line = -1;
0211 
0212     /**
0213      * column
0214      */
0215     int m_column = -1;
0216 
0217     /**
0218      * should this cursor move on insert
0219      */
0220     bool m_moveOnInsert;
0221 };
0222 
0223 }
0224 
0225 #endif