File indexing completed on 2025-02-16 10:04:26
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 #include "katetextcursor.h" 0011 #include "katedocument.h" 0012 #include "katetextbuffer.h" 0013 #include "katetextrange.h" 0014 0015 namespace Kate 0016 { 0017 TextCursor::TextCursor(TextBuffer &buffer, const KTextEditor::Cursor position, InsertBehavior insertBehavior) 0018 : m_buffer(buffer) 0019 , m_range(nullptr) 0020 , m_block(nullptr) 0021 , m_line(-1) 0022 , m_column(-1) 0023 , m_moveOnInsert(insertBehavior == MoveOnInsert) 0024 { 0025 // init position 0026 setPosition(position, true); 0027 } 0028 0029 TextCursor::TextCursor(TextBuffer &buffer, TextRange *range, const KTextEditor::Cursor position, InsertBehavior insertBehavior) 0030 : m_buffer(buffer) 0031 , m_range(range) 0032 , m_block(nullptr) 0033 , m_line(-1) 0034 , m_column(-1) 0035 , m_moveOnInsert(insertBehavior == MoveOnInsert) 0036 { 0037 // init position 0038 setPosition(position, true); 0039 } 0040 0041 TextCursor::~TextCursor() 0042 { 0043 // remove cursor from block or buffer 0044 if (m_block) { 0045 m_block->removeCursor(this); 0046 } 0047 0048 // only cursors without range are here! 0049 else if (!m_range) { 0050 m_buffer.m_invalidCursors.remove(this); 0051 } 0052 } 0053 0054 void TextCursor::setPosition(const TextCursor &position) 0055 { 0056 if (m_block && m_block != position.m_block) { 0057 m_block->removeCursor(this); 0058 } 0059 0060 m_line = position.m_line; 0061 m_column = position.m_column; 0062 0063 m_block = position.m_block; 0064 if (m_block) { 0065 m_block->insertCursor(this); 0066 } 0067 } 0068 0069 void TextCursor::setPosition(const KTextEditor::Cursor &position, bool init) 0070 { 0071 // any change or init? else do nothing 0072 if (!init && position.line() == line()) { 0073 // simple case: 1:1 equal 0074 if (position.column() == m_column) { 0075 return; 0076 } 0077 0078 // ok, too: both old and new column are valid, we can just adjust the column and be done 0079 if (position.column() >= 0 && m_column >= 0) { 0080 m_column = position.column(); 0081 return; 0082 } 0083 0084 // else: we need to handle the change in a more complex way, new or old column are not valid! 0085 } 0086 0087 // remove cursor from old block in any case 0088 if (m_block) { 0089 m_block->removeCursor(this); 0090 } 0091 0092 // first: validate the line and column, else invalid 0093 if (position.column() < 0 || position.line() < 0 || position.line() >= m_buffer.lines()) { 0094 if (!m_range) { 0095 m_buffer.m_invalidCursors.insert(this); 0096 } 0097 m_block = nullptr; 0098 m_line = m_column = -1; 0099 return; 0100 } 0101 0102 // else, find block 0103 TextBlock *block = m_buffer.blockForIndex(m_buffer.blockForLine(position.line())); 0104 Q_ASSERT(block); 0105 0106 // if cursor was invalid before, remove it from invalid cursor list 0107 if (!m_range && !m_block && !init) { 0108 Q_ASSERT(m_buffer.m_invalidCursors.contains(this)); 0109 m_buffer.m_invalidCursors.remove(this); 0110 } 0111 0112 // else: valid cursor 0113 m_block = block; 0114 m_line = position.line() - m_block->startLine(); 0115 m_column = position.column(); 0116 m_block->insertCursor(this); 0117 } 0118 0119 void TextCursor::setPosition(const KTextEditor::Cursor &position) 0120 { 0121 setPosition(position, false); 0122 } 0123 0124 int TextCursor::line() 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 KTextEditor::Document *Kate::TextCursor::document() const 0136 { 0137 return m_buffer.document(); 0138 } 0139 0140 KTextEditor::MovingRange *Kate::TextCursor::range() const 0141 { 0142 return m_range; 0143 } 0144 0145 }