예제 #1
0
void AeHighlighter::blockModified(QTextBlock block, unsigned column, unsigned added, unsigned removed) {
	// We have to lock the mutex since a background thread may be
	// attempting to update the StyleVector pointer
	mutex_.lock();
	for(int i = 0, N = styles_->value(block.blockNumber()).size(); i != N; ++i) {
		AeCodeDecoration& ts = (*styles_)[block.blockNumber()][i];
		AeCodeDecoration::Extents extents = ts.extents();
		// if the highlight begins after our cursor position, advance
		// or subtract it by the amount of characters changed
        if(extents.start >= column)
			extents.start += added - removed;
		// if the highlight ends before our cursor position,
		// leave it unchanged
        else if(extents.start + extents.length <= column)
			{}
		// otherwise, we're in the middle of it. extend it. The normal
		// highlighting algorithm will correct this later.
		else
			extents.length += added - removed;
		ts.move(extents);
	}
	mutex_.unlock();

	// We've changed the colours so have to rehighlight this line
	rehighlightBlock(block);
}
// Changing of the start delimiter of a "here documnet" doesn't invoke
// highlightBlock() for the rest of it, hence the need for this slot.
// I don't like its complex logic but it works.
void Highlighter::docChanged (int pos, int, int)
{
    QTextBlock block = qobject_cast< QTextDocument *>(parent())->findBlock (pos);
    TextBlockData *data = static_cast<TextBlockData *>(block.userData());
    /* at start or end (state = 7 or 0 or < 6),
       or inside but previously at end (state = 6),
       or outside but previously at start (state = 0 or < 6):
       these are all states that we need to check */
    if (data->isdelimiter())
    {
        /*******************************************************************
         * It's important to know that this method is always called after  *
         * highlightBlock. There are three possibilities: state = 0, 6, 7. *
         * Other values are, like 0, related to a block outside here-docs. *
         *******************************************************************/

        /* when we're inside a here-doc, go up to its header */
        if (block.userState() == hereDocBodyState)
        {
            while (block.isValid())
            {
                block = block.previous();
                if (block.userState() == hereDocHeaderState)
                    break;
            }
        }

        /* when we're before, after or at end of a here-doc... */
        if (block.userState() != hereDocHeaderState)
        {
            /* ... the header state of the next here-doc should be 7;
               so, go to it and then do as for state 7 below */
            block = block.next();
            while (block.isValid() && block.userState() != hereDocHeaderState)
                block = block.next();
        }

        /* when this is a header (state = 7)... */
        if (block.isValid())
        {
            /* ... change the header state to 9 for this
               here-doc to be rehighlighted completely
               (for the highlighting downward 'wave' to go through it) */
            delimState = hereDocTempState;
            rehighlightBlock (block);
            /* then reset its block states... */
            resetHereDocStates (block);
            /* ... and also reset the global header state */
            delimState = hereDocHeaderState;
        }
        /* now, the header states of some here-docs
           below this one may be 9; so, reset them */
        block = block.next();
        while (block.isValid())
        {
            while (block.isValid() && block.userState() != hereDocTempState)
                block = block.next();
            if (block.isValid())
            {
                resetHereDocStates (block);
                block = block.next();
            }
        }
    }
}