Exemple #1
0
static bool bracketPairDefinesRegion( const BracketPair & bracketPair )
{
    Q_ASSERT(bracketPair.first.isValid());
    Q_ASSERT(bracketPair.second.isValid());

    if ( bracketPair.first->character != '(' || bracketPair.second->character != ')' )
        return false;

    if (!tokenIsFirstAndOnlyInBlock(bracketPair.second) || !tokenIsFirstAndOnlyInBlock(bracketPair.second))
        return false;

    // check whether this is an Event
    TokenIterator it = bracketPair.first.next();
    if (it.isValid()) {
        if (it->type == Token::SymbolArg)
            return false;
        else {
            ++it;
            if (it.isValid() && it->character == ':')
                return false;
        }
    }

    return true;
}
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::gotoPreviousRegion()
{
    QTextCursor cursor = textCursor();
    int cursorPosition = cursor.position();

    BracketPair prevBracketPair;
    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while(it.isValid()) {
        nextBracketPair(it, bracketPair);
        if ( !bracketPair.second.isValid()
             || bracketPair.second.position() >= cursorPosition - 1 )
        {
            break;
        }
        if (bracketPairDefinesRegion(bracketPair)) {
            prevBracketPair = bracketPair;
        }
        it = bracketPair.second;
    }

    if ( prevBracketPair.first.isValid() && prevBracketPair.second.isValid() )
    {
        setTextCursor( cursorAt(prevBracketPair.second, 1) );
        return;
    }

    cursor.movePosition(QTextCursor::Start);
    setTextCursor(cursor);
}
QTextCursor ScCodeEditor::regionAroundCursor(const QTextCursor & cursor)
{
    int cursorPosition = cursor.position();

    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while (it.isValid()) {
        nextBracketPair(it, bracketPair);
        if (bracketPair.first.isValid() && bracketPair.first.position() < cursorPosition)
        {
            if ( bracketPair.second.isValid() && bracketPair.second.position() >= cursorPosition
                 && bracketPairDefinesRegion(bracketPair) )
            {
                QTextCursor regionCursor(QPlainTextEdit::document());
                regionCursor.setPosition(bracketPair.first.position() + 1);
                regionCursor.setPosition(bracketPair.second.position(), QTextCursor::KeepAnchor);
                return regionCursor;
            }
        } else {
            break;
        }

        it = bracketPair.second;
    }

    return QTextCursor();
}
Exemple #5
0
inline static bool tokenIsFirstAndOnlyInBlock( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    bool result = it->positionInBlock == 0;
    result = result && static_cast<TextBlockData*>(it.block().userData())->tokens.size() == 1;
    return result;
}
QTextCursor ScCodeEditor::cursorAt(const TokenIterator it, int offset)
{
    Q_ASSERT(it.isValid());

    QTextCursor textCursor(textDocument());
    textCursor.setPosition(it.position() + offset);

    return textCursor;
}
inline static bool tokenMaybeRegionEnd( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    if (it->character != ')')
        return false;
    TokenIterator next_it = it.next();
    return (!next_it.isValid() ||
            next_it.block() != it.block() ||
            next_it->character == ';');
}
static bool bracketPairDefinesRegion( const BracketPair & bracketPair )
{
    Q_ASSERT(bracketPair.first.isValid());
    Q_ASSERT(bracketPair.second.isValid());

    if (!tokenMaybeRegionStart(bracketPair.first) || !tokenMaybeRegionEnd(bracketPair.second))
        return false;

    // check whether this is an Event
    TokenIterator it = bracketPair.first.next();
    if (it.isValid()) {
        if (it->type == Token::SymbolArg)
            return false;
        else {
            ++it;
            if (it.isValid() && it->character == ':')
                return false;
        }
    }

    return true;
}
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();
    }
}
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 );
    }
}
// taking nested brackets into account
TokenIterator ScCodeEditor::previousOpeningBracket(TokenIterator it)
{
    int level = 0;
    while (it.isValid()) {
        switch (it->type) {
        case Token::OpeningBracket:
            if (level == 0)
                return it;
            --level;
            break;

        case Token::ClosingBracket:
            ++level;

        default:
            break;
        }
        --it;
    }
    return it;
}
void ScCodeEditor::gotoNextRegion()
{
    QTextCursor cursor = textCursor();
    int cursorPosition = cursor.position();

    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while (it.isValid()) {
        nextBracketPair(it, bracketPair);
        if ( bracketPair.first.isValid() && bracketPair.second.isValid()
             && bracketPair.first.position() > cursorPosition
             && bracketPairDefinesRegion(bracketPair))
        {
            setTextCursor( cursorAt(bracketPair.first) );
            return;
        }
        it = bracketPair.second;
    }

    cursor.movePosition(QTextCursor::End);
    setTextCursor(cursor);
}
inline static bool tokenMaybeRegionStart( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    return ( it->character == '(' && it->positionInBlock == 0 );
}