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();
}
Esempio n. 2
0
void ScCodeEditor::matchBracket( const TokenIterator & bracket, BracketPair & match )
{
    Q_ASSERT(bracket.isValid());

    switch(bracket->type) {
    case Token::OpeningBracket:
        match.first = bracket;
        match.second = nextClosingBracket(bracket.next());
        break;
    case Token::ClosingBracket:
        match.second = bracket;
        match.first = previousOpeningBracket(bracket.previous());
        break;
    default:
        match.first = TokenIterator();
        match.second = TokenIterator();
    }
}
Esempio n. 3
0
void ScCodeEditor::matchBrackets()
{
    mBracketSelections.clear();

    QTextCursor cursor(textCursor());
    QTextBlock block( cursor.block() );
    int posInBlock = cursor.positionInBlock();
    TokenIterator it(block);
    while (it.isValid() && it.block() == block)
    {
        const Token & token = *it;
        if (token.positionInBlock > posInBlock) {
            it = TokenIterator();
            break;
        } else if (
            (token.positionInBlock == posInBlock && token.type == Token::OpeningBracket) ||
            (token.positionInBlock == posInBlock - 1 && token.type == Token::ClosingBracket)
        )
            break;
        ++it;
    }

    BracketPair match;
    if( it.isValid() && it.block() == block)
        matchBracket( it, match );

    if( match.first.isValid() && match.second.isValid() )
    {
        const Token & tok1 = *match.first;
        const Token & tok2 = *match.second;

        if (
            (tok1.character == '(' && tok2.character == ')')
            || (tok1.character == '[' && tok2.character == ']')
            || (tok1.character == '{' && tok2.character == '}')
        ){
            QTextEdit::ExtraSelection selection;
            selection.format = mBracketHighlight;
            cursor.setPosition(match.first.position());
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
            selection.cursor = cursor;
            mBracketSelections.append(selection);

            cursor.setPosition(match.second.position());
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
            selection.cursor = cursor;
            mBracketSelections.append(selection);

            if (mHighlightBracketContents) {
                QTextCharFormat format;
                format.setBackground( mBracketHighlight.background() );
                selection.format = format;
                cursor.setPosition(match.first.position()+1);
                cursor.setPosition(match.second.position(), QTextCursor::KeepAnchor);
                selection.cursor = cursor;
                mBracketSelections.append(selection);
            }
        }
        else {
            QTextEdit::ExtraSelection selection;
            selection.format = mBracketMismatchFormat;
            cursor.setPosition(match.first.position());
            cursor.setPosition(match.second.position()+1, QTextCursor::KeepAnchor);
            selection.cursor = cursor;
            mBracketSelections.append(selection);
        }
    }

    updateExtraSelections();
}