QTextCursor ScCodeEditor::selectionForPosition( int position ) { QTextBlock block( textDocument()->findBlock(position) ); if (!block.isValid()) return QTextCursor(); int positionInBlock = position - block.position(); TokenIterator it = TokenIterator( block, positionInBlock ); if (it.type() == Token::Unknown) { // Token is invalid, or Token::Unknown (i.e. punctuations). // Prefer token at previous position. TokenIterator alternativeIt = TokenIterator( block, positionInBlock - 1 ); if (alternativeIt.isValid()) it = alternativeIt; } if (it.isValid()) { switch (it->type) { case Token::OpeningBracket: case Token::ClosingBracket: { BracketPair match; matchBracket(it, match); if (match.first.isValid() && match.second.isValid()) { int start = match.first.position(); int end = match.second.position() + 1; QTextCursor selection(textDocument()); if (it == match.second) { selection.setPosition(start); selection.setPosition(end, QTextCursor::KeepAnchor); } else { selection.setPosition(end); selection.setPosition(start, QTextCursor::KeepAnchor); } return selection; } break; } default: QTextCursor selection( textDocument() ); selection.setPosition( it.position() ); selection.setPosition( selection.position() + it->length, QTextCursor::KeepAnchor ); return selection; } } return QTextCursor(); }
void ScCodeEditor::gotoNextBlock() { QTextCursor cursor = textCursor(); TokenIterator tokenIt = TokenIterator::rightOf( cursor.block(), cursor.positionInBlock() ); if (tokenIt.type() == Token::OpeningBracket && tokenIt.block() == cursor.block() && tokenIt->positionInBlock == cursor.positionInBlock()) ++tokenIt; tokenIt = nextClosingBracket( tokenIt ); if (tokenIt.isValid()) setTextCursor( cursorAt(tokenIt, 1) ); else { cursor.movePosition( QTextCursor::End ); setTextCursor( cursor ); } }
void ScCodeEditor::gotoPreviousBlock() { QTextCursor cursor = textCursor(); TokenIterator tokenIt = TokenIterator::leftOf(cursor.block(), cursor.positionInBlock()); if (tokenIt.type() == Token::ClosingBracket && tokenIt.block() == cursor.block() && tokenIt->positionInBlock == cursor.positionInBlock() - 1) --tokenIt; tokenIt = previousOpeningBracket( tokenIt ); if (tokenIt.isValid()) setTextCursor( cursorAt(tokenIt) ); else { cursor.movePosition( QTextCursor::Start ); setTextCursor( cursor ); } }
void ScCodeEditor::keyPressEvent( QKeyEvent *e ) { hideMouseCursor(e); QTextCursor cursor( textCursor() ); bool cursorMoved = true; if (e == QKeySequence::MoveToNextWord) moveToNextToken( cursor, QTextCursor::MoveAnchor ); else if (e == QKeySequence::MoveToPreviousWord) moveToPreviousToken( cursor, QTextCursor::MoveAnchor ); else if (e == QKeySequence::SelectNextWord) moveToNextToken( cursor, QTextCursor::KeepAnchor ); else if (e == QKeySequence::SelectPreviousWord) moveToPreviousToken( cursor, QTextCursor::KeepAnchor ); else cursorMoved = false; if (cursorMoved) { setTextCursor( cursor ); return; } switch (e->key()) { case Qt::Key_Home: { Qt::KeyboardModifiers mods(e->modifiers()); if (mods && mods != Qt::ShiftModifier) { GenericCodeEditor::keyPressEvent(e); return; } QTextCursor::MoveMode mode = mods & Qt::ShiftModifier ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; QTextCursor c(textCursor()); QTextBlock b(c.block()); int pos = indentedStartOfLine(b); pos += b.position(); if (c.position() == pos) c.movePosition(QTextCursor::StartOfLine, mode); else c.setPosition(pos, mode); setTextCursor(c); return; } case Qt::Key_Backtab: { QTextCursor cursor = textCursor(); insertSpaceToNextTabStop( cursor ); ensureCursorVisible(); return; } case Qt::Key_Backspace: if (mInsertMatchingTokens && !overwriteMode() && e->modifiers() == 0) if (removeMatchingTokens()) break; GenericCodeEditor::keyPressEvent(e); break; case Qt::Key_Enter: case Qt::Key_Return: { QTextBlock cursorBlock = cursor.block(); int cursorPosInBlock = cursor.position() - cursorBlock.position(); TokenIterator nextToken = TokenIterator::rightOf(cursorBlock, cursorPosInBlock); if ( nextToken.block() == cursorBlock && nextToken.type() == Token::ClosingBracket ) { cursor.beginEditBlock(); cursor.insertBlock(); cursor.insertBlock(); cursor.endEditBlock(); cursor.movePosition( QTextCursor::PreviousBlock, QTextCursor::KeepAnchor ); indent(cursor, JoinEditBlock); cursor.movePosition( QTextCursor::EndOfBlock ); } else { cursor.beginEditBlock(); cursor.insertBlock(); cursor.endEditBlock(); indent(cursor, JoinEditBlock); } cursor.setVerticalMovementX(-1); setTextCursor(cursor); break; } default: if (!overwriteMode() && insertMatchingTokens(e->text())) break; GenericCodeEditor::keyPressEvent(e); } mAutoCompleter->keyPress(e); }